使用 useEffect 时状态变为空

Posted

技术标签:

【中文标题】使用 useEffect 时状态变为空【英文标题】:state going empty when using useEffect 【发布时间】:2021-09-14 00:31:37 【问题描述】:

当您单击一个卡片时,我有 5 个城市及其天气显示在一张卡片上我希望在另一张卡片上显示更多详细信息。我还希望详细卡有第一个城市的初始数据。问题是当我尝试将单击的数据设置为 useEffect 中的状态时,状态变为空,甚至是初始数据。如果我在 useEffect 中添加依赖数组 [props.activeWeather],我可以单击它,它将显示数据,但初始数据不会显示,因为状态显示为空。我正在使用道具向卡片发送点击的城市对象以及第一个数据数组。

const ActiveWeather = (props) => 
    const [weather, setWeather] = useState(props.data);

//adding this cause the weather state to go empty?
    useEffect(() => 
        if (props.activeWeather) 
            setWeather(props.activeWeather);
        
    , []);

    console.log(weather);
    return (
        <Container>
            <Card>
                <Card.Header> weather?.city</Card.Header>
                weather?.temp
            </Card>
        </Container>
    );
;

export default ActiveWeather;

父组件

const fetchCity = async (city) => 
    const res = await axios.get(`https://api.openweathermap.org/data/2.5/weather?q=$city&appid=$key`);

    return 
        description: res.data.weather[0].description,
        icon: res.data.weather[0].icon,
        temp: res.data.main.temp,
        city: res.data.name,
        country: res.data.sys.country,
        id: res.data.id,
    ;
;

function App() 
    const [data, setData] = useState([]);

    const [activeWeather, setActiveWeather] = useState([]);

    useEffect(() => 
        const fetchCities = async () => 
            const citiesData = await Promise.all(["Ottawa", "Toronto", "Vancouver", "California", "London"].map(fetchCity)).catch((err) => 
                console.log("error:", err);
            );

            setData((prevState) => prevState.concat(citiesData));
        ;

        fetchCities();
    , []);

    const handleClick = (event) => 
        const weather = JSON.parse(event.target.dataset.value);
        setActiveWeather(weather);
    ;

    return (
        <div className="App">
            <Header />
            <Container>
                <Row>
                    <Col>
                        <WeatherPanel data=data handleClick=handleClick />
                    </Col>
                    <Col>data.length > 0 && <ActiveWeather activeWeather=activeWeather data=data[0] /></Col>
                </Row>
            </Container>
        </div>
    );


export default App;

尝试使用 useEffect 时...

【问题讨论】:

你还需要useEffect吗?由于activeWeather 与您父级中的状态相关联,因此对其进行任何更改都会导致重新渲染 【参考方案1】:
 if (props.activeWeather) 
        setWeather(props.activeWeather);
    

总是被执行,因为空数组是真实的。所以当activeWeather是一个空数组时,weather被设置为[]

【讨论】:

if(props.activeWeather.length) ...【参考方案2】:

试试这样:-

   ​useEffect(() => 
    ​if (props.activeWeather) 
       ​setWeather(props.activeWeather);
   ​, [props.activeWeather])

在 useEffect 数组中设置你的道具activeWeather。如果您的父组件中所做的任何更改导致 useEffect 自动触发。

【讨论】:

以上是关于使用 useEffect 时状态变为空的主要内容,如果未能解决你的问题,请参考以下文章

为啥 React 的 useReducer 在第一次在 useEffect 上获取数据时返回空状态?

React:使用 Refs 修复缺少的依赖警告 useEffect

React Hooks:如何在 useEffect 中设置状态?

似乎无法通过空依赖数组影响 React 的 useEffect() 中的状态。套接字.io

useEffect 中的无限循环

React 中带有 useEffect 的异步上下文