当父级状态发生变化时,如何在 React 中更新(重新渲染)子组件?

新手上路,请多包涵

好的,我已经知道一种方法可以做到这一点。但是,我问这个是为了防止我重新发明轮子,因为我是 React 的新手。我的印象是,如果父组件通过 props 将她的状态传递给子组件,而不是更新父组件的状态,则子组件将在需要时重新渲染。但事实似乎并非如此。我设置了这个例子,

 class Child extends Component {
  constructor(props) {
    super(props);
    this.state = {
      number: props.number,
    };
  }

  updateNumber(n) {
    this.setState({number: n});
  }

  render() {
    return (<h1>{this.state.number}</h1>);
  }
}

class Parent extends Component {

  constructor(props) {
    super(props);
    this.state = {
      number: -1,
    };
    this.child = React.createRef();
    setInterval(this.updateState.bind(this), 1000);
  }

  updateState() {
    console.log(this.state);
    this.setState({
      number: Math.floor((Math.random() * 10) + 1),
    });
    // this.child.current.updateNumber(this.state.number);
  }

  render() {
    return (
      <div>
        <Child ref={this.child} number={this.state.number}/>
      </div>
    );
  }
}

在这个例子中,除非我显式定义一个引用并使用它来调用子项的更新函数(注释部分),否则每次更新父项的状态时都不会重新渲染子项。是这样吗?如果他们的父母的状态作为道具传递给他们,你是想手动更新你的孩子的状态(嘿)还是他们应该自动更新(并因此重新渲染)。

原文由 scribe 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 501
2 个回答

这是因为您的 Child 组件也在使用自己的状态。总是问自己 state 是否必要,这是 React 初学者的常见错误。

希望你能通过看这个例子更深入地理解它。 Instead of calling setInterval in your constructor function, I will recommend you to call it in componentDidMount and to clearInterval in your componentWillUnmount .

 // Since you are not using state, you can use functional component for your Child component
const Child = ({ number }) => <h1>{number}</h1>;

class Parent extends React.Component {
  constructor(props) {
    super(props);
    this.timer = null;
    this.state = { number: 0 };
  }

  componentDidMount() {
    // setInterval after component did mount
    this.timer = setInterval(this.incrementNumber, 1000);
  }

  componentWillUnmount() {
    // clearInterval when component is going to unmount
    if (this.timer) {
      clearInterval(this.timer);
    }
  }

  incrementNumber = () => {
    // setState function callback to ensure state received will be latest state
    this.setState(prevState => ({ number: prevState.number + 1 }));
  }

  render() {
    const { number } = this.state;
    return (
      <div>
        <Child number={number} />
      </div>
    );
  }
}

原文由 junwen-k 发布,翻译遵循 CC BY-SA 4.0 许可协议

重新渲染孩子的一个简单选择是在每次需要重新渲染时更新唯一的关键属性。

<ChildComponent key={this.state.updatedKey}/>

原文由 Gary Vernon Grubb 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题