When to use the setState function

I have been studying React over the past few days, reviewing several guides and explanations regarding the different ways in which you can write different elements. However, there is one that interests me the most - the setState function for updating / overriding the state properties of a component.

For example, imagine that I have a class with the following:

 class Photos extends React.Component { constructor() { super() state = { pictures: [] } } componentDidMount() { // This is where the fetch and setState will occur (see below) } render() { return { <div className="container"> {this.state.pictures} </div> } } } 

This example shows how I retrieve images from the API.

Given that I performed my selection, the map, and return it for this function, I update the pictures: [] state array with the results obtained in the API call.

My question is related to the various methods that I have seen regarding how to update / override the image state property.

I saw how it is written in two different ways:

1) This is apparently a very simple and convenient way to read

this.setState({pictures: pics})

2) This is more complicated, but I see that it is a safer method

 this.setState(prevState => ({ pictures: prevState.pictures.concat(pics) })) 

Can someone explain the reasons for using? I want to be compatible with the code in the future, dealing with props and states, etc., Therefore, the most universal method, of course, will be preferable.

+4
source share
2 answers

First of all, in your case the two syntaxes are completely different, what you can look for is the difference between

 this.setState({pictures: this.state.picture.concat(pics)}) 

and

 this.setState(prevState => ({ pictures: prevState.pictures.concat(pics) })) 

To understand why the second method is preferred, you need to understand what React does with setState inside

The reaction will first merge the object you passed in to setState() in its current state. Then he will begin this reconciliation thing. Due to Calling, setState() may not immediately update your state.

React can make multiple calls to setState() in a single update for performance.

Consider a simple case to understand this, in your function you can call setState more than once, for example

 myFunction = () => { ... this.setState({pictures: this.state.picture.concat(pics1)}) this.setState({pictures: this.state.picture.concat(pics1)}) this.setState({pictures: this.state.picture.concat(pics1)}) ... } 

which is not a valid user in a simple application, but as the application becomes complex, several setState calls can come from several places, doing the same.

So now, in order to perform an effective update, React performs a batch processing operation, retrieving all the objects passed to each setState() call, joining them together to form one object, and then using that single object to execute setState() . According to setState documentation

If you try to increase the number of items more than once in the same cycle, which will lead to the equivalent:

 Object.assign( previousState, {quantity: state.quantity + 1}, {quantity: state.quantity + 1}, ... ) 

Subsequent calls will override the values ​​from previous calls in the same so that the number will only increase once. If the next state depends on the previous state, we recommend using the updater instead of the form

Therefore, if any of the objects contains the same key, the key value of the last object with the same key is stored. And so the update only happens once with the last value

Demo codesandbox

+3
source

TL DR: The functional setState is generally useful to expect a correct state update when several setState are started in a short amount of time, when a regular setState performs a reconciliation and can lead to an unexpected state.

Please check out this great article on Functional setState for a clear understanding.

And here is the WORKING DEMO

First, you try to do different things in each of your cases, you assign pics in one and concatenate pics in the other.

Suppose this.state.pictures contain [1, 2, 3] , and pics contain [4, 5, 6]

this.setState({pictures: pics})

In the above case, this.state.pictures will contain photos ie this.state.pictures = [4, 5, 6]

 this.setState(prevState => ({ pictures: prevState.pictures.concat(pics) })) 

If in the above snippet this.state.pictures will contain previous photos + pics ie this.state.pictures = [1, 2, 3, 4, 5, 6]

In any case, you can customize it to suit your API needs, if it looks like a page-by-page response, you'd better concatenate the results for each request, otherwise if you get the whole array every time, just assign the whole array.

Normal setState VS Functional setState

Now your question is basically, perhaps you should use setState with an object or with a function.

People use both of them for various reasons, now the functional setState is considered safe, because React does something called a reconciliation process, where it merges several objects inside setState at startup often or simultaneously and changes are applied in one shot, sort of like a batch process . This can lead to unexpected results in scenarios like the ones below.

Example:

 increaseScoreBy3 () { this.setState({score : this.state.score + 1}); this.setState({score : this.state.score + 1}); this.setState({score : this.state.score + 1}); } 

As expected, the score will be increased by 3, but what React does will combine all the objects and update the score only once, increasing it by 1

This is one of the cases where a functional callback is lit because reconciliation is not performed on functions, and the execution of the code below will do something expected. ie update score by 3

 increaseScoreBy3 () { this.setState(prevState => ({ score: prevState.score + 1 })); this.setState(prevState => ({ score: prevState.score + 1 })); this.setState(prevState => ({ score: prevState.score + 1 })); } 
+2
source

Source: https://habr.com/ru/post/1275391/


All Articles