Reactjs 反应、映射组件、意外结果

Reactjs 反应、映射组件、意外结果,reactjs,dictionary,components,Reactjs,Dictionary,Components,我正在构建天气应用程序,我的想法是将城市名称保存在数据库/本地主机中,将城市置于useState(现在它是硬编码的),在第一个子组件中使用地图进行迭代,并在第二个子组件中显示 问题在于,第二个子组件只输出一个元素(尽管console.log会打印这两个元素,但事件会同时输出) 顺便说一句,当我在编辑器中更改代码并保存时,会出现另一个“li”元素 主要成分 const-App=()=>{ const[cities,setCities]=useState(['London','Berlin']);

我正在构建天气应用程序,我的想法是将城市名称保存在数据库/本地主机中,将城市置于useState(现在它是硬编码的),在第一个子组件中使用地图进行迭代,并在第二个子组件中显示

问题在于,第二个子组件只输出一个元素(尽管console.log会打印这两个元素,但事件会同时输出)

顺便说一句,当我在编辑器中更改代码并保存时,会出现另一个“li”元素

主要成分
const-App=()=>{
const[cities,setCities]=useState(['London','Berlin']);
返回(
)
}
导出默认应用程序
第一个子组件
constdisplayweather=({DisplayWeather})=>{
const[fetchData,setFetchData]=useState([]);
常数apiKey='4c97ef52cb86a6fa1cff027ac4a37671';
useffect(()=>{
displayWeather.map(异步城市=>{
const res=等待取数(`http://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&appid=${apiKey}`)
const data=wait res.json();
setFetchData([…fetchData,data]);
})
}, [])
返回(
{fetchData.map(数据=>)
))} ) } 导出默认显示天气
第二个子组件
const Weather=({data})=>{
console.log(data)//它正确打印两个数据
返回(
  • {data.name}//只显示一个数据
  • ) } 导出默认天气
    问题 默认情况下,
    setFetchData
    hooks setter方法是异步的,它不会在设置后立即提供状态的更新值

    当第二个城市的
    天气
    结果返回并设置为状态时,当前值
    fetchData
    当时仍然是一个空数组,因此您实际上是在用第二个
    天气
    结果散布一个空数组

    解决方案 将回调传递给您的
    setFetchData
    ,获取
    状态的当前上一个值
    ,然后继续相应的排列


    像这样,你的数据结构是什么?数据是从API获取的对象我知道!但是,当你做一个
    console.log(data)
    它仍然是对象{coord:{…},weather:Array(1),base:“stations”,main:{…},visibility:10000,}base:{all:0}cod:200 coord:{lon:19.565,lat:50.2813}dt:1620762052 id:3090146 main:{temp:20.25,感觉像:19.53,temp\u min:18.89,temp\u max:22,压力:1008,}名称:“Olkusz”系统:{类型:1,id:1701,国家:PL,日出:1620702034,日落:1620756945}时区:7200能见度:10000天气:[{…}风速:4.12,摄氏度:80}原型:目标是
    console.log()
    组件中,无论是
    还是
    组件谢谢,这个解决方案是有效的。但我仍然不明白为什么它不起作用,因为我知道useState是异步的,但看看react-dev工具,状态和道具都是正确的,所以即使稍后出现(异步),我认为状态或道具的更改应该呈现站点并最终显示,就像
    .map()
    回调函数中的每一个一样,回调函数都被推到调用堆栈中,带有一个空数组的
    fetchData
    ,当它们被执行时,它们不会得到状态更新
    const App = () => {
    
        const [cities, setCities] = useState(['London', 'Berlin']);
        
        return (
            <div>
                <DisplayWeather displayWeather={cities}/>
            </div>
        )
    }
    
    export default App
    
    
    const DisplayWeather = ({displayWeather}) => {
    
    
        const [fetchData, setFetchData] = useState([]);
    
        const apiKey = '4c97ef52cb86a6fa1cff027ac4a37671';
    
    
        useEffect(() => {
        
            displayWeather.map(async city=>{
           
                const res =await fetch(`http://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&appid=${apiKey}`)
                const data = await res.json();
                 
                    setFetchData([...fetchData , data]);
               
            })
            
        }, [])
    
    
        return (
            <>
                {fetchData.map(data=>(            
                     <ul>
                         <Weather                        
                            data={data}/> 
                      </ul>
                ))}
            </>
        )
    }
    
    export default DisplayWeather
    
    
    const Weather = ({data}) => {
    
    
        console.log(data) // it prints correctly both data
    
    
        return (
    
            <li>       
                {data.name} //display only one data
            </li>
        )
    }
    
    export default Weather