React.memo и аннулирование в функциональном компоненте не аннулируют

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

const SpeakerDetail = React.memo(
  ({ record, prop1 }) => {...

Когда я вызываю этот компонент, я делаю это так

const record = {prop1: 'abcd', prop2: 'efgh', prop3: 'ijkl'};
const Speakers = () => {
   ...
   return(
      <SpeakerDetail record={record} prop1={record.prop1}></SpeakerDetail>
   )...

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

Проблема в том, что если я явно не передаю prop1 в качестве отдельного параметра, версия кеша React.memo не распознает изменение свойства записи.

Есть ли способ не передавать это избыточное свойство, чтобы React.memo пересчитывал?

Это похоже на проблему с глубоким / неглубоким копированием, но я не уверен.


person Pete    schedule 24.07.2020    source источник


Ответы (1)


memo HOC

memo HOC просто выполняет поверхностную проверку равенства переданных свойств. Вы можете указать функцию равенства в качестве второго параметра для memo HOC, которая принимает предыдущий и следующий реквизиты, возвращающие true, если сравнение вернет тот же результат, в противном случае - false.

const SpeakerDetail = React.memo(
  ({ record, prop1 }) => {...},
  (prevProps, nextProps) => {
    if (prevProps.record.prop1 !== nextProps.record.prop1) return false;
    return true;
  },
);
person Drew Reese    schedule 25.07.2020
comment
Привет, @DrewReese. На данный момент я снял отметку с этого вопроса как ответ, потому что, похоже, он не решает мою проблему. Я создал здесь пример stackblitz, а также опубликовал новый вопрос, поскольку теперь пример другой. stackoverflow.com/questions/63123846/ URL-адрес Stackblitz: stackblitz .com / edit / response-upe9vu? file = SpeakerWithMemo.js. - person Pete; 28.07.2020
comment
URL для редактирования stackblitz.com/edit/react-upe9vu - person Pete; 28.07.2020
comment
@Pete Я ответил на другой вопрос. Похоже, вы изменяли свой объект состояния, и это было причиной проблемы. - person Drew Reese; 28.07.2020
comment
Примечание здесь. Мне нравится второй параметр для сравнения предыдущих и следующих реквизитов, но оказывается, что вам не нужно этого делать, если вы правильно управляете состоянием. React, кажется, разбирается в мелком вложении +1. Я обновил свой stackblitz здесь, чтобы показать его: stackblitz.com/edit/react-ayfxqg - person Pete; 28.07.2020
comment
@Pete Да, это очень вероятно. Я считаю, что он предназначен для гораздо более сложных форм опорных объектов / более глубоких проверок. - person Drew Reese; 28.07.2020