1
votes

I am new to Redux and I have been reading quite good stuff around it, including memoization technique (especially with reselect). I have a question though and I struggle to find a proper answer. If we add memoization for every single selector (assuming we have a lot), even the simple getters, will it cause performance issues (due to memoized data under the hood maybe?)? Memoization for complex selectors is obviously beneficial as it prevents recomputing if not needed. But I find memoization for simple selectors beneficial as well, to avoid useless rerender.

In fact, I use useSelector hook and the doc states:

When an action is dispatched, useSelector() will do a reference comparison of the previous selector result value and the current result value. If they are different, the component will be forced to re-render. If they are the same, the component will not re-render.

So even for a selector returning the same primitive value (say an int), If i am not wrong, the useSelector should always make the component rerender (even if the selector always returns the same value).

If what I am saying is ture, memoizing even simple getters is usefull for that matter, but can overusing it cause other performance issues?

Thanks for helping

1
Reselect memoization and optimizing code performance is just one of the reasons to use it and better performance is not guaranteed. What is guaranteed is better designed code. As a starting programmer you should try to write functions that implement one thing and functions that need to do more than one thing you need to find a way to combine the "implement one thing" functions (composing functions). This is what reselect can do for your selector functions. A function such as state=>state.one.two implements 2 things: 1) location of one in state 2) location of two in one - HMR

1 Answers

3
votes

Writing memoized selector functions is useful, but many people try to memoize too many selectors which really shouldn't be memoized.

If a selector function just does a simple lookup and return of existing data from the state, there's no need to memoize it - it could just be a simple function. For example:

const selectTodoById = (state, id) => state.todos.entities[id];

Second, you also probably shouldn't create a separate selector for every single state field. Find a reasonable level of granularity.

Memoized selectors are only useful when the selector returns some derived data. A good example of this is filtering an array:

const selectCompletedTodos = createSelector(
  state => state.todos,
  state => state.filters.completed,
  (todos, completed) => todos.filter(t => t.completed === completed)
);

That way, the derived data is only re-calculated when the input values change.

As a side note, I actually am planning to write a new Redux core docs page with guidance and usage information on when and how to write memoized selectors. Until then, you can read my post Using Reselect Selectors for Encapsulation and Performance , which covers a lot of that material already.