React.memo - por que minha função de igualdade não está sendo chamada?

8

Eu tenho um componente pai que processa uma coleção de filhos com base em uma matriz recebida via adereços.

import React from 'react';
import PropTypes from 'prop-types';
import shortid from 'shortid';
import { Content } from 'components-lib';
import Child from '../Child';

const Parent = props => {
  const { items } = props;

  return (
    <Content layout='vflex' padding='s'>
      {items.map(parameter => (
        <Child parameter={parameter} key={shortid.generate()} />
      ))}
    </Content>
  );
};

Parent.propTypes = {
  items: PropTypes.array
};

export default Parent;

Toda vez que um novo itemé adicionado, todos os filhos são renderizados novamente e eu estou tentando evitar isso. Eu não quero que outros filhos sejam renderizados novamente. Apenas quero renderizar o último que foi adicionado.

Então, tentei React.memo na criança em que provavelmente compararei pela codepropriedade ou algo assim. O problema é que a função de igualdade nunca é chamada.

import React from 'react';
import PropTypes from 'prop-types';
import { Content } from 'components-lib';

const areEqual = (prevProps, nextProps) => {
  console.log('passed here') // THIS IS NEVER LOGGED!!
}

const Child = props => {
  const { parameter } = props;
  return <Content>{parameter.code}</Content>;
};

Child.propTypes = {
  parameter: PropTypes.object
};

export default React.memo(Child, areEqual);

Alguma idéia do porquê?

Joana Deluca Kleis
fonte
1
Ele não registrará nada até que os objetos sejam alterados. Tente ajustar adereços em seus pais.
tipo de usuário
você tem um erro ao importar `Import Child from '../Child' ', não tenho certeza se essa é a causa.
Afia
1
Se você está tentando impedir repetições desnecessárias dos componentes de seus filhos, deve atribuir a cada uma uma chave exclusiva. O React possui uma maneira muito delicada de lidar com as chaves e, se a chave de um componente mudar, o React a renderiza completamente. Se você gerar uma nova chave toda vez, o React renderizará tudo sempre que os objetos no pai forem alterados.
22719 Konstantin
@konstantin você é um gênio !! Eu removi a geração de chaves e funcionou como um encanto !! : D a igualdade fn agora está sendo chamada e eu poderia fazer a comparação. Obrigado!! Você pode adicionar isso como uma resposta para que eu possa votar como a correta?
Joana Deluca Kleis
Ainda bem que pude ajudar :), irá adicioná-lo agora
Konstantin

Respostas:

2

Em resumo, o motivo desse comportamento é devido ao modo como o React funciona.

O React espera uma chave exclusiva para cada um dos componentes, para que ele possa acompanhar e saber qual é qual. Ao usar shortid.generate()um novo valor da chave, é criada, a referência ao componente é alterada e o React pensa que é um componente completamente novo, que precisa ser renderizado novamente.

No seu caso, em qualquer alteração de objetos no pai, o React renuncia todos os filhos porque as chaves serão diferentes para todos os filhos em comparação com a renderização anterior.

Consulte esta maravilhosa resposta a este tópico

Espero que isto ajude!

Konstantin
fonte
0

Não conheço o resto da sua biblioteca, mas fiz algumas alterações e seu código e (principalmente) parece funcionar. Então, talvez, isso possa ajudá-lo a diminuir a causa.

https://codesandbox.io/s/cocky-sun-rid8o

Lhew
fonte
Obrigado por dedicar seu tempo e por criar essa caixa de proteção de código. Eu agradeço! Meu caso é um pouco diferente, você está explicitamente alterando a propriedade quando clica no botão e isso aciona o fn. No meu caso, estou apenas adicionando um novo item à matriz dos pais, criando um novo filho toda vez e esperando que o fn seja acionado. Acabei de descobrir que o problema era a chave que eu estava gerando aleatoriamente.
Joana Deluca Kleis