Concurrent Store

Skipping re-renders with the previous result

You will learn

Reading from a normalized store builds a fresh object tree every time. Memoised components compare by identity, so they all re-render even though most of their data is unchanged.

A selector here is called as selector(state, previous). The second argument is its own previous result, so it can hand back the parts that did not move instead of returning all-new objects.

Try it

  1. Click Ada gains a follower a few times.
  2. Watch stats rendered at the bottom of each column.

Notice that only Ada’s counter moves on the right. Grace and Alan came back as the objects they already were, so their memo held.

An equality function cannot do this. It can only answer whether to keep the whole result; recycling needs the previous value itself.

(state) => project(state)fresh
AAda Lovelace128 posts · 9,421 followers
GGrace Hopper311 posts · 18,022 followers
AAlan Turing74 posts · 12,907 followers
stats renderedada 0grace 0alan 00 total

Everyone re-renders. Ada’s count moved, so the projection is new, and so is every object inside it.

(state, previous) => recycleNodesInto(previous, …)recycled
AAda Lovelace128 posts · 9,421 followers
GGrace Hopper311 posts · 18,022 followers
AAlan Turing74 posts · 12,907 followers
stats renderedada 0grace 0alan 00 total

Only Ada re-renders. Grace and Alan came back as the same objects, so their memo held.