React.memo: ¿por qué no se llama a mi función de igualdad?

8

Tengo un componente principal que representa una colección de hijos basada en una matriz recibida a través de accesorios.

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;

Cada vez que itemse agrega un nuevo , todos los niños se vuelven a procesar y estoy tratando de evitarlo, no quiero que se vuelvan a procesar otros niños, solo quiero renderizar el último que se agregó.

Así que probé React.memo en el niño donde probablemente compararé por la codepropiedad o algo así. El problema es que la función de igualdad nunca se llama.

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);

Alguna idea de por qué?

Joana Deluca Kleis
fuente
1
No registrará nada hasta que se cambien los accesorios. Intenta ajustar los accesorios en tus padres.
usuario amable
tiene un error en la importación 'import Child from' ../Child '' no estoy seguro si esa es la causa.
Afia
1
Si está tratando de evitar la repetición innecesaria de componentes de sus hijos, debe dar a cada uno una clave única. React tiene una forma muy delicada de manejar las claves, y si la clave de un componente cambia, entonces React lo vuelve a procesar por completo. Si genera una nueva clave cada vez, React volverá a entregar todo cada vez que cambien los accesorios en el padre.
Konstantin
@konstantin eres un genio !! ¡Eliminé la generación de claves y funcionó de maravilla! : D ahora se llama a la igualdad fn y podría hacer la comparación. ¡¡Gracias!! ¿Puedes agregar esto como respuesta para que pueda votar como la correcta?
Joana Deluca Kleis
Me alegro de poder ayudar :), lo agregaré ahora
Konstantin

Respuestas:

2

En resumen, la razón de este comportamiento se debe a la forma en que funciona React.

React espera una clave única para cada uno de los componentes para poder realizar un seguimiento y saber cuál es cuál. Al shortid.generate()crear un nuevo valor de la clave, se crea la referencia al componente y React piensa que es un componente completamente nuevo, que necesita ser reenviado.

En su caso, en cualquier cambio de accesorios en el padre, React representará a todos los hijos porque las claves serán diferentes para todos los hijos en comparación con el renderizado anterior.

Por favor, haga referencia a esta maravillosa respuesta a este tema

¡Espero que esto ayude!

Konstantin
fuente
0

No conozco el resto de su biblioteca, pero hice algunos cambios y su código y (principalmente) parece funcionar. Entonces, tal vez, puede ayudarlo a reducir la causa.

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

Lhew
fuente
Gracias por tomarse su tiempo y por crear esa caja de arena de código. ¡Lo aprecio! Mi caso es un poco diferente, estás cambiando explícitamente la propiedad cuando haces clic en el botón y eso activa el fn. En mi caso, solo estoy agregando un nuevo elemento a la matriz de los padres, creando un nuevo hijo cada vez y esperando que se active el fn. Me acabo de enterar de que el problema era la clave que estaba generando al azar.
Joana Deluca Kleis