我是软件开发的新手,我正在尝试使用 ReactJS 创建一个模态 UI 元素并从 Pokeapi.co 获取数据。我已经获得了所有数据,可以使用 State 和 Axios 正确加载。但是,当我尝试创建从 PokeAPI 加载一些数据的模态时,模态只是位于 UI 上。我尝试了不同的方法来将 UI 返回到无模态,但没有成功。这是我目前正在使用的代码以及指向 GitHub 存储库的链接。 文字]
import React from 'react'
import './Pokemon.css'
export const PokemonDetails = ({data, setPokeModal}) => {
>! console.log(data)
>! const checkClose = () => {
>! setPokeModal = false
>! console.log(setPokeModal)
}
return (
<>
{
(!data) ? '': (
<>
>! <div className="BackShadow">
>! <div className='Modal'>
>! <div className='close-btn'><button onClick={()=>checkClose()}>X</button></div>
<div>
<h1>{data.name}</h1>
<img src={`https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/home/${data.id}.png`} alt=''/>
</div>
<div className='TypesContainer'>
{
data.types.map(pokemon=>{
return (
<>
<h2>
{pokemon.type.name}
</h2>
</>
)
})
}
</div>
>! </div>
>! </div>
</>
)
}
</>
)
}
上面的代码片段是处理模态加载时我想要呈现的数据的模态元素。该代码当前已删除模态注释。
下面的代码片段处理创建模态的 CSS 和模态内内容的样式。
.BackShadow {
width: 100%;
height: 100vh;
position: fixed;
top: 0;
left: 0px;
background-color: rgba(0, 0, 0, 0.7);
display: flex;
justify-content: center;
align-items: center;
}
.BackShadow .Modal {
width: 800px;
height: 800px;
background-color: rgb(188, 247, 247);
position: relative;
}
.close-btn button{
width: 25px;
height: 25px;
border-radius: 5px;
display: flex;
justify-content: center;
align-items: center;
font-size: 12px;
font-weight: 600;
cursor: pointer;
position: absolute;
top: -15px;
right: -15px;
}
.PokeDetails {
width: 13%;
text-align: center;
color: black;
position: fixed;
top: 100px;
right: 200px;
}
.PokeDetails img {
margin: 2rem;
height: 200px;
}
.PokeDetails h1 {
text-transform: uppercase;
font-weight: bolder;
letter-spacing: 1px;
}
下面的代码块处理非模态内容的呈现。内容本身是可点击的,点击时它会加载模态。之后模态卡在 UI 上。
import React from "react";
import "./Pokemon.css"
export const PokemonImage = ({pokemon, loading, pokemonInfo}) => {
// console.log(pokemon)
return (
<>
{
loading ? <h1>Loading...</h1>: pokemon.map((data)=>{
return (
<>
<div className="PokemonContainer" key={data.id}
onClick={()=>{
pokemonInfo(data)}}
>
<h2>{data.id}</h2>
<img className="PokemonCard" src={data.sprites.front_default} alt=""/>
<h2>{data.name}</h2>
</div>
</>
)
})
}
</>
)
}
下面的代码块是处理所有状态和渲染其他组件的主要组件。
import React from 'react'
import { PokemonImage } from './PokemonImage'
import { PokemonDetails } from './PokemonDetails'
import axios from 'axios'
import { useEffect, useState } from 'react'
import "./Pokemon.css"
export const Main = () => {
const [pokeData, setPokeData] = useState([]);
const [loading, setLoading] = useState(true);
const [url, setUrl] = useState('https://pokeapi.co/api/v2/pokemon?limit=20');
const [nextUrl, setNextUrl] = useState();
const [prevUrl, setPrevUrl] = useState();
const [pokeDexData, setPokeDexData] = useState();
const [pokeModal, setPokeModal] = useState(false)
const fetchPokeData = async() => {
setLoading(true);
const res = await axios.get(url);
// console.log(res)
setNextUrl(res.data.next);
setPrevUrl(res.data.previous);
getPokeData(res.data.results)
setLoading(false)
// console.log(pokeData)
}
const getPokeData=async(res)=>{
setPokeData([])
res.map(async(item)=>{
const Pokemons=await axios.get( item.url)
// console.log(Pokemons.data)
setPokeData(state =>{
state=[...state, Pokemons.data]
state.sort((a,b)=>a.id>b.id?1:-1)
return state
})
})
}
useEffect(() => {
fetchPokeData ();
}, [url])
return (
<>
<div className='MainContainer'>
<div className='PokedexContainer'>
<PokemonImage pokemon={pokeData} loading={loading} pokemonInfo={poke=>setPokeDexData(poke)}/>
<div className='button-group'>
<button onClick={()=>{
setPokeData([])
setUrl(prevUrl)
}}>Previous</button>
<button onClick={()=>{
setPokeData([])
setUrl(nextUrl)
}}>Next</button>
</div>
</div>
<div className='PokeDetails'>
{pokeModal === true && (
<PokemonDetails setPokeModal={setPokeModal} data={pokeDexData}/>
)}
<PokemonDetails setPokeModal={setPokeModal} data={pokeDexData}/>
</div>
</div>
</>
)
}
最初,当我制作这个应用程序时,我使用 State 将所有数据渲染到右侧。这工作正常并且状态根据更新并在单击不同的口袋妖怪时呈现新的口袋妖怪数据。但是,当我重新评论模态时。单击口袋妖怪时模态加载但随后卡在 UI 上。
我尝试使用 state 用布尔值更新模态的状态。但是,我没有成功。我怀疑我在某处遗漏了一行代码,以便在单击关闭按钮时重新呈现模式。但是,无论我尝试什么,它都不会点击。感谢任何帮助,完整代码可在提供的 GitHub 链接中找到。
它应该看起来像这样:
let [modalOpen, setModalOpen] = useState(true)
return <>
{modalOpen && <div className="Modal"/>}
<div className="close-btn"><button onClick={() => setModalOpen(false)}>X</button></div>
</>