Luego de de nuestra prolongada recopilación de datos solucionamos este enigma que pueden tener algunos de nuestros lectores. Te dejamos la solución y deseamos serte de mucha ayuda.
Solución:
En un comentario de arriba gabriele petrioli enlaces a la documentación de React.memo que explica cómo implementar shouldComponentUpdate. Estaba buscando en Google combinaciones de shouldComponentUpdate + useEffect + “react hooks”, y esto surgió como resultado. Entonces, después de resolver mi problema con la documentación vinculada, pensé en traer la información aquí también.
Esta es la forma antigua de implementar shouldComponentUpdate:
class MyComponent extends React.Component
shouldComponentUpdate(nextProps)
return nextProps.value !== this.props.value;
render()
return (
"My Component " + this.props.value
);
La nueva forma de React Hooks:
React.memo(function MyComponent (props)
return "My Component " + props.value ;
)
Sé que probablemente estaba pidiendo más en su pregunta, pero para cualquiera que venga de Google y busque cómo implementar shouldComponentUpdate usando React Hooks, ahí tiene.
La documentación está aquí: how-do-i-implement-shouldcomponentupdate
Agregando a la respuesta de PAT-O-MATION,
React.memo también acepta un segundo parámetro, que es una función que se puede usar para determinar si un componente debe renderizarse o no.
si la funcion regresa true entonces el componente no se volverá a renderizar al cambiar ese accesorio, por el contrario, se actualiza cuando el valor de retorno es false
function SomeComp(prop1, prop2)
return(
..
)
React.memo(SomeComp, (props, nextProps)=>
if(props.prop1 === nextProps.prop1)
// don't re-render/update
return true
)
Nota: el componente solo se volvería a procesar cuando la función de devolución de llamada regrese falsepor lo que en el caso anterior, incluso si el valor de prop2 cambia, no se volverá a procesar
Aquí hay un enlace personalizado que toma una función de actualización y devuelve un valor que cambia solo cuando la función de actualización regresa trueque se puede pasar en el segundo argumento a useEffect
o useCallback
o useMemo
para forzar una nueva renderización:
function useShouldRecalculate(shouldRecalculateFn)
const prevValueRef = useRef(0);
if(shouldRecalculateFn())
// If we need to recalculate, change the value we return
prevValueRef.current += 1;
// else we return the same value as the previous render, which won't trigger a recalculation
return prevValueRef.current;
Por ejemplo, esto actualizará el título del documento solo cuando el recuento sea par:
const shouldUpdateTitle = useShouldRecalculate(
() => count % 2 === 0
);
useEffect(() =>
document.title = `You clicked $count times`;
, [shouldUpdateTitle]); // eslint-disable-line react-hooks/exhaustive-deps
Por qué probablemente no deberías hacer esto
En la mayoría de los casos, no recomendaría hacer esto.
En general, habrá formas más limpias de realizar la misma tarea, utilizando la API de enlaces idiomáticos. (El ejemplo anterior podría haber puesto simplemente un if
bloque alrededor de la línea que actualiza el título del documento).
Quizás más importante, el deps
El argumento no se trata solo de optimización, sino de mantener actualizados los valores de cierre y evitar errores como:
const [count, setCount] = useState(0)
const increment = useCallback(() =>
// Bug: `count` is always 0 here, due to incorrect use of the `deps` argument
setCount(count + 1)
, [])
Este error será capturado por el react-hooks/exhaustive-deps
regla linter, pero tendrá que deshabilitar esa regla en cualquier lugar donde use lógica personalizada para controlar la ejecución.
Es probable que el uso de una lógica de memorización personalizada haga que sus componentes sean más propensos a errores y más difíciles de razonar en general. Así que consideraría esto useShouldRecalculate
engancha algo como último recurso.
Acuérdate de que tienes la capacidad de reseñar .