Shubham
Shubham

Reputation: 1191

Deep into ReactJS

I'm using react since 6 to 8 month. I've gone through the about the react basics and created some application. But some of the following questions are digging into my mind -

So why the constructor method is used? If we can achieve the same without the constructor.

Upvotes: 0

Views: 60

Answers (1)

bennygenel
bennygenel

Reputation: 24680

Probably not going to be able all your questions but maybe I can be able to give you some direction.

1) componentWillMount VS componentDidMount

It is better to make an API call in componentDidMount because it means your component finished rendering. Use case of this probably showing a loading indicator while still waiting for a response from the server or etc. There is a good blog post here.

This function (refering to componentWillMount) is called right before the component’s first render, so at first glance it appears to be a perfect place to put data fetching logic.

There’s a “gotcha,” though: An asynchronous call to fetch data will not return before the render happens. This means the component will render with empty data at least once.

2) componentWillUnmount

There is lots of use cases for this life-cycle event. One of them can be removing any event listeners before un-mounting the component. An example use case for this type of use can be reavt-native's BackHandler

componentDidMount() {
  BackHandler.addEventListener('hardwareBackPress', this.handleBackButton);
}

componentWillUnmount() {
  BackHandler.removeEventListener('hardwareBackPress', this.handleBackButton);
}

3) componentWillUpdate && componentDidUpdate && shouldComponentUpdate

When you have a parent-child relationship in component you sometimes need to pass props to the child components. When some action happen and the value of the parent component change, you pass a new value to the child component. If you are using this value for making API request or render child component you can be notified before the update happens. You will have the access for nextProp and nextState. You can use these to make calculations and run actions between renders. You can use componentDidUpdate to notify parent component that the update has finished and you can use shouldComponentUpdate to prevent unnecessary updates in child component.

For Example

class ParentComponent extends Component {
  constructor(props) {
    this.state = {
      item: {}
    }
  }
  componentDidMount() {
    this.setState({
      item: {
        name: 'Item Name',
        count: '24',
        lastChangeTime: new Date()
    });
    setTimeout(() => {
      this.setState({
        item: {
          name: 'Item Name',
          count: '24',
          lastChangeTime: new Date()
      });
    }, 5000);
    setTimeout(() => {
      this.setState({
        item: {
          name: 'Item Name',
          count: '24',
          lastChangeTime: new Date()
      });
    }, 10000);
  }
  childWillUpdate() {
    console.log('Child component gonna update. Show loading indicator.');
  }
  childUpdated() {
    console.log('Child component finished updating you can close loading indicator inside the parent');
  }
  render() {
      return (
        <ChildComponent
          childWillUpdate={this.childWillUpdate}
          childUpdated={this.childUpdated}
          item={this.state.item} 
        />
      )
  }
} 

class ChildComponent extends Component {
  constructor(props) {
    this.state = {
      item: props.item || null
    }
  }
  componentWillReceiveProps(nextProps) {
    if(nextProps.item.count !== this.props.item.count || nextProps.item.name !== this.props.item.name) {
      // do not set state if only the change is lastChangeTime
      this.setState({ item: nextProps.item });
    }
  }
  shouldComponentUpdate(nextProps, nextState) {
    // prevent update of the component if only change is on lastChangeTime
    return (nextProps.item.count !== this.props.item.count || nextProps.item.name !== this.props.item.name)
  }
  componentWillUpdate(nextProps, nextState) {
    // notify parent component that child gonna update
    this.props.childWillUpdate();
  }
  componentDidUpdate(prevProps, prevState) {
    // notify parent component that update complete
    this.props.childUpdated();
  }
  render() {
      return (this.state.item ? <h1>{this.state.open}</h1> : <h1>Loading...</h1>)
  }
}

4) constructor

Although your given examples are correct and can be used there is a different use case like I showed at the previous example. You might need to set state with a value from parent that passed with props. In this case you can use constructor to receive that prop and then set it to state.

class MyClass extends React.component{
    constructor(props){
        super(props);
        this.state = {
          nextCall: props.item.lastChange.getTime() + (1000 * 60 * 5)    
    }
}

This might not be a complete explanation or use case example for all the mentioned life-cycle methods but I hope they'll give you some ideas about how you can use them and how you can get better performance out of your applications or websites. At the end it all depends on how you use them and when you use them.

Upvotes: 3

Related Questions