0

I am having trouble in using the customHooks with my redux saga here. I am new with the redux saga so couldn't able to get my head around calling the custom hooks function here.

I have created a custom hook for calling my api functions in which there is a function userLogin . Now I want this same function in to be called in the saga file, every time a particular dispatch action occurs.

What is the correct way to approach this. Should I not define my api's function inside a custom hooks ?

useApi.js

//useApi custom hook
export const useApi = () => {

    const api = useAxios();

    const userLogin = async (body, config = {}) => {
        const res = await api.post(LOGIN, body, config);
        return res.data;
    };

    return {
        userLogin,
    };
}

userSaga.js

import { takeEvery } from 'redux-saga/effects';


export function* userLoginFunction() {
    //how can I call my custom hook function here ?
    //because according to hooks rules, I cann't use the hook here.
    
    try {
       
    } catch (e) {
        
    }
}
export default function* rootSaga() {
    yield takeEvery('USER_LOGIN', fetchNumberSaga);
}
1
  • 1
    "Should I not define my api's function inside a custom hooks?" - No, probably not. This is so you don't lock your service code into only being callable from React functions and custom hooks. React hooks can only be called from React functions and custom React hooks. You'll need to abstract the axios code/logic to be a regular function instead of a "special" React hook function if you want it to be callable from your saga/asynchronous action.
    – Drew Reese
    Commented Jun 29, 2023 at 6:59

1 Answer 1

1

You can't. React hooks can be used only inside React functional components.

But no worries 🙌.

Instead, you can create plain API functions and use them.

Example:

api.js

export const api = axios.create({ baseURL: 'https://your-api.com/api/v1' })

user-api.js

import { api } from './api'

export const signIn = async ({ credentials }) => {
  const { data: user } = await api.request({
    method: 'POST',
    url: '/sign-in',
    // ... other params
  })

  return user
}

userSaga.js

import { takeEvery, call } from 'redux-saga/effects';
import { signIn } from './user-api';

export function* userSignInWorker(action) {
  try {
    const user = yield call(signIn, { credentials: action.payload })
    // ... your code
  } catch (e) {
    // ... error handling
  }
}

export default function* rootSaga() {
  yield takeEvery('USER_LOGIN', userSignInWorker)
}
3
  • I was kinda using the api function like this. But because I wanted to make a global axios interceptor so that I can kick out the user when it's request gives "INVALID_TOKEN" and use a dispatch function to update the user state (loggedOut: true) and because dispatch comes with useDispatch() hook so I had to make my axios inside a custom Hook. How can I solve this issue ? Commented Jun 29, 2023 at 7:25
  • To solve this issue you can use axios interceptors: api.interceptors.response.use(onFulfilled, onRejected) or api.interceptors.request.use(onFulfilled, onRejected). It's easy to check a token inside. Actually there you can even dispatch any actions. Commented Jun 29, 2023 at 8:12
  • Ohh right, I can just use store.dispatch(function) without useDispatch() hook. Thanks Commented Jun 29, 2023 at 15:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.