1

I have a Parent component and Child one, and I have action that trigger some api call in Child component and on componentWillMount I check in if condition some props that come from parent and do some trigger. If condition true I trigger a method that render new component. The problem is that in child component in componentWillmount the props this.props.person and this.props.notFound come undefined, but I need wait for api request before render and check this props.

parent:

export class Parent extends Component {

  state = {
    id: this.props.id || ''
  }

    render() {
        <Child value={this.state.value} onNotValidId={() => this.renderNewComponent()} />
    }

}

export const mapStateToProps = state => ({
    tagStatus: state.tagAssignment.status,
    persons: state.entities.persons,
)}

Children:

export class Child extends Component {
  componentWillMount = () => {
         this.props.init(parseInt(this.props.id, 16), this.props.accessToken)
        if (!this.props.notFound && !this.props.person)
            this.props.onNotValidId()

    }

   render = () => {
      return (
         <div>Some body</div>
       )
   }
}

export const mapStateToProps = state => ({
    status: state.tagAssignment.status,
    person: state.entities.persons[state.tagAssignment.assignee],
    accessToken: state.auth.accessToken,
})

export const mapDispatchToProps = dispatch => ({
    init: (id, accessToken) => dispatch(checkId(id, accessToken)),
})

export default compose(
    connect(mapStateToProps, mapDispatchToProps),
)(Child)
Palaniichuk Dmytro
  • 2,943
  • 12
  • 36
  • 66
  • I would probably use componentDidUpdate and set a variable state then use that to only render child when update (eg result from Api call) occurs and sets offsets the update. – Afshin Ghazi May 11 '18 at 12:44

1 Answers1

1

The problem you are having is happening because your call to the API is happening asynchronously to the react lifecycle methods. By the time the API response returned the parents component's render method has been called for the first time which rendered the child component that in turn called the component will mount with the props passed down to it by the parent before they were initialized with the API response data. When the API results are finally returned and passed down as new props to the child component (A result of the parents re-render ) it will not trigger the componentWillMount lifecycle since its already mounted.

You can solve this in multiple ways and it really depends on how you plan to use the child component in the future. A few solutions:

1) In your parent components render method make sure to not render the child component until the response from the API is returned. This will make sure that when the child component does mount for the first time it will have valid props to work with. eg:

render() {
  this.state.value && <Child value={this.state.value} onNotValidId={() => this.renderNewComponent()} />
}

2) Move or duplicate (Depends on how your planning to us the child component) the child components initialization logic from/to another lifecycle hook such as componentDidUpdate or getDerivedStateFromProps (Depending n the version of React you are sing)

Tal Goldfus
  • 151
  • 3