反应,映射组件,意外结果

react, map component, unexpected result

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

问题是第二个子组件只输出一个元素(事件虽然 console.log 打印两个)

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

主要成分

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

问题

setFetchData hooks setter 方法默认是异步的,它不会在设置后立即给你状态的更新值。

当第二个cityweather结果返回并置为状态时,此时的当前值fetchData仍然是一个空数组,所以你本质上是用第二个 weather 结果

传播一个空数组

解决方案

将回调传递给您的 setFetchData 并获取 state 当前的先前值,然后相应地继续您的价差。

像这样

setFetchData((previousData) => [...previousData, data]);