【问题标题】:Component not updating when I change the props that I pass to it in React当我更改在 React 中传递给它的道具时,组件没有更新
【发布时间】:2020-02-07 22:55:55
【问题描述】:

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

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

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

下面是显示文本。

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

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

提前致谢!

【问题讨论】:

  • 您必须将相关代码作为minimal reproducible example添加到您的问题中。
  • 如何更改文本?我怀疑你只是在改变传递的道具,这对反应不起作用。
  • 您好,您可以添加您的代码以便有人帮助您吗?问候。
  • 添加了最少的可重现示例代码

标签: javascript reactjs parent-child react-props rerender


【解决方案1】:

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

因此,在您的情况下,更改 text 变量不会更新您的 parent 状态,因此不会重新渲染组件,而反过来也不会重新渲染和更新子组件.

如果您希望您的父组件更新它的状态(并更新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 方法就会再次清除超时。这将防止您的计时器在组件卸载后无限期运行。

【讨论】:

  • 是的,如果不使用一些 React 实用程序来修改 state/props 是不可能做到的。
【解决方案2】:

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

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

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

}

【讨论】:

  • 你是对的,我的错。我会相应地更新我的答案。感谢您的意见。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-10
  • 2018-10-28
  • 2017-09-28
相关资源
最近更新 更多