Прекратить повторную визуализацию функционального компонента react

#reactjs #react-redux #react-hooks

#reactjs #react-redux #реагирующие хуки

Вопрос:

Я использую сторонний компонент, который повторно рендерится при каждом изменении состояния, что хорошо, но в некоторых случаях я не хочу, чтобы он повторно отображался, даже если состояние меняется. Есть ли способ сделать это с помощью функционального компонента react. Я прочитал онлайн, и там говорится, что используйте shouldComponentUpdate (), но я пытаюсь использовать функциональный компонент и попробовал использовать React.Примечание, но он все еще выполняет повторный рендеринг

Код

 const getCustomers = React.memo((props) => {

useEffect(() => {

});

return (
<>
<ThirdPartyComponent>
do other stuff 
{console.log("Render Again")}
</ThirdPartyComponent>

</>
)
});
  

Комментарии:

1. ...but in some instances I do not want it to re-render even if the state changes... это сводит на нет всю цель React. Это похоже на проблему XY, что вы на самом деле пытаетесь сделать?

2. Можете ли вы быть более конкретным? В какой ситуации вы хотите приостановить рендеринг? Это довольно необычный вариант использования, но все еще действующий

3. @Dupocas Да, я хочу остановить повторный рендеринг в некоторых случаях, потому что я получаю сообщение об ошибке при использовании другой библиотеки, которая unstable_flushDiscreteUpdates: не удается сбросить обновления, когда React уже отрисовывается.

4. Можете ли вы дополнить свой вопрос или опубликовать изолированную среду?

Ответ №1:

Для реквизита:

Как мне реализовать shouldComponentUpdate?

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

 const Button = React.memo((props) => {
  // your component
});
  

Это не перехват, потому что он не составляется так, как это делают перехваты. React.memo эквивалентен PureComponent , но он сравнивает только реквизиты. (Вы также можете добавить второй аргумент, чтобы указать пользовательскую функцию сравнения, которая принимает старые и новые реквизиты. Если он возвращает значение true, обновление пропускается.)

Для состояния:

Для достижения этого нет способа сборки, но вы можете попытаться извлечь свою логику в пользовательский хук. Вот моя попытка выполнить повторный рендеринг только тогда, когда shouldUpdate возвращает true. Используйте его с осторожностью, потому что это противоположно тому, для чего был разработан React:

 const useShouldComponentUpdate = (value, shouldUpdate) => {
  const [, setState] = useState(value);
  const ref = useRef(value);

  const renderUpdate = (updateFunction) => {
    if (!updateFunction instanceof Function) {
      throw new Error(
        "useShouldComponentUpdate only accepts functional updates!"
      );
    }

    const newValue = updateFunction(ref.current);

    if (shouldUpdate(newValue, ref.current)) {
      setState(newValue);
    }

    ref.current = newValue;
    console.info("real state value", newValue);
  };

  return [ref.current, renderUpdate];
};
  

Вы бы использовали его следующим образом:

   const [count, setcount] = useShouldComponentUpdate(
    0,
    (value, oldValue) => value % 4 === 0 amp;amp; oldValue % 5 !== 0
  );
  

В этом случае повторный рендеринг произошел бы (из-за использования setcount ), если и только если shouldUpdate возвращает true . т.Е. Когда значение кратно 4, а предыдущее значение не кратно 5. Поиграйте с моим примером CodeSandbox, чтобы увидеть, действительно ли это то, чего вы хотите.