Yes, this question seems to be a duplicate of this question:
Should each component have a useDispatch?
But it is not repeated. I offer different methods:
Suppose I have 3 child components, and they all use the Redux Toolkit's dispatch function.
The usual way is this:
const ChildA = () => { const dispatch = useAppDispatch(); const incr = useCallback(() => { dispatch(increment()); }, [dispatch]); return <button onClick={incr}>ChildA</button>; }; const ChildB = () => { const dispatch = useAppDispatch(); const incr = useCallback(() => { dispatch(increment()); }, [dispatch]); return <button onClick={incr}>ChildB</button>; }; const ChildC = () => { const dispatch = useAppDispatch(); const incr = useCallback(() => { dispatch(increment()); }, [dispatch]); return <button onClick={incr}>ChildC</button>; }; export const MyApp = () => { const dispatch = useAppDispatch(); const count = useAppSelector((state) => state.counter.value); const incr = useCallback(() => { dispatch(increment()); }, [dispatch]); return ( <div> <button onClick={incr}>MyApp</button> <ChildA /> <ChildB /> <ChildC /> <div>{count}</div> </div> ); };
But what if I do this? See:
export const glo: { dispatch: ReturnType<typeof useAppDispatch>; } = { // @ts-ignore dispatch: null }; const ChildA = () => { const incr = useCallback(() => { glo.dispatch(increment()); }, []); return <button onClick={incr}>ChildA</button>; }; const ChildB = () => { const incr = useCallback(() => { glo.dispatch(increment()); }, []); return <button onClick={incr}>ChildB</button>; }; const ChildC = () => { const incr = useCallback(() => { glo.dispatch(increment()); }, []); return <button onClick={incr}>ChildC</button>; }; export const MyApp = () => { const dispatch = useAppDispatch(); glo.dispatch = dispatch; if (!glo.dispatch) { throw new Error("dispatch is falsy"); } const count = useAppSelector((state) => state.counter.value); const incr = useCallback(() => { glo.dispatch(increment()); }, []); return ( <div> <button onClick={incr}>MyApp</button> <ChildA /> <ChildB /> <ChildC /> <div>{count}</div> </div> ); };
After my testing, it also works well. Please tell me why I should do it the usual way? Now the new code (the glo based code) is bigger, but that's because we only have 3 subcomponents. When we have 30+ subcomponents, the glo based code will be much smaller and easier to understand.
Here are the differences:
https://i.ibb.co/tKWv2Qc/image.png
This is the CodeSandbox link:
https://codesandbox.io/s/clever-monad-c99q3k?file=/src/features/index.tsx
For example, this dispatch function will change in your test.
Doing this in some environments without testing isn't a "bug" per se, but it's not a big win either.
If you have the line
const dispatch = useAppDispatch();
in your application, then most likely, when the js package is gziped (which is normal nowadays), it will gzip to 3 or 4 anyway byte.If you really want to remove the code here, remove
useCallback
as it is completely unnecessary when passing the callback directly to html.