MobX: Avoid triggering re-render when object keys are not used in views

Viewed 926

I have a list of observable objects:

[
    {
        key1: "x",
        updateTs: "y"
    },

    ...
]

The user can mutate these objects through the UI.

Those changes are sent to a remote server, and once the request returns the "updateTs" is updated.

The issue is that when online, this causes a double render:

  1. Initial edit from UI.

  2. When remote request returns and edits updateTs.

I am not using updateTs in my view, only its sibling keys (key1).

MobX @observer tracks reads to objects, so it triggers a re-render.

This causes UI jank as it consumes JS CPU time to re-compute the virtual dom and diff it (the list is very large).

Is it possible to avoid the second re-render?

2 Answers

In order to avoid the "jank", make your Mobx components as small as possible. For example, create your "item" component with a "key" subcomponent and a "ts" subcomponent (and make both subcomponents observers). Mobx then should only cause the subcomponents to update, and because each subcomponent only cares about one property, editing one should not affect the other.

You will have to pass the entire "item" observable to the component (as a prop), though, so that Mobx can track it properly. Also, make sure that updates to the item collection and values are in place, and don't re-create objects.

You are correct that reading a property causes Mobx to track that property's changes. Therefore, if you do not want a component to re-render, then you must not change anything you read from in that component. However, subcomponents that are observers track Mobx properties in separate contexts. So if you read something in a child observer component but not in the parent component, then Mobx won't update the parent.

See also: Optimizing Mobx for React

I guess you can find answer here component lifecycle

Choose one of variant that fits you: 1. uses shouldcomponentupdate 2. uses PureComponent

Related