Ненужные повторные рендеры с useContext - PullRequest
1 голос
/ 19 февраля 2020

В этом примере

function App() {
  const [value1, dispatch1] = useReducer(reducer, initialState1);
  const [value2, dispatch2] = useReducer(reducer, initialState2);

  return (
    <React.Fragment>
      <button
        onClick={() => {
          dispatch1({ type: "setFirstName", firstName: "nick" });
        }}
      >
        change1
      </button>
      <button
        onClick={() => {
          dispatch2({ type: "setFamilyName", familyName: "fname" });
        }}
      >
        change2
      </button>
      <JediContext1.Provider value={value1}>
        <Display1 />
      </JediContext1.Provider>
      <JediContext2.Provider value={value2}>
        <Display2 />
      </JediContext2.Provider>
    </React.Fragment>
  );
}

я использовал два контекста для рекомендации из здесь . Но я мог неправильно понять, и, возможно, проблема с github относится к другому делу? Потому что, похоже, это не решает мою проблему.

Проблема с приведенным выше кодом заключается в том, что если я нажму кнопку change1, которая изменит value1, компонент Display2 также переопределяется, что даже не потребляет value1.

На самом деле это имеет смысл для меня, потому что Я изменил состояние в приложении, следовательно, он переопределяет все его дочерние элементы. Но тогда я не понимаю использование рекомендации из ссылки на github, потому что это не решило мою проблему здесь?

Это может быть проблематично c производительности, если у вас есть большое приложение и root поставщик контекста сказать.

Ответы [ 2 ]

3 голосов
/ 19 февраля 2020

Обычно, не всегда, вы хотите запомнить children ваших провайдеров, чтобы избежать этого. В этом случае Display1 и Display2 могут быть PureComponent или просто

const Display1 = React.memo(() => <Whatever />)

Проблема github, на которую вы ссылаетесь, относится к другой проблеме: ваш провайдер содержит много данных, и вы хотите подписаться только часть этого. Могут быть случаи, когда вы обновляете значение контекста, и он будет повторно отображать потребителя, который не использует это значение. В этом случае вы можете просто разделить его на несколько контекстов, как объяснено. Но это не твоя проблема здесь.

1 голос
/ 19 февраля 2020

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

const MemoDisplay = React.memo(Display1);
const MemoDisplay2 = React.memo(Display2);

function App() {
  ...
  return (
    <React.Fragment>
      ...
      <JediContext1.Provider value={value1}>
        <MemoDisplay />
      </JediContext1.Provider>
      <JediContext2.Provider value={value2}>
        <MemoDisplay2 />
      </JediContext2.Provider>
    </React.Fragment>
  );
}

Edit React Hooks - useContext()

Обратите внимание на журналы , после этого нет ненужных рендеров.

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