0

I have been working on building an app, where an uncommon scenario has raised for me to handle. I had to pass props to a child component from the parent, and the child component needs to set those props as its state.

<ChildComponent allProps={parentProps}>
  <SomeChildren withProps />
</ChildComponent>

In the ChildComponent:

class ChildComponent extends Component {
  state: {
    someRequiredProps: null
  }
  setStateForThisComponent(propsToSet) {
    this.setState({someRequiredProps: propsToSet});
  }
  componentDidMount() {
    this.props.allProps()
  }
  render() {
    //I know this is incorrect syntax
    return (<div allProps={(propsArg) => this.setStateForThisComponent(propsArg)});
  }
}

Usually, I can run this method from parent component using refs, but since this ChildComponent being a very heavily reused component, I do not want to go with the refs approach. Some other solutions suggested, that I create the state in parent component itself, and pass it as props to ChildComponent, but that is not what I am trying to achieve.

Please let me solve this issue of setting the child component's state using the parent's.

starlight
  • 765
  • 3
  • 14
  • 30

1 Answers1

0

If you just need to set the initial props as the state, you can do it in constructor:

constructor(props) {
  super(props);
  this.state = {
    someRequiredProps: props.someRequiredProps,
  }
}

If the state must be updated whenever the prop updates, you need to use the new getDerivedStateFromProps method:

class ChildComponent extends Component {
  state: {
    someRequiredProps: null,
  };
  static getDerivedStateFromProps(nextProps, prevState) {
    return {
      // return the new state based on `nextProps`
      someRequiredProps: nextProps.someRequiredProps,
    };
  }

Also note from the docs:

Note that if a parent component causes your component to re-render, this method will be called even if props have not changed. You may want to compare new and previous values if you only want to handle changes.

Roy Wang
  • 11,112
  • 2
  • 21
  • 42