Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React hooks: dispatch action from useEffect

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.

like image 589
HarshvardhanSharma Avatar asked Feb 28 '19 16:02

HarshvardhanSharma


People also ask

How do you dispatch an action in React hooks?

You would need to pass either bound action creators or a reference to dispatch to your hook. These would come from a connected component, same as you would normally use React-Redux: function MyComponent(props) { useFetching(props. fetchSomething); return <div>Doing some fetching!

How does useEffect () hook gets executed?

useEffect() hook runs the side-effect after initial rendering, and on later renderings only if the name value changes.

What is useSelector and useDispatch?

useSelector and useDispatch are a set of hooks to use as alternatives to the existing connect() higher-order component. The equivalent of map state to props is useSelector. It takes in a function argument that returns the part of the state that you want. The equivalent of map dispatch to props is useDispatch.


1 Answers

Version using react-redux hooks:

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.

like image 174
Alex Hans Avatar answered Sep 17 '22 17:09

Alex Hans