Можно ли использовать хуки для одного свойства контекста? - PullRequest
0 голосов
/ 14 января 2020

Я пытаюсь прослушать изменения одного свойства значения контекста. Если я использую контекст React, который имеет значение объекта с дюжиной или около того свойств:

{
  prop1: "value1",
  prop2: "value2",
  prop3: "value3",
  ...
  prop12: "value12"
}

, то каждый компонент, имеющий useContext(MyContext), будет перерисован.

function MyComponent() {
   const c = useContext(MyContext); // The full object

   const {prop1} = c; // This component only cares about prop1

   return <div>{prop1}</div>;
}

Поскольку этот компонент заботится только об одном свойстве в контексте, я не хочу, чтобы он повторно отображался, если prop1 остался прежним. Я пытаюсь создать хук, который будет перерисовываться на основе селектора, например:

useContextProp(MyContext, c => c.prop1); // only re-renders when prop1 changes

, но я не могу найти способ подписаться на изменения. Кто-нибудь знает хитрость?


Обновление:

Мое текущее решение - useMemo в компоненте, чтобы избежать повторного рендеринга сложных макетов:

function MyComponent() {
  const {prop1} = useContext(MyContext);

  // ... other possibly complex calculations

  return useMemo(() => <div>{prop1}</div>, [prop1]); // Assume complex layout
}

Но это не помогает мне с другими частями компонента, где могут быть сложные вычисления, сборка данных и т. Д. c. Подробности не важны, но было бы здорово, если бы был хук, который прослушивал одно значение, чтобы мне не приходилось писать useMemo везде.

Ответы [ 2 ]

0 голосов
/ 14 января 2020

Используйте ловушку useCallback для получения запомненного обратного вызова. https://reactjs.org/docs/hooks-reference.html#usecallback

const memoizedCallback = useCallback(
  () => {
    doSomething(a, b);
  },
  [a, b],
);
0 голосов
/ 14 января 2020

Вы можете использовать React.memo, чтобы обернуть ваш компонент и передать во втором аргументе функцию, которая сравнивает предыдущий реквизит со следующим реквизитом.

function MyComponent(props) {
  /* render using props */
}
function areEqual(prevProps, nextProps) {
  /*
  return true if passing nextProps to render would return
  the same result as passing prevProps to render,
  otherwise return false
  */
}
export default React.memo(MyComponent, areEqual);

См. Здесь в документации https://reactjs.org/docs/react-api.html#reactmemo

Если вы используете React-Redux, их ловушки уже оптимизированы для этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...