Reactjs life cycle: call while only change state - reactjs

In below image we have react life cycle methods.
Is there any other method which will call only when we change the state only ?
Here shouldComponentUpdate & comonentWillUpdate both will call in case of changes into props and state.
Thank you in Advance !!!

No lifecycle methods exist, but you can use the existing shouldComponentUpdate and componentWillUpdate hooks and wrap your state change logic in a check to make sure that previousState !== this.state

When you change your state, shouldComponentUpdate will be called, if this method return false. No other lifecyle methods will be called anymore.
So just check and return false in shouldComponentUpdate if you don't want other lifecycle methods to be called.

Related

Does shouldComponentUpdate block getDerivedStateFromProps?

I am updating a legacy component which uses:
shouldComponentUpdate() to avoid an expensive state re-computation
componentWillUpdate() to do the re-computation and render if 1 passes
The docs say
if shouldComponentUpdate() returns false, then
UNSAFE_componentWillUpdate(), render(), and componentDidUpdate() will not be invoked`
But getDerivedStateFromProps() is not mentioned. I want to use this to replace the deprecated componentWillUpdate().
My question is: does shouldComponentUpdate() block the invocation of getDerivedStateFromProps() in the same way as it did for componentWillUpdate()?
NB: I know about looking at memoization as another solution.
When the passed props change getDerivedStateFromProps() function is called and then shouldComponentUpdate().
However if state changes only the shouldComponentUpdate() lifecycle function is triggered.
You can check the component lifecycle diagram here for more help

Is setState() inside componentDidMount() considered an anti-pattern

I've just had a look at this discussion about setState() inside componentDidMount().
You can see that after the render() function, the componentDidMount() function will be called by React. When you put a setState() call in componentDidMount() then you are causing the entire component tree be re-rendered not only the current component - not to forget, the current component did just finished with rendering.
And some people suggested to put setState() call inside componentWillMount(). In some cases, I want to get the height of a rendered element and store it as state, and the above method wouldn't work. I also had a look at the React official website, and it suggests to do Ajax call inside componentDidMount(), which again goes against the above idea.
So, am I wrong about putting setState() inside componentDidMount()? If yes, what should I apply as an alternative?
You may call setState() immediately in componentDidMount(). It will
trigger an extra rendering, but it will happen before the browser
updates the screen. This guarantees that even though the render() will
be called twice in this case, the user won’t see the intermediate
state. Use this pattern with caution because it often causes
performance issues. In most cases, you should be able to assign the
initial state in the constructor() instead. It can, however, be
necessary for cases like modals and tooltips when you need to measure
a DOM node before rendering something that depends on its size or
position.
React docs
Using DidMount makes it clear that data won’t be loaded until after
the initial render. This reminds you to set up initial state properly,
so you don’t end up with undefined state that causes errors.
Example
TLDR:
- If you have all needed data in constructor - assign state there
constructor(props) {
super(props);
// Don't call this.setState() here!
this.state = { counter: 0 };
}
Call async action, touch DOM in componentDidMount()
Your case with unknowing the height of a rendered element might be a valid excuse to use setState inside componentDidMount. However in such a case I would definitely add another lifecycle method,shouldComponentUpdate, to control the rerender issue.
Normally you don't want to do synchronous state setting inside componentDidMount, you should just put it in the constructor. However element height is a bit unique, since you can't actually get the height of an element until it's mounted and rendered into the DOM.
So normally not, but in the case of element height it's ok to do it in componentDidMount.
You can do Async call and you must do it inside the componentDidMount() lifecycle hook. But this will call the render method again.
If you don't want the re-render to happen again, use the shouldComponentUpdate() method to prevent re-rendering the DOM. Example as follows:
shouldComponentUpdate (nextProps, nextState) {
// check the condition here
if (nextState.something !== 'value') {
// stop re-rendering
return false;
}
// continue rendering
return true;
}

How to migrate to new React lifecycle API?

As you know some lifecycle methods like componentWillReceiveProps are now deprecated.
Well, my code used this lifecycle method and now I have no idea how to migrate to the new API of React.
Here is how I used:
componentWillReceiveProps(nextProps) {
if (nextProps.newPost) {
this.props.posts.unshift(nextProps.newPost);
}
}
In the react blog I could read that...
Together with componentDidUpdate, this new lifecycle should cover all
use cases for the legacy componentWillReceiveProps.
... but how to implement this?
componentDidUpdate() is invoked immediately after updating occurs. This method is not called for the initial render.
Use this as an opportunity to operate on the DOM when the component has been updated. This is also a good place to do network requests as long as you compare the current props to previous props (e.g. a network request may not be necessary if the props have not changed).
componentDidUpdate(prevProps) {
// Typical usage (don't forget to compare props):
if (this.props.userID !== prevProps.userID) {
this.fetchData(this.props.userID);
}
}
Note that it must be wrapped in a condition like in the example above, or you’ll cause an infinite loop.
you can use getDerivedStateFromProps or componentDidMount, there is sequence to running lifecycles :
getDerivedStateFromProps
shouldComponentUpdate
render
getSnapshotBeforeUpdate
componentDidUpdate

Can getDerivedStateFromProps be used as an alternative to componentWillReceiveProps

getDerivedStateFromProps is being added as a safer alternative to the legacy componentWillReceiveProps.
This is what the 16.3 doc says. Is there anything more to this lifecycle or is it just a name change?
getDerivedStateFromProps is not just a name change to componentWillReceiveProps. It's a static method that is called after a component is instantiated or before it receives new props, unlike componentWillReceiveProps which was not called on initial render.
Return an object to update state in response to prop changes.
Return null to indicate no change to state.
Static lifecycle methods are introduced to prevent unsafe access of instance properties.
The purpose of getDerivedStateFromProps is to only update the state based on props change and not take actions like API call or function call based on prevProps that could be done. All of these could be done in the componentDidUpdate lifecycle function which is safe because even if the change was done in componentWillReceiveProps the data would arrive after render and most often you would trigger another re-render, which could well be done in the componentDidUpdate lifecycle method.
You can refer to this RFC to understand more about why this change was made.

Why official doc recommend to use componentDidMount instead of callback in setState?

https://facebook.github.io/react/docs/react-component.html#setstate
I have seem the official doc says :
The second parameter to setState() is an optional callback function that will be executed once setState is completed and the component is re-rendered. Generally we recommend using componentDidUpdate() for such logic instead.
why they recommend to use componentDidUpdate instead of callback when we need to use the latest state?
componentDidUpdate is also invoked immediately after every updating occurs. At this time, latest state is updated.
Putting all checking state logics in componentDidUpdate is easier for managing than many callback with every setState.
By the way if you use redux, we will not do setState in your components.
More about redux
Note: componentDidUpdate is not called for the initial render.
Learn more Component life cycle https://facebook.github.io/react/docs/react-component.html#componentdidupdate

Resources