Laura delgado
Laura delgado

Reputation: 362

Passing state from Parent to Child using componentWillReceiveProps render many times

I'm passing state from parent component to child component everything works fine but i'm getting undefined of the props that coming from parent component I think because I'm making async it take two sec before I setting state. When I'm setting TimeOut this.props.check for two sec in componentDidMount of Child component it works fine I got data

The problem here I don't feel ok to use setTimeOut so I decided to use componentWillReceiveProps it's worked but when any events in child component rendered the componentWillReceiveProps will re-render and I just need it to render only once.

I changed my code to be simple

Parent Component

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      check: ''
    }
  }
  componentWillMount() {
    this.call();
  }
  call = () => {
    //I'm making async here might take two sec
      this.setState({ check: 'received' })

  }

  render() {
    return (
      <div>
        <span>Parent Component</span>
        <Child check={this.state.check}  />
      </div>
    )
  }
}

Child Component

class Child extends Component {

  componentDidMount() { // this works fine and render only one time, this what I really wanna do but I don't like to use setTimeOut
    setTimeout(() => {
      console.log(this.props.check); 
    }, 2000)
  }
  componentWillReceiveProps(nextProps){ // this works but when any action happening this will re-render 
    if (nextProps.check !== this.props.check){
      console.log(this.props.check)
    }
  }
  render() {
    return (
      <div>
        <span>Child Component</span>
      </div>
    )
  }
}

export default Child;

Upvotes: 1

Views: 121

Answers (1)

ashirley
ashirley

Reputation: 1147

If App's state.check might be null (because it is set asynchronously), you need to decide what you want to render during that time.

It might be that you don't want to render Child at all until state.check is set by using this in App's render method:

{ this.state.check ? (<Child check={this.state.check} />) : (<div>Loading...</div>) }

Upvotes: 1

Related Questions