Почему этот код использует и useMemo, и createSelector? - PullRequest
1 голос
/ 18 июня 2020

Документация React-Redux предоставляет этот пример , когда селектор используется в нескольких экземплярах компонента и зависит от свойств компонента.

import React, { useMemo } from 'react'
import { useSelector } from 'react-redux'
import { createSelector } from 'reselect'

const makeNumOfTodosWithIsDoneSelector = () =>
  createSelector(
    state => state.todos,
    (_, isDone) => isDone,
    (todos, isDone) => todos.filter(todo => todo.isDone === isDone).length
  )

export const TodoCounterForIsDoneValue = ({ isDone }) => {
  const selectNumOfTodosWithIsDone = useMemo(
    makeNumOfTodosWithIsDoneSelector,
    []
  )

  const numOfTodosWithIsDoneValue = useSelector(state =>
    selectNumOfTodosWithIsDone(state, isDone)
  )

  return <div>{numOfTodosWithIsDoneValue}</div>
}

export const App = () => {
  return (
    <>
      <span>Number of done todos:</span>
      <TodoCounterForIsDoneValue isDone={true} />
      <span>Number of unfinished todos:</span>
      <TodoCounterForIsDoneValue isDone={false} />
    </>
  )
}

Почему в функции TodoCounterForIsDoneValue автор помещает makeNumOfTodosWithIsDoneSelector в useMemo? Насколько я понимаю, createSelector из reselect состоит в том, что он генерирует мемоизированный селектор, так какова цель «двойного» запоминания этого селектора?

1 Ответ

2 голосов
/ 18 июня 2020

Потому что каждый компонент нуждается в собственном уникальном экземпляре селектора для правильного поведения мемоизации. Если многие компоненты используют один и тот же экземпляр селектора и каждый передает свои собственные аргументы (например, selectThingById(state, props.itemId)), селектор никогда не запомнит правильно. Создавая уникальный экземпляр для каждого компонента, каждый селектор может передавать свои собственные отдельные аргументы и получать согласованную мемоизацию.

...