ReactJs子组件未通过Props更新

4

目标:通过从父组件的非状态变量发送props,仅重新渲染子组件。

我想仅重新渲染子组件而不重新渲染父组件。以下是我编写的示例代码。cRoot是传递props的父组件,CButton子组件需要在Visibility变量更改时进行渲染。

  • 在子组件中,我没有使用state,因为它只会发生一次,我不想将该值保留在state中。同时,我也不想将Child创建为Pure组件。
  • 在父组件中,我想使用变量(submitBtnVisibility)作为props发送。

请问为什么子组件没有更新?从子组件的角度来看,props已经更新了吗?或者请指出我哪里做错了?

非常感谢您的帮助。

// Parent Component 

class Root extends React.Component {
  constructor(props) {
    super(props);
    this.state = { refresh: true };
    // Parents non-state variable.
    this.submitBtnVisibility = { visibility1: 1, visibility2: 2 };

  }

  componentDidMount() {
    console.log("Root componentDidMount ");
  }

  componentDidUpdate(prevProps, prevState) {
    console.log("Root componentDidUpdate ", prevProps, prevState);
  }

  handleonclick = () => {
    console.log(" Root Btn Clicked");
    //this.setState({ var1: 5 });  -> If I enable this line , child is getting rendered
    this.submitBtnVisibility.visibility1 = 5;
  };
  render() {
    console.log(" Root Render ");

    return (
      <div className={classes.uploadContainerArea}>
        <Btncomponent visibility={this.submitBtnVisibility} />
        <button className={classes.btnroot} onClick={this.handleonclick}>
          {" "}
          Root Btn{" "}
        </button>
      </div>
    );
  }
}

// Child Component 

class Btncomponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { Btnprops: this.props.visibility };
  }

  componentDidMount() {
    console.log("Btncomponent componentDidMount ");
  }

  componentDidUpdate(prevProps, prevState) {
    console.log("Btncomponent componentDidUpdate ", prevProps, prevState);
  }

  static getDerivedStateFromProps(props, state) {
    console.log(" getDerivedStateFromProps ");
    return null;
  }
  shouldComponentUpdate(nextProps, nextState) {
    console.log(" shouldComponentUpdate ");
    return true;
  }
  getSnapshotBeforeUpdate(prevProps, prevState) {
    console.log(" getSnapshotBeforeUpdate ");
    return null;
  }
  render() {
    console.log(" Btncomponent Render ", this.props);

    return <button type="button"> {this.props.visibility.visibility1} </button>;
  }
}
1个回答

3
想一想,你的子组件如何重新渲染?如果它的 props 或 state 发生了变化。好的,现在想一想,你的父组件如何将其更改的 prop 传递给子组件?当它重新渲染时。
父组件如何重新渲染?当它的状态发生变化时(或者对于父组件,它现在没有任何 prop)当然会重新渲染。所以,你没有改变父组件的状态,它也不会重新渲染。所以,你的子组件也不会重新渲染。就这么简单。
除非子组件从上级组件获得新的 props,否则无法渲染子组件。父组件不会重新渲染,除非它的状态(或 props)发生了变化。在这里,你没有做任何这样的改变。
评论后更新:
必须渲染父组件才能渲染子组件。如果父组件没有更改,则子组件不会重新渲染。
不要害怕频繁重新渲染。重新渲染本身并不那么昂贵,DOM 变化才是。React 比较虚拟 DOM 和实际 DOM,如果没有任何改变,它就不会卸载 / 重新挂载组件。
另外,我不知道为什么你不想使用 PureComponent,但它提供了你想要的功能。除此之外,也可以使用 shouldComponentUpdate,但大多数人不建议使用它,因为它有其他缺点,如果使用不当会降低性能而不是提高性能。

完全同意devserkan的观点!!但是想象一下这样一个场景,父组件有(假设)10个子组件。然后在父组件渲染时,所有10个子组件都会重新渲染。如果我的目标只是渲染其中一个子组件,在其余9个组件中,我需要编写额外的代码(以避免重新渲染,例如prev props未更改等)。那么有没有办法只针对特定的子组件重新渲染而不重新渲染父组件呢?作为Reactjs的新手,我只是在想而已。但我完全理解你的解释。 - John34
欢迎您,也欢迎您加入SO,并祝您旅途愉快 :) - devserkan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接