Devashish
Devashish

Reputation: 1290

Change in 1 state property triggers re render of whole element and all children

I have a parent component with its state like this:

var db = {
    one: {
        name: 'xyz',
        color: 'blue',
        seen: false
    },
    two: {
        name: 'abc',
        color: 'red',
        seen: false
    },
    ........and so on many objects
};

this.state = { ...db };

Now when i update only 1 of these objects, all of the parent element is re rendered. how can i avoid this and only render that part which changed. How should i set state (which way/method) so that the shallow comparison that react does returs true only for that particular element object and not for the whole state object?

currently, this is how i am setting my state:

this.setState(state => {
    state[objectKeyName] = _editedObject;
});

Upvotes: 1

Views: 373

Answers (1)

zeh
zeh

Reputation: 10659

You can't. React's shallow comparison (via PureComponent) will simply check whether the object is different. Since it is different, it triggers a re-render. There's no way for it to know "what" to re-render, as in some kind of partial render.

Your best bet is either to make the children PureComponents themselves or apply some behavior via shouldComponentUpdate. You'd still trigger the parent render, but the children would be smart enough not to re-render.

As a note of warning, I'd advise against trying to be too clever here. You can easily make things more complicated and less performant at the same time. React's renderer works via a virtual DOM diffing, so if the actual DOM rendering of a component isn't changing, it's not going to do much. You still have the overhead of re-rendering the virtual DOM and checking for differences, of course, so it makes sense to use PureComponent/shouldComponentUpdate in places if you can. But it's not like React is expensively recreating your entire HTML all the time.

There's a lot of documentation around that talks about best practices to avoid re-rendering. This one seems to be what you're looking for.

Upvotes: 2

Related Questions