By Prem


2017-05-04 09:47:16 8 Comments

I'm having the following class that renders users based on a sort dropdown. Users will be listed in alphabetical order if i choose "alphabetical" and in group order when i choose "group".

render(){
    return(
        const {members, sort} = this.state
        { sort === "alphabetical" && <SortByAlphabet members={members} /> }
        { sort === "group" && <SortByGroup members={members}/> }
    )
)

In <SortByAlphabet /> component I am setting a component state object from props.members in componentWillReceiveProps() function.

componentWillReceiveProps = props => {
    this.setState({ members : props.members });
}

When I choose "group" sort, <SortByAlphabet /> component is unmounting and <SortByGroup /> is mounting in the DOM. Again when i switch back to "alphabetical" sort, the state variable (members) that was set previosly in <SortByAlphabet /> component becomes NULL because the component was removed from the DOM.

componentWillReceiveProps function is not triggering the second time when re-rendering <SortByAlphabet /> b'coz the props didn't change. But i want to update the state variable like i did it for the first time in componentWillReceiveProps function.

How to do that?

2 comments

@Shubham Khatri 2017-05-04 10:37:26

As @Vikram also said, componentWillReceiveProps is not called for the first time, so when your component is initially mounted your state is not getting set, so you need to set the state with props in the componentWillMount/componentDidMount function(which are called only on the first render) also along with the componentWillReceiveProps function

componentWillReceiveProps = props => {
    if(props.members !== this.props.members) {
        this.setState({ members : props.members });
    }
}

componentWillMount() {
     this.setState({ members : this.props.members });
}

From version 16.3.0 onwards, you would make use of getDerivedStateFromProps method to update the state in response to props change,

getDerivedStateFromProps is invoked after a component is instantiated as well as when it receives new props. It should return an object to update state, or null to indicate that the new props do not require any state updates.

static getDerivedStateFromProps(nextProps, prevState) {
    if(nextProps.members !== prevState.memebers) {
         return { members: nextProps.members };
    }
    return null;
}

EDIT: There has been a change in getDerivedStateFromProps API from v16.4 where it receives props, state as arguments and is called on every update along with initial render. In such a case, you can either trigger a new mount of the component by changing the key

<SortByAlphabet  key={members} />

and in SortByAlphabet have

componentWillMount() {
     this.setState({ members : this.props.members });
}

or use getDerivedStateFromProps like

static getDerivedStateFromProps(props, state) {
    if(state.prevMembers !== props.members) {
         return { members: nextProps.members, prevMembers: props.members };
    }
    return { prevMembers: props.members };
}

@Raaj Nadar 2018-07-22 11:25:55

Sorry dude while voting your answer I pressed the downvote button and the vote is locked until you edit the answer. Please edit the answer so that I can remove my vote.

@Shubham Khatri 2018-07-23 05:49:41

@RaajNadar Done

@Vikram Saini 2017-05-04 10:02:05

componentWillMount is called only once in the component lifecycle, immediately before the component is rendered. It is usually used to perform any state changes needed before the initial render, because calling this.setState in this method will not trigger an additional render So you can update your staate using

componentWillMount ()
{

        this.setState({ members : props.members });


}

@Viktor Seč 2017-05-04 10:17:25

I don't understand your code. Do you really mean to redefine componentWillReceiveProps •inside• componentWillMount? What will that do?

@Vikram Saini 2017-05-04 11:47:55

just set the state inside willmount

@Viktor Seč 2017-05-04 11:48:46

Sure, makes sense now :)

@Vikram Saini 2017-05-04 11:49:34

answered that in hurry.updated the code:)

@user1449456 2018-01-16 13:59:25

setState is async. You should not use it in componentWillMount. Use componentDidMount instead.

@Vikram Saini 2018-01-17 04:43:34

but componentDidMount is called after page is rendered once but in this scenario we have to make any changes before first render of page is done

@Raaj Nadar 2018-07-19 08:59:06

componentWillMount is deprecated and will be removed in future version

Related Questions

Sponsored Content

24 Answered Questions

[SOLVED] What is the difference between state and props in React?

  • 2015-01-16 19:28:27
  • skaterdav85
  • 119522 View
  • 348 Score
  • 24 Answer
  • Tags:   javascript reactjs

3 Answered Questions

[SOLVED] ReactJS - Does render get called any time "setState" is called?

  • 2014-07-13 01:11:07
  • Brad Parks
  • 157932 View
  • 351 Score
  • 3 Answer
  • Tags:   javascript reactjs

0 Answered Questions

React.js component reconstructed every prop change of parent

2 Answered Questions

[SOLVED] React unmount and remount child component

  • 2018-03-09 05:06:33
  • jaimefps
  • 2456 View
  • 4 Score
  • 2 Answer
  • Tags:   reactjs ckeditor

2 Answered Questions

[SOLVED] How to update the props of a rendered react component from App.js?

  • 2017-12-02 16:52:54
  • Hasan Jafri
  • 62 View
  • 1 Score
  • 2 Answer
  • Tags:   javascript reactjs

2 Answered Questions

1 Answered Questions

[SOLVED] Can I use state AND props for control between parent/child

3 Answered Questions

[SOLVED] When does a component unmount?

  • 2017-01-06 04:05:23
  • stackjlei
  • 10500 View
  • 22 Score
  • 3 Answer
  • Tags:   javascript reactjs

0 Answered Questions

Sponsored Content