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

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

Related

Setting State Between Radio Buttons

An example of the issue is found on CodeSandBox. Am I short circuiting myself between TRUE/FALSE values?
Can someone please help explain why the state variable isOptionOne is not being set as expected? Upon calling setIsOptionOne I would think that I can use isOptionOne in the remaining lines of code of the function. Unfortunately, that does not seem to be the case. To verify, see the console.log output. The two values for isDefault and isOptionOne should match.
Where am I going wrong? Thank you.
That is the expected behavior. React batches the state updates, which means it doesn't immediately update the state and re-render everything after each setState method call. From official documentation:
setState() enqueues changes to the component state and tells React
that this component and its children need to be re-rendered with the
updated state. This is the primary method you use to update the user
interface in response to event handlers and server responses.
Think of setState() as a request rather than an immediate command to
update the component. For better perceived performance, React may
delay it, and then update several components in a single pass. React
does not guarantee that the state changes are applied immediately.
setState() does not always immediately update the component. It may
batch or defer the update until later. This makes reading this.state
right after calling setState() a potential pitfall. Instead, use
componentDidUpdate or a setState callback (setState(updater, callback)), either of which are guaranteed to fire after the update
has been applied. If you need to set the state based on the previous
state, read about the updater argument below.
Additionally, the above document is for the traditional class component's setState API. If you want to detect a change in your hook-based state, use useEffect.

Calling setState inside componentDidMount synchronously

I am beginner in react and I am learning about lifecycle hooks. I came across some articles stating don't call setState synchronously inside componentDidMount. But we can setState in then block of promise.
The reason mentioned was setState will cause re-render of the component, which will affect performance.
My question is, even if I write setState inside then block of promise, re-render will be there anyways, also setState is asynchronous so it won't be called immediately. So why its not recommended to call setState inside componentDidMount synchronously, And how does writing inside then block of promise solves the problem if there are any.
PS: I have researching on SO for quite a while, but couldn't find answers that says don't call setState synchronously, I found some related answers, but didn't answer my question, and I couldn't get them because they were totally related to some scenario.
React setState calls are asynchronous. React decides when to do it efficiently. For example, multiple setState calls are batched together into one single update. The way to get around this is using setStates's 2nd parameter which is a callback that will execute once setState is completed and the component re-rendered.
handleThis = () => {
this.setState({someVar: someVal}, funcToCallimmediately )
}
To test, console.log the state variable just after setState() and write another console.log inside the "funcToCallimmediately" function.
📝 Take note that if you need to set the state based on the previous state you should use another method. First, just know that setState's 1st parameter can be an object and can also be a function. So you do it like this...
this.setState((state, props) => {
return {counter: state.counter + props.step};
});
To understand more, read more about setState() here. You'll get what you need.

ReactJS - componentWillReceiveProps uses

I started to learn ReactJS I would like to know what are the scenario to use componentWillReceiveProps? what is the purpose for using it?
Currently i'm using props without it, is there any impact ?
In cases where you want to take action in child component in response to props change, componentWillReceiveProps was supposed to the right candidate. Example of it is when you have a user component which calls and API to fetch the user details based on an ID that is provided by its parent and anytime the prop ID changes, you would want to trigger the API call again and re-render the updated view.
However, componentWillReceiveProps is called on every parent re-render and not just prop change, so while you are using it, you must provide a conditional check between previous and currentProps like
componentWillReceiveProps(nextProps) {
if(nextProps.id !== this.props.id) {
//API call goes here
}
}
However from v16 onwards, its discouraged to use componentWillReceiveProps and instead its usage is split into componentDidUpdate which is where you can make API calls and getDerivedStateFromProps or memoized functions or key updates in order to make state change based on prop change.
Please check componentWillReceiveProps vs getDerivedStateFromProps for more details
If your component accept some props and if on change of that props you would like to do some business logic or state change, componentWillReceiveProps is the lifecycle method where this logic should go, as every time props changes componentWillReceiveProps is called.

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.

Does my component need force update to scrollIntoView?

I'm making my first react + redux app and I have a question. I have a component that render a input field and, as some content is added above it, I need it to scrollIntoVIew.
So, I just added the scrollIntoView in the component componentDidUpdate() lifecycle method :
componentDidUpdate() {
console.log("scroll");
this.refs.input.scrollIntoView();
}
The only problem is that this component does not re render each time (as nothing change in it) so the scrollIntoVIew is called only one time.
I could force update to component but this is not really good practice isn't it ? What can I do in this case ?
You could call setState and update some object in the component's state every time content is added to re-render the component, and componentDidUpdate will be invoked.
You could also use the second argument (callback) to setState, but the React docs say the following about second argument of setState:
The second parameter 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.

Resources