componentWillReceiveProps(nextProps) {
// Check to see if the requestRefresh prop has changed
if (nextProps.requestRefresh !== this.props.requestRefresh) {
this.setState({loading: true}, this.updateData);
}
}
As far as my understanding goes, this lifecycle hook is called when a Component's properties are updated by the parent.
This piece of code checks if the requestRefresh property is different (one to update and one that it currently has)
Now what i dont understand is this , this.updateData);
why is this with the setState method. Please help me understand
Secondly where does prevState come from and which lifecycle hook can update it
the setState method can be called with a callback as its second parameter, mainly to handle operations which need to be done when the state is fully updated.
In your example this.updateData is the callback.
setState's first argument is also a function, with the signature (prevState, props) => stateChange, this is allowing you to get access to the previous state when performing updates.
You may want to check the official doc for further details :
https://reactjs.org/docs/react-component.html#setstate
The React maintainers discourage the use of componenetWillReceiveProps.
From the React docs:
It is recommended that you use the static getDerivedStateFromProps lifecycle instead of UNSAFE_componentWillReceiveProps. Learn more about this recommendation here.
To answer your question: prevstate is the previous state, so it is the state of your component before new props are received which in turn might chnage the new state. You can also hanlde prevstate in the static getDerivedStateFromProps method:
static getDerivedStateFromProps(nextProps, prevState)
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.
Related
componentWillMount() {
let dID=this.props.match.params.datumID;
this.setState({datumID: dID});
console.log(dID);
console.log(this.state.datumID);
}
I'm just trying use setState() method.
But the problem is it is not working.
Here is what I get as output:
First console.log() : 66
Second console.log(): null
this.setState accepts a second argument as callback which is fired after the state is successfully changed.
componentWillMount() {
let dID=this.props.match.params.datumID;
console.log(dID);
this.setState({datumID: dID},()=>console.log(this.state.datumID));
}
side note : Move your code to componentDidMount.
componentWillMount() is invoked immediately before mounting occurs. It
is called before render(), therefore setting state in this method
will not trigger a re-render. Avoid introducing any side-effects or
subscriptions in this method.
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.
If you need to set the state based on the previous state,
read about the updater argument below.
this.setState((prevState, props) => {
return {datumID: props.match.params.datumID};
});
Because SetState() is an asynchronous function, use below code
componentWillMount() {
let dID=this.props.match.params.datumID;
this.setState({datumID: dID},
function(){
console.log(this.state.datumID)});
console.log(dID);
}
and if possible try to avoid compenentWillMount since it would be deprecated soon
setState() being an asynchronous function it is in progress of updating the state and javascript being single-threaded language it will execute the next line of code. So if you want to see the state value set you have to do something like this.
componentDidMount=()=> {
let dID=this.props.match.params.datumID;
this.setState({
datumID: dID
},()=>{
console.log(dID);
console.log(this.state.datumID);
});
}
Also I would recommend you to use componentDidMount as willMount won't work in the future as it is deprecated
this.setState is an asynchronous function that takes time and passes the newly assigned
state value over all of the React's life-cycle functions in order to update a state and trigger the re rendering of a component. Your first console logs out the value that is assigned to set state and the next console logs out the value that is currently residing in the state this.state.datumID. if you need to perform operations after setting state you can pass a callback that is triggered after a state is successfully updated.
this.setState({datumID: dID}, () => console.log(this.state.datumID) ); // this will log the updated value
Another thing I want to point out is componentWillMount will wont work in the future release. If you want to do something after DOM is rendered, use componentDidMount or you can perform pre-render task in the constructor of your Class Component.
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.
componentWillRecieveProps is deprecated and getDerivedStateFromProps is being advocated to use.
But componentWillRecieveProps gets called when the props get changed but getDerivedStateFromProps is getting called on any state change even.
My requirement is to reset state on props change. So how would I get to know if the props really got changed.
I am not in favor of storing the props value in state as it would unnecessarily make the state bulkier and I still not have given state management(Redux or Context API) a thought
Please advise
how would I get to know if the props really got changed.
Compare previous prop with new prop.
For simplest use case, just use componentDidUpdate(), with prop comparing:
componentDidUpdate(prevProps) {
// Typical usage (don't forget to compare props):
if (this.props.userID !== prevProps.userID) {
this.fetchData(this.props.userID);
}
}
According to React Doc, it is OK to perform side effect or setState() inside componentDidUpdate().
And setState() can cause re-rendering, which affects component performance. When performance in this case is actually a thing, read on: https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#when-to-use-derived-state
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.
my English is not good but I try, to explain my problem.
I am new in react, I need to know how can I change local component state with global component if conditional is met..
It is difficult to answer because you have no code in your question. You will find you will garner a better response by providing what you have tried. However I will guess that what you need to do is setState according to a condition that you define.
setState(updater[, callback])
From the docs:
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.
For example in psuedo code:
if (predicate) {
this.setState((prevState, props) => {
return {key: value};
});
}
You can start by reading the docs here for more on setState.