小能豆

为什么 React 不能正确渲染我的组件状态?

javascript

我已经尝试使用类组件来实现这一点:

class Foo extends React.Component {
    x = 3;
    componentDidMount () {
        fetch(apiURL).then(() => {
            x = 5;                
        });
    }

    render () {  
        return <div>{x}</div>;
    }
}

并使用函数组件:

let x = 3;
fetch(apiURL).then(() => {
    x = 5;                
});

const Foo = () => <div>{x}</div>;

页面上显示的 x 值始终没有变化,或者看起来是随机变化的。这是怎么回事?


阅读 45

收藏
2024-05-31

共1个答案

小能豆

在这两种情况下,无论您使用的是类组件还是函数组件,问题都在于您如何处理异步操作(请求fetch)并更新的值x

类别组件:

在类组件中,您将x直接在componentDidMount生命周期方法中更新属性。但是,不是组件状态的一部分,因此当它发生变化时,React 不知道重新渲染组件。相反,它会使用 的初始值(即 )x进行渲染。x``3

要解决此问题,您需要存储x组件的状态并使用以下方法更新它setState

class Foo extends React.Component {
    state = {
        x: 3
    };

    componentDidMount () {
        fetch(apiURL).then(() => {
            this.setState({ x: 5 });                
        });
    }

    render () {  
        return <div>{this.state.x}</div>;
    }
}

功能组件:

在函数组件中,您将x在组件主体之外更新变量。这意味着组件在x发生变化时不会重新渲染。即使您将调用放在fetch组件主体内,它仍然无法按预期工作,因为函数组件不支持诸如 之类的生命周期方法componentDidMount

为了解决这个问题,你可以使用useState钩子来管理状态x

import React, { useState, useEffect } from 'react';

const Foo = () => {
    const [x, setX] = useState(3);

    useEffect(() => {
        fetch(apiURL).then(() => {
            setX(5);                
        });
    }, []);

    return <div>{x}</div>;
}

通过使用useState,您可以创建x组件状态的一部分,因此当它发生变化时,React 知道重新渲染组件。钩子useEffect用于在函数组件中执行副作用,例如获取数据。空的依赖项数组确保效果仅在组件安装后运行一次,模拟类组件中[]的行为。componentDidMount

2024-05-31