React 异步状态问题 - Context 中的状态设置为 true,但在组件中仍然为 false(使用 Context 和 API 调用进行 React 身份验证)

问题描述 投票:0回答:1

我在 React 上遇到异步状态问题

我使用上下文来确定管理员是否经过身份验证并有权访问状态为 isAuth 的页面

interface UserContext {
    setToken: (token:string) => void;
    getToken: () => string|null;
    logout: () => void;
    setIsAuth: (value:boolean) => void;
    isAuth: boolean;
}

const initialState: UserContext = {
    setToken: () => {}, 
    getToken: () => null,
    logout: () => {},
    setIsAuth: () => {},
    isAuth: false,
}

const UserContext = createContext<UserContext>(initialState)

export function UserContextProvider ({children}:{children:React.ReactNode}){
    const [isAuth, setIsAuth] = useState(false);

    console.log("isAuth in UserContextProvider",isAuth);

    const setToken = (token:string) => {
        window.localStorage.setItem('token', token);
    }

    const getToken = () => {
        return window.localStorage.getItem('token');
    }

    const logout = () => {
        //redirect("/login")
        window.localStorage.removeItem('token');
    }


    return <UserContext.Provider value={{setToken, getToken, logout, setIsAuth, isAuth }}>
        {children}
    </UserContext.Provider>
}

export const useUserContext = () => {
    return useContext(UserContext)
}

main.ts

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <UserContextProvider>
      <App />
    </UserContextProvider>
  </React.StrictMode>,
)

在应用程序中,我进行 API 调用来检查管理员是否经过身份验证,并将 isAuth 设置为 response.code === 200 (如果经过身份验证,则响应为 200)。在本例中,管理员已通过身份验证,因此响应为 200 并且 isAuth 设置为 true

function App() {
  const {setIsAuth,getToken} = useUserContext();

  useEffect(() => {
    const token = getToken();

    fetch(import.meta.env.VITE_API_URL+"/isAuth", {
      headers: {Authorization: `Bearer ${token}`}
    })
    .then((res) => res.json())
    .then((response) => {
        console.log("response App",response);
        setIsAuth(response.code === 200);
    })
    
  }, [location.pathname])

在ProjectTable组件(显示项目的管理页面)中,我需要检查他是否通过身份验证,如果没有,则重定向到/login

我做了一个isAuth的日志

export function ProjectTable({projects}:{projects:Project[]}){
    const { t } = useTranslation();
    const {isAuth} = useUserContext();
    const navigateTo = useNavigate();

    useEffect(() => {
        
        console.log("isAuth in useEffect ProjectTable",isAuth);

        // if (!isAuth){
        //     navigateTo("/login");
        // }

    }, [])

这是我在管理页面 ProjectTable 上时的控制台输出,它显示了项目

logs

UserContextProvider 中的 isAuth 为 false,ProjectTable 中的 isAuth 为 false。

然后我进行 API 调用并将 isAuth 设置为 true。

UserContextProvider 中的 isAuth 设置为 true,但 ProjectTable 中未设置。我没有看到表明 isAuth 为 true 的日志;在 UserContextProvider 中的 isAuth 变为 true 之前,我只看到旧日志将其显示为 false。

所以,如果我取消注释 if (!isAuth),我会被重定向到 /login,即使我不应该这样做,因为我已经通过了身份验证

reactjs react-hooks fetch react-context react-state
1个回答
0
投票

您应该在函数组件中打印

isAuth

export function ProjectTable({projects}:{projects:Project[]}){
  const {isAuth} = useUserContext();

  console.log("isAuth in useEffect ProjectTable",isAuth)
}

或者,将其添加到

useEffect
钩子

的依赖列表中
export function ProjectTable({projects}:{projects:Project[]}){
  const {isAuth} = useUserContext();
  useEffect(() => {
    console.log("isAuth in useEffect ProjectTable",isAuth)
  }, [isAuth])

}
© www.soinside.com 2019 - 2024. All rights reserved.