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

Component not updating when I change the props that I pass to it in React

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

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

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

下面是 DisplayText。

function DisplayText(props){
    return(<p>{props.text}</p>)
}

如何更新子组件,使其在 3 秒后显示 'This is the new text' 而不是 'This is the original text'?

提前致谢!

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

所以在你的情况下改变你的 text 变量不会更新你的 parent 的状态,因此不会重新渲染组件,这在 return 中获胜不重新渲染和更新子组件。

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

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

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

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

"This is the original text" 是您的初始状态,您的 text 变量的初始值。

要更新您的状态,您可以这样做:

setText("This is the new text");

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

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} />);
}

useEffect 是必需的,以便能够在组件安装后立即定义您的 setTimeout。它可用于在某个变量(在 [] 括号之间定义)更新后立即执行一些代码。例如:如果你这样写:

React.useEffect(() => {
    // execute some code
}, [text])

一旦您的 text 变量发生变化,它就会执行一些代码。将 [] 括号留空以仅在组件安装和卸载时触发 useEffect

useEffect 挂钩中声明您的 setTimeout,在这种情况下,一旦组件安装,它就会设置您的计时器。 useEffect 中的 return 方法会在组件卸载后立即再次清除超时。这将防止您的计时器在组件卸载后无限期 运行。

为了让变量在子组件中为prop添加监听器,它应该是父组件状态的一部分,而你的父组件的写法是错误的,因为你定义了一个static使用 let.

的变量

您有两个选择,要么遵循 Luze 发布的 react hooks 示例(缺少将在组件加载后触发 setTimeout 的 useEffect 函数),要么将您的父组件转换为 class,如下:

import React from 'react';

class MainPage extends React.Component {
  state={
      text: "This is the original text",
  };

  componentDidMount(){
     setTimeout(()=> { this.setState({
        text: "This is the new text"
      }) 
     }, 3000);
  }

  render(){
    return(<DisplayText text={text} />);
  }

}