Creé un componente React que tiene dos hijos: uno muestra un gráfico (vis.js) y cuando el usuario se desplaza sobre un nodo en el gráfico, el componente principal se da cuenta de esto mediante un cambio de estado. El único hijo que usa este estado es un div (hermano del gráfico).
Sin embargo, cuando cambia el estado, todos los elementos secundarios (incluido el gráfico) se vuelven a representar. No quiero representar el gráfico cada vez que paso el mouse sobre un nodo, solo su hermano.
Este es mi código:
import React, { useState } from "react"; ... const Graph = (props) => { ... const [nodeName, setNodeName] = useState(""); function handleHoverEvent(node) { if (nodeName !== node) { setNodeName(node); } } function makeNodes() { ... } function makeEdges() { ... } return ( <div> <Vis nodes={makeNodes()} edges={makeEdges()} OnHover={handleHoverEvent} /> <NameDisplay name={nodeName} /> </div> ); } ... export default Graph; makeNodes() y makeEdges() no dependen del estado de ninguna manera.
¿Cómo puedo evitar que el gráfico se vuelva a renderizar cada vez? Todo lo que necesito hacer es "pasar" datos de un niño a otro, mientras solo actualizo uno de ellos.
Todo lo que se necesitó fue convertir todos los componentes a clases ES6. Esto se describe aquí: https://reactjs.org/docs/state-and-lifecycle.html#converting-a-function-to-a-class
Ni siquiera tuve que especificar un método shouldComponentUpdate() .
Puede usar React.memo() , React.useCallback para evitar volver a renderizar cosas en el componente de reacción. Evitar que el componente React se vuelva a renderizar con React.memo
Ejemplo :
Botón
import React from "react"; interface IProps { handleClick: () => void; children: any; } function Button({ handleClick, children }: IProps) { console.log("Rendering button - ", children); return <button onClick={handleClick}>{children}</button>; } export default React.memo(Button);Contar
import React from "react"; import Button from './Button' interface IProps { text: any; count: any; handleClick: () => void; children: any; } function Count({ text, count, handleClick, children }: IProps) { console.log(`Rendering ${text}`); return ( <div> <div> {text} - {count} </div> <Button handleClick={handleClick}>{children}</Button> </div> ); } export default React.memo(Count);Componente principal
import React, { useState, useCallback } from "react"; import Count from "./Count"; export const ParentComponent = () => { const [age, setAge] = useState(25); const [salary, setSalary] = useState(50000); // const incrementAge = () => { // setAge(age + 1) // } // const incrementSalary = () => { // setSalary(salary + 1000) // } const incrementAge = useCallback(() => { setAge(age + 1); }, [age]); const incrementSalary = useCallback(() => { setSalary(salary + 1000); }, [salary]); return ( <> <Count text="Age" count={age} handleClick={incrementAge}> Increment Age </Count> <Count text="Salary" count={salary} handleClick={incrementSalary}> Increment Salary </Count> </> ); };