reactjs 登录后从SWR mutate返回数据

2w3kk1z5  于 5个月前  发布在  React
关注(0)|答案(2)|浏览(61)

我有nextJS应用程序与Laravel后端,我试图使用Laravel-NextJS
所有的登录和后台功能工作正常。
这里是一些登录

export const useAuthLaravel = ({ middleware } = {}) => {
    
    const router = useRouter()
    
    const { data: user, error, mutate } = useSWR('/api/user', () =>
        axios
            .get('/api/user')
            .then(res => res.data)
            .catch(error => {
                if (error.response.status != 409) throw error

                router.push('/verify-email')
            }),

    )
    
    const csrf = () => axios.get('/sanctum/csrf-cookie')

    const login_laravel = async ({ setErrors, setStatus, ...props  }) => {

        await csrf()

        setErrors([])
        setStatus(null)

        axios
            .post('/login', props)
            .then(() => mutate())
            .catch(error => {
                if (error.response.status != 422) throw error
                setErrors(Object.values(error.response.data.errors).flat())
            })
    }

    useEffect(() => {
            if (middleware == 'guest' && user) return user
            if (middleware == 'auth' && error && !user) logout_laravel()
        }, [user, error])

        return {
            user,
            csrf,
            login_laravel,
        }
    }

字符串
现在,在我试图放入AuthContext的user的返回值之上,

import { createContext, useEffect, useReducer, useState } from 'react';
import { authApi } from 'src/mocks/auth';

const initialState = {
  isAuthenticated: false,
  isInitialized: false,
  user: null
};

export const AuthProvider = (props) => {

  const { login_laravel, logout_laravel, user } = useAuthLaravel()

  const [state, dispatch] = useReducer(reducer, initialAuthState);

  useEffect(() => {   
        
    const initialize = async () => {

      try {
        if (user) {
          console.log('user exist')
          dispatch({
            type: 'INITIALIZE',
            payload: {
              isAuthenticated: true,
              user
            }
          });
        } else {
          console.log('user not exist')
          dispatch({
            type: 'INITIALIZE',
            payload: {
              isAuthenticated: false,
              user: null
            }
          });
        }
      } catch (err) {
        console.error(err);
        dispatch({
          type: 'INITIALIZE',
          payload: {
            isAuthenticated: false,
            user: null
          }
        });
      }
    };

    initialize();

  }, []);

  const login = async (email, password) => {

    try {
      const user = await login_laravel({ email, password, setErrors, setStatus });

      dispatch({
        type: 'LOGIN',
        isAuthenticated: true,
        payload: {
          user
        }
      });
   
    } catch (err) {
      dispatch({
        type: 'LOGIN',
        payload: {
          isAuthenticated: false,
          user: null
        }
      });
    }
  };

  return (
    <AuthContext.Provider
      value={{
        ...state,
        method: 'LARAVEL',
        login,
      }}
    >
      {children}
    </AuthContext.Provider>
  );
};


现在,当登录函数运行时,它运行SWR验证,但当登录完成时,它不会将静音的user返回到AuthProvider函数,
useAuthLaravel在执行mutate和login函数后会再次运行吗?
谢谢你,
不知道什么顺序出错了,有什么提示吗?

hc8w905p

hc8w905p1#

据我所知,您正在尝试基于useSWR的数据在UseEffect中验证您的用户。这些是“相似的”。我的意见是您需要为您的页面修改return function,而不是尝试在useEffect中使用验证。(页面加载时的useEffect和useSWR触发器,useEffect可以比useSWR加载更快)
我是如何做到这一点:

if (data){
        //trigger a function to validate your data
        return(
            <>
              <div>{something}</div>
            </>
            )
    }

if (error){
        //trigger a function to validate your data
        return (
            <div>
                
            </div>
        )
    }

字符串
我不确定这是你实际上在寻找什么.但我建议你做所有的数据操作上的backend side或在getServerSideProps,而不是在front end端加载巨大的函数.在完美的世界,你需要发送完全获取的数据到您的front end .

y1aodyip

y1aodyip2#

如果你需要“刚刚”登录的用户,你可以尝试这样做。你甚至可以在登录后根据他们的用户角色重定向他们。你可以从/login响应中获取数据,因为laravel返回用户数据
我假设您使用的是基于共享代码的breeze-next
内部src/hooks/auth.js

const login = async ({ setErrors, setStatus, ...props }) => {

    await csrf();

    setErrors([]);
    setStatus(null);

    const userJustLoggedIn = await axios
      .post("/login", props)
      .then(() => mutate())
      .catch((error) => {
        if (error.response.status !== 422) throw error;
        setErrors(error.response.data.errors);
      }).finally(function () {
        setLoading(false)
      })

      switch(userJustLoggedIn?.data?.role) {
        case 'admin':
          break;

        case 'role-1':
          break;

        case 'role-2':
          window.location.replace(`${window.location.origin}/role-2/dashboard`);
          break;
      }
  };

字符串

相关问题