Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

118
Views
react useEffect comparing objects

I am using react useEffect hooks and checking if an object has changed and only then run the hook again.

My code looks like this.

const useExample = (apiOptions) => {
    const [data, updateData] = useState([]);
    useEffect(() => {
       const [data, updateData] = useState<any>([]);
        doSomethingCool(apiOptions).then(res => {               
           updateData(response.data);
       })
    }, [apiOptions]);

    return {
        data
    };
};

Unfortunately it keeps running as the objects are not being recognised as being the same.

I believe the following is an example of why.

const objA = {
   method: 'GET'
}

const objB = {
   method: 'GET'
}

console.log(objA === objB)

Perhaps running JSON.stringify(apiOptions) works?

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

Use apiOptions as state value

I'm not sure how you are consuming the custom hook but making apiOptions a state value by using useState should work just fine. This way you can serve it to your custom hook as a state value like so:

const [apiOptions, setApiOptions] = useState({ a: 1 })
const { data } = useExample(apiOptions)

This way it's going to change only when you use setApiOptions.

Example #1

import { useState, useEffect } from 'react';

const useExample = (apiOptions) => {
  const [data, updateData] = useState([]);
  
  useEffect(() => {
    console.log('effect triggered')
  }, [apiOptions]);

  return {
    data
  };
}
export default function App() {
  const [apiOptions, setApiOptions] = useState({ a: 1 })
  const { data } = useExample(apiOptions);
  const [somethingElse, setSomethingElse] = useState('default state')

  return <div>
    <button onClick={() => { setApiOptions({ a: 1 }) }}>change apiOptions</button>
    <button onClick={() => { setSomethingElse('state') }}>
      change something else to force rerender
    </button>
  </div>;
}

Alternatively

You could write a deep comparable useEffect as described here:

function deepCompareEquals(a, b){
  // TODO: implement deep comparison here
  // something like lodash
  // return _.isEqual(a, b);
}

function useDeepCompareMemoize(value) {
  const ref = useRef() 
  // it can be done by using useMemo as well
  // but useRef is rather cleaner and easier

  if (!deepCompareEquals(value, ref.current)) {
    ref.current = value
  }

  return ref.current
}

function useDeepCompareEffect(callback, dependencies) {
  useEffect(
    callback,
    dependencies.map(useDeepCompareMemoize)
  )
}

You can use it like you'd use useEffect.

over 4 years ago · Santiago Trujillo Report

0

I just found a solution which works for me.

You have to use usePrevious() and _.isEqual() from Lodash. Inside the useEffect(), you put a condition if the previous apiOptions equals to the current apiOptions. If true, do nothing. If false updateData().

Example :

const useExample = (apiOptions) => {

     const myPreviousState = usePrevious(apiOptions);
     const [data, updateData] = useState([]);
     useEffect(() => {
        if (myPreviousState && !_.isEqual(myPreviousState, apiOptions)) {
          updateData(apiOptions);
        }
     }, [apiOptions])
}

usePrevious(value) is a custom hook which create a ref with useRef().

You can found it from the Official React Hook documentation.

const usePrevious = value => {
  const ref = useRef();
  useEffect(() => {
    ref.current = value;
  });
  return ref.current;
};
over 4 years ago · Santiago Trujillo Report

0

If the input is shallow enough that you think deep equality would still be fast, consider using JSON.stringify:

const useExample = (apiOptions) => {
    const [data, updateData] = useState([]);
    const apiOptionsJsonString = JSON.stringify(apiOptions);

    useEffect(() => {
       const apiOptionsObject = JSON.parse(apiOptionsJsonString);
       doSomethingCool(apiOptionsObject).then(response => {               
           updateData(response.data);
       })
    }, [apiOptionsJsonString]);

    return {
        data
    };
};

Note it won’t compare functions.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!