Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ReactJs Child Component is not getting updated through Props

Goal: Re-render only Child component , by sending props from parent's non-state variable.

I want to re-render only child component without parent render . Below is example code I wrote . cRoot is parent passing props and CButton Child component needs to be rendered upon change of Visibility variable.

  • In child component , I haven't used state because it onetime and I don't want to keep that value in state . Also Child I don't want to create as Pure component .
  • In parent , I want to use variable (submitBtnVisibility)to send as props .

Can you please explain why child component is not getting updated as for child component point of view props are getting updated ? or point to me where I went wrong ?

Thanks a lot in advance for helping .

// 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>;
  }
}
like image 969
John34 Avatar asked Nov 06 '25 03:11

John34


1 Answers

Think about it, how can your Child component re-render? If its props or state changes. OK, now think about that how your parent component pass its changed prop to your child component? When it rerenders of course.

How does parent component rerender? When its state changes (or props but for the parent, there is not any prop for now) of course. So, you are not changing parent's state and it does not re-render. So, your child does not re-render. Simple as it is.

You can't render a child component unless it gets new props above parent. The parent does not re-render unless its state (or props) changes. Here, you are not doing any of this.

Update after comments

You can't render a child unless you render the parent component. No change in parent then no rerender for the child.

Do not afraid of rendering so much. Rendering itself is not so expensive, DOM changes are. React compares the DOM's (virtual one with the real one) and if nothing changed it does not unmount/remount the component.

Also, I don't know why you don't want to use PureComponent but it provides the functionality of what you want. Other than that you can use shouldComponentUpdate maybe, but most people do not suggest using it since it has other disadvantages and if not used properly it decreases the performance instead of decreasing it.

like image 78
devserkan Avatar answered Nov 08 '25 16:11

devserkan