Home > Blockchain >  React update state from the axios response
React update state from the axios response

Time:03-26

I have been trying to build this authentication verify component and I've been stuck.

What I'm trying to do is to make an axios get request to my backend server to verify if the user is logged in. The backend part works just fine. Keep in mind that the cookies are sent when they exist. What happens is that I send the user's cookies & headers with the request, to the backend, and then the server validates it, and then sends back a success response. I'm trying to change the react useState's state based on the axios response.

Here's my current code:

import { useEffect, useState } from 'react';
import { Navigate, Outlet } from 'react-router-dom';
import apiurl from '../axios'; // custom axios interceptor

const AuthVerifyFunction = () => {
    const [isAuth, setIsAuth] = useState();

    const config = {
        headers: {
            "Content-Type": "application/json",
            "X-Requested-With": "XMLHttpRequest"
        }
    }

    const verifyAuth = () => {
        apiurl.get('/api/auth/verify', config)
            .then(res => {
                setIsAuth(res.data.success)
                console.log(res)
                console.log("isAuth:", isAuth);
            })
            .catch(err => {
                console.log(err)
            });
    }

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

    return (
        <h1>{isAuth ? <Outlet /> : <Navigate to="/login" />}</h1>
    )

}

export default AuthVerifyFunction;

This is the success response i get back:

{data: {…}, status: 200, statusText: 'OK', headers: {…}, config: {…}, …}
  config: {transitional: {…}, transformRequest: Array(1), transformResponse: Array(1), timeout: 0, adapter: ƒ, …}
  data: {success: true, authHeader: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZC…Tg4fQ.lX8piOnRb9-MQCS8mibMSmFfjBcCeTaC7sw-DgdwBl8'}
  headers: {content-length: '230', content-type: 'application/json; charset=utf-8'}
  request: XMLHttpRequest {onreadystatechange: null, readyState: 4, timeout: 0, withCredentials: true, upload: XMLHttpRequestUpload, …}
  status: 200
  statusText: "OK"
  [[Prototype]]: Object

The part I've been stuck on is that I don't know how to not redirect the user before the async response, or in easy words, I just want to show the outlet if the response.data.success is true, if it isn't, then redirect them to /login.

If there's any other better way to do this, please let me know. Thank you in advance.

CodePudding user response:

You could use a isLoading state: set it to false when you receive a response from the API:

import { useEffect, useState } from 'react';
import { Navigate, Outlet } from 'react-router-dom';
import apiurl from '../axios'; // custom axios interceptor

const AuthVerifyFunction = () => {
  const [isLoading, setIsLoading] = useState(true);
  const [isAuth, setIsAuth] = useState();

  const config = {
    headers: {
      'Content-Type': 'application/json',
      'X-Requested-With': 'XMLHttpRequest',
    },
  };

  const verifyAuth = () => {
    apiurl
      .get('/api/auth/verify', config)
      .then((res) => {
        setIsAuth(res.data.success);
        setIsLoading(false);
        console.log(res);
        console.log('isAuth:', isAuth);
      })
      .catch((err) => {
        console.log(err);
      });
  };

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

  return (
    <h1>
      {isLoading ? (
        'Authenticating...'
      ) : isAuth ? (
        <Outlet />
      ) : (
        <Navigate to='/login' />
      )}
    </h1>
  );
};

export default AuthVerifyFunction;

CodePudding user response:

Maybe you should declare your initial state,so it won't be null

 const [isAuth, setIsAuth] = useState(false);
  • Related