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