Можно ли избавиться от расчетов useContext при каждом повторном рендеринге? - PullRequest
0 голосов
/ 09 июня 2019

Мы можем предотвратить ненужные вычисления для useEffect с пустым массивом в качестве второго аргумента в ловушке:

// that will be calculated every single re-rendering
useEffect(() => {...some procedures...})
// that will be calculated only after the first render
useEffect(() => {...some procedures...}, [])

Но для ловушки useContext, которую мы не можем сделать, как описано выше, предоставьте второй аргумент.Кроме того, мы не можем обернуть useContext с помощью useCallback, useMemo.Например, у нас есть компонент:

const someComponent = () => {

  const contextValue = useContext(SomeContext);

  const [inputValue, setInputValue] = useState('');

  return (
    <Fragment>
      <input value={inputValue} onChange={onInputChange} />
      <span>{contextValue}</span>
    </Fragment>
  )

Проблема в том, что при каждом наборе текста будет запускаться повторный рендеринг, и у нас будет ненужный повторный рендеринг useContext каждый раз.Одним из решений является торможение компонента на два:

const WithContextDataComponent = () => {

  const contextValue = useContext(SomeContext);

  return <JustInputComponent contextValue={contextValue} />

const JustInputComponent = (props) => {

  const [inputValue, setInputValue] = useState('');

  return <input value={inputValue} onChange={onInputChange} />

Итак, теперь проблема исчезла, но два компонента у нас есть.А в верхнем компоненте вместо <SomeComponent /> мы должны импортировать <WithContextDataComponent />, что, на мой взгляд, немного некрасиво.

Можно ли остановить ненужный повторный рендеринг для useContext без разделения на два компонента?

1 Ответ

0 голосов
/ 09 июня 2019

Из API React Hooks:

https://reactjs.org/docs/hooks-reference.html#usecontext

useContext

const value = useContext(MyContext);

Принимает объект контекста (значение, возвращенное из React.createContext) и возвращает текущее значение контекста для этого контекста.Текущее значение контекста определяется значением prop ближайшего над вызывающим компонентом в дереве.

Когда обновляется ближайший выше компонента, этот хук вызовет повторное рендеринг с последним переданным значением контекстаэтому поставщику MyContext.

Как видно из документации, ловушка useContext() будет вызывать повторную визуализацию вашего компонента, только если значения, которые он предоставляет, изменяются в какой-то момент,Ответ: это, вероятно, ваше предполагаемое поведение.Зачем вам нужны устаревшие данные в вашем контекстном хуке?

Когда ваш компонент выполняет рендеринг сам по себе, без изменений в контексте, строка useContext() просто возвращает те же значения, что и в предыдущемrender.

Кажется, вы используете хук useContext() так, как это было задумано.Я не вижу в этом ничего плохого.

...