1

StackOverflow,

I'm having a question about React Hooks, more particularly, useEffect hook. I'm aware that one use case of useEffect hook is to capture changes of certain state variables.

Let's suppose we have the following code:

const MyComponent = () => {
  const [sv, setSv] = useState([
    {
      a: 1,
      b: { c: 'val11', d: 'val12', e: 'val13' }
    },
    {
      a: 8,
      b: { c: 'val21', d: 'val22', e: 'val23' }
    },
    {
      a: 19,
      b: { c: 'val31', d: 'val32', e: 'val33' }
    }
  ]);

  const someCallback = useCallback(() => {
    console.log('change triggered!')
  });

  useEffect(someCallback, [sv]);
}

Let's also assume sv is an array of objects, each of which has the same set of keys, but different values associated with these keys.

It works just fine if I want to execute someCallback on any changes made to sv, including objects nested in each object contained by the array sv.

Now let's assume that there is a need to execute someCallback only when certain properties of each object in the array sv will change. For example, I'll want to only monitor changes to b.c and b.d. The way I thought would work is:

useEffect(someCallback, [sv.map(item => item.b.c), sv.map(item => item.b.d)]);

However, it didn't trigger at all. This probably because Array.map creates a new array with no reference to the previous one, however, I can't think of any other way to map the necessary values.

Any help is greatly appreciated.

Thanks!

2
  • If you spread the mapped arrays that should actually work. useEffect(someCallback, [...sv.map(item => item.b.c), ...sv.map(item => item.b.d)]); Commented Jun 8, 2021 at 12:34
  • Maybe you can keep the previous state, check if the parts of the objects you wanted to change are changed in the new state. do that inside the useEffect (compare between new and previous state). that's a messy way but it should work. Commented Jun 8, 2021 at 12:37

1 Answer 1

2

I think using SPREAD operator should work

useEffect(someCallback, [...sv.map(item => item.b.c), ...sv.map(item => item.b.d)]);
Sign up to request clarification or add additional context in comments.

1 Comment

Getting an error: The final argument passed to useEffect changed size between renders. The order and size of this array must remain constant. Previous: [] Incoming: [[object Object]]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.