My folder structure:
|--App
|--Components
|--PageA.js
|--PageB.js
|--PageC.js
|--common-effects
|--useFetching.js
I am refactoring my code to fetch data from API, using react hooks. I want to dispatch an action from useEffect in useFetching.js that is intercepted by saga middleware. The action should be dispatched only when the components(PageA, PageB, PageC) mount.
I am using redux, react-redux and redux-saga.
PageA.js:
function(props) {
useFetching(actionParams)
//....//
}
Similar code for PageB and PageC components.
I have abstracted the reusable code to fetch data in useFetching
Custom hook.
useFetching.js
const useFetching = actionArgs => {
useEffect( () => {
store.dispatch(action(actionArgs)); // does not work
})
}
I don't know how to access redux dispatch
in useFetching. I tried it with useReducer
effect, but the sagas missed the action.
You can even cut out the connect function completely by using useDispatch
from react-redux:
export default function MyComponent() {
useFetching(fetchSomething);
return <div>Doing some fetching!</div>
}
with your custom hook
import { useDispatch } from 'react-redux';
const useFetching = (someFetchActionCreator) => {
const dispatch = useDispatch();
useEffect(() => {
dispatch(someFetchActionCreator());
}, [])
}
Edit: removed dispatch from custom hook as suggested by @yonga-springfield
Note: React guarantees that dispatch function identity is stable and won’t change on re-renders. This is why it’s safe to omit from the useEffect or useCallback dependency list.