当我更改在 React 中传递给它的道具时,组件不会更新

Dar*_*mer 5 javascript parent-child rerender reactjs react-props

我有一个具有子组件的功能组件。子组件显示一些通过 props 从父组件传递给它的文本。当我更改父组件中的文本并将其向下传递时,子组件仍保留旧文本。

下面是父组件 MainPage 的最小可重现示例。

function MainPage(){
    let text = "This is the original text";
    setTimeout(function(){ text = "This is the new text" }, 3000);
    return(<DisplayText text={text} />);
}
Run Code Online (Sandbox Code Playgroud)

下面是显示文本。

function DisplayText(props){
    return(<p>{props.text}</p>)
}
Run Code Online (Sandbox Code Playgroud)

如何更新子组件,使其在 3 秒后显示“这是新文本”而不​​是“这是原始文本”?

提前致谢!

Luz*_*uze 5

组件仅更新一次其state更改或props更改。Astate是一个变量或一组变量,当组件重新渲染时会记住它。一旦组件重新渲染,所有其他变量将返回其默认值。您可以将其视为组件的内存。

所以在你的情况下,改变你的text变量不会更新你parent的状态,因此不会重新渲染组件,作为回报,它不会重新渲染和更新子组件。

如果你想让你的父组件更新它的状态(并更新child的道具),你需要像这样声明你的文本变量:

const [text, setText] = React.useState("This is the original text");
Run Code Online (Sandbox Code Playgroud)

Text是您的变量,它现在包含在您的组件状态中,并且会在组件重新渲染时被记住。你可以给它任何你想要的名字。

setText是一个函数,它更新您的text变量并重新渲染您的组件及其子组件。你可以给它任何你想要的名字。

“这是原始文本”是您的初始状态,您的text变量的初始值。

要更新您的状态,您可以执行以下操作:

setText("This is the new text");
Run Code Online (Sandbox Code Playgroud)

所以在你的情况下,它看起来像这样:

function MainPage(){
    const [text, setText] = React.useState("This is the original text");

    React.useEffect(() => {
        const timeout = setTimeout(function(){
            setText("This is the new text")
        }, 3000);

        return clearTimeout(timeout)
    }, []);

    return(<DisplayText text={text} />);
}
Run Code Online (Sandbox Code Playgroud)

useEffect is necessary to be able to define your setTimeout as soon as the component mounts. It can be use to execute some code as soon as a certain variable (defined between the [] brackets) updates. For example: If you wrote it like this:

React.useEffect(() => {
    // execute some code
}, [text])
Run Code Online (Sandbox Code Playgroud)

It would execute some code as soon as your text variables changes. Leave the [] brackets empty to only trigger useEffect when the component mounts and unmounts.

Within the useEffect hook you declare your setTimeout, this sets your timer as soon as the component mounts in this case. The return method within your useEffect clears your timeout again as soon as the component unmounts. This will prevent your timer from running indefinitely after your component unmounts.