Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why useDispatch re-renders parent components?

I'm using useDispatch hook (from Redux) in onSelect callback in the Tree component (from Ant library):

export const MyComponent = () => {

    const dispatch = useDispatch();

    const onSelect = (selectedNode) => {
            const selectedItem = selectedNode[0];
            dispatch(fetchSelectedItems(selectedItem));
    };

    return 
        <Tree
            onSelect={onSelect}
        >
            <TreeNode .. />
            <TreeNode .. />
            <TreeNode .. />
        </Tree
}


export const fetchSelectedItems = (selected: string) =>
    (dispatch) =>
        axios({
            url: `/api/items?id=${selected}`,
            method: 'GET',
        }).then(response => {
            dispatch(fetchSelectedItemsSuccess(response.data))
        }).catch((error: any) => {throw(error)});

Why does useDispatch re-render parent components? Is there any way to prevent from this? I tried useCallback like it's in Redux documentation but this solution is to prevent child components from re-rendering, not parents.

like image 437
kriz Avatar asked Nov 07 '22 09:11

kriz


1 Answers

It looks like my assumption in the comment was correct.

So I will show you the workaround.
You can extract the part that uses clickValue in the container to another component, say ClickValue.

Doing so will isolate the update to ClickValue component only.

My fork: https://codesandbox.io/s/soanswer60515755-9cc7u

function ClickValue() {
  const clickValue = useSelector(state => state.value);
  console.log(clickValue);
  return clickValue;
}

export default function Container() {
  return (
    <div className="Container">
      <h3>Container</h3>
      <ParentComponent />
      <ClickValue />
    </div>
  );
}

Check out the profile result below.

profile result

like image 63
dance2die Avatar answered Nov 09 '22 23:11

dance2die