Home > Blockchain >  How to use hooks within function in React Js
How to use hooks within function in React Js

Time:02-02

I have a file where I keep all my functions that make api calls, then I import these functions inside components to use where needed. The issue I'm facing is that when api call is made and it returns 'unauthorized user'(because token has expired) I need to redirect users to the login page.

// apiCalls.js file

 export async function getData(){
 let response = await fetch(url)
 let res = response.json()
 // here I need to add redirect to /login if res.status.code is 401 for example

}

I tried to create a custom hook (with useNavigate) to use inside the function, but app throws error saying that hooks can't be used inside function. I can check status of the request inside the component(after I import function from apiCalls.js) but it doesn't seem like a correct way of approaching this as I'll have to add check inside every component that may use this function. Any advise is greatly appreciated

EDITED: to add context, I need to redirect user from a function( not functional component), function is exported from apiCalls.js file.

CodePudding user response:

There's a great way to use hooks inside of a function - make the function a hook! The caveat is that this function will also need to follow the rules of hooks; a big one being the one you've just discovered: you should only be calling it inside a component or other hooks. If you're getting an error because of eslint, you generally also have to (and should) prefix this function with use (like useGetData).

export function useGetData(){
  const navigation = useNavigation();

  const getData = async (url) => {
    let response = await fetch(url)
    let res = response.json()
    if (/* isInvalidStatus */) {
       // navigate to '/login'
    }
    // return your data
  }

  return { getData }
}

export function MyComponent() {
  const { getData } = useGetData();

  // call getData() from useEffect or a click handler

  // return jsx;
}

Brief explanation in case it helps:.
First we'll rename the function to follow convention, but we'll also have to remove the async keyword (which we address later). We'll add the useNavigation hook.

export function useGetData() {
  // or whatever navigator your router provides
  const navigation = useNavigation();
}

The hook itself can't be async, but we can expose a function in the hook's return object:

const getData = async (url) => {
  // would probably use const instead of let
  const response = await fetch(url);
  if (response.status === 401 || response.status === 403) {
    navigate('/login');
    return;
  }
  return response.json();
}

return { getData }

And now in the component you can grab getData from useGetData and use it however you want; the auth guard logic will be handled for us in the hook, no matter which component we use it in.

CodePudding user response:

Hooks are JavaScript functions, but you need to follow two rules when using them.

  1. Don’t call Hooks inside loops, conditions, or nested functions.
  2. Don’t call Hooks from regular JavaScript functions.

So if you want to use hook inside a function, change that function into hook

  • Related