Digamos que tengo 3 entradas: tasa, cantidad de envío y cantidad de recepción. Puse esas 3 entradas en los parámetros de diferenciación de useEffect. Las reglas son:
receiveAmount = sendAmount * ratesendAmount = receiveAmount / ratereceiveAmount = sendAmount * rate cuando sendAmount > 0 o calculo sendAmount = receiveAmount / rate cuando receiveAmount > 0Aquí está el codesandbox https://codesandbox.io/s/pkl6vn7x6j para demostrar el problema.
¿Hay alguna manera de comparar los oldValues y los valores newValues como en componentDidUpdate en lugar de crear 3 controladores para este caso?
Gracias
Aquí está mi solución final con usePrevious https://codesandbox.io/s/30n01w2r06
En este caso, no puedo usar varios useEffect porque cada cambio conduce a la misma llamada de red. Es por eso que también uso changeCount para rastrear el cambio. Este changeCount también es útil para realizar un seguimiento de los cambios solo desde el lugar local, por lo que puedo evitar llamadas de red innecesarias debido a los cambios del servidor.
Puede escribir un enlace personalizado para proporcionarle accesorios anteriores usando useRef
function usePrevious(value) { const ref = useRef(); useEffect(() => { ref.current = value; }); return ref.current; } y luego usarlo en useEffect
const Component = (props) => { const {receiveAmount, sendAmount } = props const prevAmount = usePrevious({receiveAmount, sendAmount}); useEffect(() => { if(prevAmount.receiveAmount !== receiveAmount) { // process here } if(prevAmount.sendAmount !== sendAmount) { // process here } }, [receiveAmount, sendAmount]) } Sin embargo, es más claro y probablemente mejor y más claro de leer y comprender si usa dos useEffect por separado para cada identificación de cambio que desea procesar por separado
En caso de que alguien esté buscando una versión de TypeScript de uso anterior:
En un módulo .tsx :
import { useEffect, useRef } from "react"; const usePrevious = <T extends unknown>(value: T): T | undefined => { const ref = useRef<T>(); useEffect(() => { ref.current = value; }); return ref.current; }; O en un módulo .ts :
import { useEffect, useRef } from "react"; const usePrevious = <T>(value: T): T | undefined => { const ref = useRef<T>(); useEffect(() => { ref.current = value; }); return ref.current; }; const Component = (props) => { useEffect(() => { console.log("val1 has changed"); }, [val1]); return <div>...</div>; };Comparar un valor actual con un valor anterior es un patrón común y justifica un enlace personalizado propio que oculta los detalles de implementación.
const Component = (props) => { const hasVal1Changed = useHasChanged(val1) useEffect(() => { if (hasVal1Changed ) { console.log("val1 has changed"); } }); return <div>...</div>; }; const useHasChanged= (val: any) => { const prevVal = usePrevious(val) return prevVal !== val } const usePrevious = (value) => { const ref = useRef(); useEffect(() => { ref.current = value; }); return ref.current; }