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

253
Views
Passing array to useEffect dependency list

There's some data coming from long polling every 5 seconds and I would like my component to dispatch an action every time one item of an array (or the array length itself) changes. How do I prevent useEffect from getting into infinity loop when passing an array as dependency to useEffect but still manage to dispatch some action if any value changes?

useEffect(() => {
  console.log(outcomes)
}, [outcomes])

where outcomes is an array of IDs, like [123, 234, 3212]. The items in array might be replaced or deleted, so the total length of the array might - but don't have to - stay the same, so passing outcomes.length as dependency is not the case.

outcomes comes from reselect's custom selector:

const getOutcomes = createSelector(
  someData,
  data => data.map(({ outcomeId }) => outcomeId)
)
over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

You can pass JSON.stringify(outcomes) as the dependency list:

Read more here

useEffect(() => {
  console.log(outcomes)
}, [JSON.stringify(outcomes)])
over 4 years ago · Santiago Trujillo Report

0

Another ES6 option would be to use template literals to make it a string. Similar to JSON.stringify(), except the result won't be wrapped in []

useEffect(() => {
  console.log(outcomes)
}, [`${outcomes}`])

Another option, if the array size doesn't change, would be to spread it in:

useEffect(() => {
  console.log(outcomes)
}, [ ...outcomes ])
over 4 years ago · Santiago Trujillo Report

0

Using JSON.stringify() or any deep comparison methods may be inefficient, if you know ahead the shape of the object, you can write your own effect hook that triggers the callback based on the result of your custom equality function.

useEffect works by checking if each value in the dependency array is the same instance with the one in the previous render and executes the callback if one of them is not. So we just need to keep the instance of the data we're interested in using useRef and only assign a new one if the custom equality check return false to trigger the effect.

function arrayEqual(a1: any[], a2: any[]) {
  if (a1.length !== a2.length) return false;
  for (let i = 0; i < a1.length; i++) {
    if (a1[i] !== a2[i]) {
      return false;
    }
  }
  return true;
}

type MaybeCleanUpFn = void | (() => void);

function useNumberArrayEffect(cb: () => MaybeCleanUpFn, deps: number[]) {
  const ref = useRef<number[]>(deps);

  if (!arrayEqual(deps, ref.current)) {
    ref.current = deps;
  }

  useEffect(cb, [ref.current]);
}

Usage

function Child({ arr }: { arr: number[] }) {
  useNumberArrayEffect(() => {
    console.log("run effect", JSON.stringify(arr));
  }, arr);

  return <pre>{JSON.stringify(arr)}</pre>;
}

Taking one step further, we can also reuse the hook by creating an effect hook that accepts a custom equality function.

type MaybeCleanUpFn = void | (() => void);
type EqualityFn = (a: DependencyList, b: DependencyList) => boolean;

function useCustomEffect(
  cb: () => MaybeCleanUpFn,
  deps: DependencyList,
  equal?: EqualityFn
) {
  const ref = useRef<DependencyList>(deps);

  if (!equal || !equal(deps, ref.current)) {
    ref.current = deps;
  }

  useEffect(cb, [ref.current]);
}

Usage

useCustomEffect(
  () => {
    console.log("run custom effect", JSON.stringify(arr));
  },
  [arr],
  (a, b) => arrayEqual(a[0], b[0])
);

Live Demo

Edit 59467758/passing-array-to-useeffect-dependency-list

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!