Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React state array updates/renders entire array, is there a work-around?

Here's the basic idea...

constructor(props) {
    super(props);
    this.state = {
        children: [{id:1},{id:2}], // HERE ARE THE TWO OBJECTS
        style: {top: 0}
    };
}

Now let's say I update one of those two objects but those objects are mapped to an array of components.

<div className="thread">
    {this.state.children.map((child) =>
        <Post
            key={child.id}
            id={child.id}
        />
    )}
</div>

Now... when I update one of those objects...

changeID (id, newID) { // this is a different function, just an example
    let temp = this.state.children;
    for (let i = 0; i < temp.length; i++) {
        if (temp[i].id === id) {
            temp[i].id = newID; // <- update this
        }
    }
    this.setState({
        children: temp // <- plug temp[] back as the updated state
    });
}

I throw the new state back in, but it updates each of the mapped objects.

// on one change to one element
id 1 POST UPDATED
id 2 POST UPDATED

1) Does it re-render EVERY component (in the mapped array) or is it smart enough to tell that the state values passed as props to the mapped component are the same?

2) Is it incredibly expensive in processing power if that array is significantly longer?

3) If yes, how can I go about this better? Constructive criticism is appreciated.

Thank you!

like image 204
jscul Avatar asked Jun 29 '17 10:06

jscul


People also ask

Does React Rerender entire component on state change?

As we already saw before, React re-renders a component when you call the setState function to change the state (or the provided function from the useState hook in function components). As a result, the child components only update when the parent component's state changes with one of those functions.

What happens when state is updated in React?

State updates in React are asynchronous; when an update is requested, there is no guarantee that the updates will be made immediately. The updater functions enqueue changes to the component state, but React may delay the changes, updating several components in a single pass.

Why we should never update React state directly?

One should never update the state directly because of the following reasons: If you update it directly, calling the setState() afterward may just replace the update you made. When you directly update the state, it does not change this.

Does React re-render entire component?

🧐 Re-renders reason: context changes When the value in Context Provider changes, all components that use this Context will re-render, even if they don't use the changed portion of the data directly.


1 Answers

This is how react works, whenever you change any state variable it will re-render the complete component and update the virtual dom not the actual dom, then it will check the diff between these two and change only that particular element in actual dom.

As per DOC:

React provides a declarative API so that you don't have to worry about exactly what changes on every update.

React Only Updates What's Necessary:

React DOM compares the element and its children to the previous one, and only applies the DOM updates necessary to bring the DOM to the desired state.

DOM Elements Of The Same Type:

When comparing two React DOM elements of the same type, React looks at the attributes of both, keeps the same underlying DOM node, and only updates the changed attributes.

For Example:

<div className="before" title="stuff" />

<div className="after" title="stuff" />

By comparing these two elements, React knows to only modify the className on the underlying DOM node.

Use of Keys:

React supports a key attribute. When children have keys, React uses the key to match children in the original tree with children in the subsequent tree.

Imp:

Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity. Keys used within arrays should be unique among their siblings. However they don't need to be globally unique.

For example:

<ul>
  <li key="2015">Duke</li>
  <li key="2016">Villanova</li>
</ul>

<ul>
  <li key="2014">Connecticut</li>
  <li key="2015">Duke</li>
  <li key="2016">Villanova</li>
</ul>

Now React knows that the element with key '2014' is the new one, and the elements with the keys '2015' and '2016' have just moved.

Check this article: How Virtual-DOM and diffing works in React

like image 112
Mayank Shukla Avatar answered Nov 11 '22 00:11

Mayank Shukla