How to compare oldValues and newValues on React Hooks useEffect? How to compare oldValues and newValues on React Hooks useEffect? reactjs reactjs

How to compare oldValues and newValues on React Hooks useEffect?


You can write a custom hook to provide you a previous props using useRef

function usePrevious(value) {  const ref = useRef();  useEffect(() => {    ref.current = value;  });  return ref.current;}

and then use it in 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])}

However its clearer and probably better and clearer to read and understand if you use two useEffect separately for each change id you want to process them separately


Incase anybody is looking for a TypeScript version of usePrevious:

In a .tsx module:

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

Or in a .ts module:

import { useEffect, useRef } from "react";const usePrevious = <T>(value: T): T | undefined => {  const ref = useRef<T>();  useEffect(() => {    ref.current = value;  });  return ref.current;};


Option 1 - run useEffect when value changes

const Component = (props) => {  useEffect(() => {    console.log("val1 has changed");  }, [val1]);  return <div>...</div>;};

Demo

Option 2 - useHasChanged hook

Comparing a current value to a previous value is a common pattern, and justifies a custom hook of it's own that hides implementation details.

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

Demo