He estado jugando con React 16.6.0 recientemente y me encanta la idea de React Memo , pero no he podido encontrar nada con respecto a los escenarios más adecuados para implementarlo.
Los documentos de React ( https://reactjs.org/docs/react-api.html#reactmemo ) no parecen sugerir ninguna implicación por simplemente incluirlo en todos sus componentes funcionales.
Debido a que hace una comparación superficial para averiguar si necesita volver a renderizarse, ¿alguna vez habrá una situación que afecte negativamente el rendimiento?
Una situación como esta parece una opción obvia para la implementación:
// NameComponent.js import React from "react"; const NameComponent = ({ name }) => <div>{name}</div>; export default React.memo(NameComponent); // CountComponent.js import React from "react"; const CountComponent = ({ count }) => <div>{count}</div>; export default CountComponent; // App.js import React from "react"; import NameComponent from "./NameComponent"; import CountComponent from "./CountComponent"; class App extends Component { state = { name: "Keith", count: 0 }; handleClick = e => { this.setState({ count: this.state.count + 1 }); }; render() { return ( <div> <NameComponent name={this.state.name} /> <CountComponent count={this.state.count} /> <button onClick={this.handleClick}>Add Count</button> </div> ); } } Debido a que el name nunca cambiará en este contexto, tiene sentido memorizar .
Pero, ¿qué pasa con una situación en la que los accesorios cambian con frecuencia?
¿Qué sucede si agrego otro botón que cambió algo más en el estado y activó una nueva representación? ¿Tendría sentido envolver CountComponent en memo , aunque este componente por diseño está destinado a actualizarse con frecuencia?
Supongo que mi pregunta principal es , mientras todo permanezca puro, ¿hay alguna situación en la que no envuelva un componente funcional con React Memo?
Cuando la aplicación es muy sencilla y no requiere guardar cambios significativos en la memoria.
correcto
Cuando no sabes si realmente vas a tener una mejora en la aplicacion utilizando el hook.
correcto
¿Habrá alguna vez una situación que afecte negativamente el rendimiento?
Sí. Puede terminar con un peor rendimiento, si React.memo envuelve todos los componentes sin pensar.
No es necesario en muchos casos. Para probarlo con un componente crítico para el rendimiento, realice primero algunas medidas, agregue memorización y luego vuelva a medir para ver si la complejidad adicional valió la pena.
React.memo ? Un componente memorizado compara los accesorios antiguos con los nuevos para decidir, si volver a renderizar, cada ciclo de renderizado .
A un componente simple no le importa y solo se renderiza, después de los accesorios/cambio de estado en un padre.
Eche un vistazo a la implementación de shallowEqual , que se invoca en updateMemoComponent .
React memo ? No hay reglas estrictas. Cosas que afectan negativamente a React.memo :
Anuncio 1: en este caso, React.memo no puede evitar que se vuelva a procesar, pero tuvo que hacer cálculos adicionales.
Anuncio 2: el costo de comparación agregado no vale la pena para un componente "simple" en términos de procesamiento, reconciliación, cambio de DOM y costos de efectos secundarios.
Anuncio 3: Cuantos más apoyos, más cálculos. También puede pasar un comparador personalizado más complejo.
React.memo ? Solo verifica accesorios, no cambios de contexto o cambios de estado desde adentro. React.memo también es inútil si el componente memorizado tiene children no primitivos. useMemo puede complementar memo aquí, como:
// inside React.memo component const ctxVal = useContext(MyContext); // context change normally trigger re-render return useMemo(() => <Child />, [customDep]) // prevent re-render of children