Home > Back-end >  How to use an array as a dependency of a React hook
How to use an array as a dependency of a React hook

Time:11-10

I have a component that has a callback. It depends on an array of plain old objects stored in redux which won't change very often while the component itself will change its state pretty frequently. Some subcomponents should be rerendered on those state changes, but the one that uses the callback, should not.

What's the best approach to making an array a dependency of useCallback()? So far, I've been using

const handleAllItemsSelectedChange = useCallback(
  checked => {
    if (checked) {
      dispatch(setSelected(items));
    } else {
      dispatch(selectSelected([]));
    }
  },
  // eslint-disable-next-line react-hooks/exhaustive-deps
  [JSON.stringify(items)]
);

This doesn't seem ideal, and potentially slower than just rerendering the component every time. I can't imagine this isn't a very common use-case. The React team surely has a best practice for this, right? I can't find it in the documentation.

CodePudding user response:

JSON.stringify or any deep comparison is going to be inefficient and slow. React has no plans to support it

Depending on whether you add or remove items (if not mutating the objects) you can just compare with items.length. Or you could possibly save performance by just creating the function each time, as opposed to trying to save performance putting it in a useCallback.

It's a case by case scenario

CodePudding user response:

In redux reducer every time the array changes you have to create new array. So, your array becomes immutable and you can use it for dependency by reference. Example below just demonstrates the principle.

function reducer(state, action) {
    switch(action.type) {
        case "addItem":
            return {...state, items: [...state.items, action.value]};
        case "changeProp":
            return {...state, prop: action.value}
        default:
            return state;
     }
 }

As you can see every time the array changes you'll get the new instance of the array. That means you can use it by reference and don't need to strignify it anymore:

 const handleAction = useCallback(checked=>{
      ....
 }, [items]);

By the way immutability is the approach recommended by redux documentation

  • Related