Source:  Twitter logo

My folder structure:


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.


function(props) {

Similar code for PageB and PageC components.

I have abstracted the reusable code to fetch data in useFetching Custom hook.


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.

Version using react-redux hooks:

You can even cut out the connect function completely by using useDispatch from react-redux:

export default function MyComponent() {

  return <div>Doing some fetching!</div>

with your custom hook

import { useDispatch } from 'react-redux';

const useFetching = (someFetchActionCreator) => {
  const dispatch = useDispatch();
  useEffect(() => {
  }, [])

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.

43 users liked answer #0dislike answer #043
Alex Hans profile pic
Alex Hans

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) {

    return <div>Doing some fetching!</div>

const mapDispatch = {

export default connect(null, mapDispatch)(MyComponent);

The hook should then call the bound action creator in the effect, which will dispatch the action accordingly.

Also, note that your current hook will re-run the effect every time the component is re-rendered, rather than just the first time. You'd need to modify the hook like this:

const useFetching = someFetchActionCreator => {
  useEffect( () => {
  }, [])
16 users liked answer #1dislike answer #116
markerikson profile pic

This is just to bring some optimization to @Alex Hans' answer.

As per the documentation here. A custom Hook is a JavaScript function whose name starts with ”use” and that may call other Hooks.

With this in mind, we need not send a reference to the dispatch function to the useFetching hook as a parameter but rather, simply not send it and rather simply use it from within the useFetching hook with the appropriate imports.

Here's an excerpt of what I mean.

import { useDispatch } from 'react-redux';

const useFetching = (someFetchActionCreator) => {
    const dispatch = useDispatch()

    useEffect(() => {
  }, [])

I can't ascertain this example will fit without errors in your codebase in your case but just trying to explain the idea/concept behind this post.

Hope this helps any future comer.

9 users liked answer #2dislike answer #29
yonga springfield profile pic
yonga springfield

Alex Hans right decision with dispatch, but to eliminate request loops to api you can specify the dependence on dispatch ( I used Redux Toolkit )

  import React, { useEffect } from 'react'
  import { useDispatch } from 'react-redux'
  import axios from 'axios'
  import { getItemsStart, getItemsSuccess, getItemsFailure } from '../features/itemsSlice'

  const fetchItems = () => async dispatch => {
    try {
      const { data } = await axios.get('url/api')
    } catch (error) {

  const PageA = () => {
    const dispatch = useDispatch()
    const { items } = useSelector(state => state.dataSlice)
    useEffect(() => {
    }, [dispatch])

    return (
         { => <li>{}</li>}
  export default PageA

it is important to passed dependency parameter of dispatch in the useEffect(() => {...}, [dispatch])

8 users liked answer #3dislike answer #38
FreeClimb profile pic
useEffect(() => {
 }, []);

 async function fetchData() {
   try {
     await Auth.currentSession();
   } catch (e) {
     if (e !== "No current user") {
   dispatch(authentication({ type: "SET_AUTHING", payload: false }));
2 users liked answer #4dislike answer #42
Asgar Ali Khachay profile pic
Asgar Ali Khachay

Copyright © 2022 QueryThreads

All content on Query Threads is licensed under the Creative Commons Attribution-ShareAlike 3.0 license (CC BY-SA 3.0).