【问题标题】:REACT - how can wait until api call finish to load a path?反应 - 如何等到 api 调用完成加载路径?
【发布时间】:2020-08-13 18:51:20
【问题描述】:

如果用户有权访问应用程序,我使用 axios post 向后端请求。问题是 axios 返回 undefined 然后 true 或 false 。如果返回 true 或 false(在这种情况下为 undefined = false),有一个私有 Route 来管理要做什么,是 axios 的问题还是有其他方法?比如等到返回真假

IsLogin.jsx

import React from 'react'
const axios = require('axios');
export const AuthContext = React.createContext({})

export default function Islogin({ children }) {
   const isAuthenticated =()=>{
       try{
            axios.post('/api/auth').then(response => {
               var res = response.data.result;
               console.log(res)
               return res
           })
       } catch (error) {
           console.error(error);
           return false
       }

   }
  
   var auth = isAuthenticated()
   console.log(auth);
   return (
       <AuthContext.Provider value={{auth}}>
           {children}
       </AuthContext.Provider>
   )
}

privateRoute.js

import React, { useContext } from 'react';
import { Route, Redirect } from 'react-router-dom';
import  {AuthContext}  from '../utils/IsLogin';

const PrivateRoute = ({component: Component, ...rest}) => {

   const {isAuthenticated}  = useContext(AuthContext)
   
   return (

       // Show the component only when the user is logged in
       // Otherwise, redirect the user to /unauth page
       <Route {...rest} render={props => (
           isAuthenticated ?
               <Component {...props} />
           : <Redirect to="/unauth" />
       )} />
   );
};
export default PrivateRoute; 

app.js

class App extends Component {
  render() {
  return (
    <>
    <BrowserRouter>
    <Islogin>
      <Header/>
    <Banner/>
     <Switch>
      <PrivateRoute exact path="/index" component={Landing} />
     <PrivateRoute path="/upload" component={Upload} exact />
     <PublicRoute restricted={false} path="/unauth" component={Unauthorized} exact  />
    </Switch>
    </Islogin>
    </BrowserRouter>
  
    </>
  );
}
}

【问题讨论】:

    标签: javascript reactjs axios react-router-dom


    【解决方案1】:

    您不想在发布请求中返回任何内容。你应该更新你的上下文存储

    const isAuthenticated = () => {
        try {
            axios.post('/api/auth').then(response => {
                var res = response.data.result;
                console.log(res)
                // update your context here instead of returning
                return res
            })
        } catch (error) {
            console.error(error);
            return false
        }
    }
    

    在您的私有路由中,使用 componentDidUpdate 样式 useEffect 挂钩来检查身份验证状态的变化并根据需要更新内部标志

    const PrivateRoute = ({ component: Component, ...rest }) => {
        const { isAuthenticated } = useContext(AuthContext)
        const [validCredentials, setValidCredentials] = React.useState(false)
    
        React.useEffect(() => {
            if (typeof isAuthenticated === 'boolean') {
                setValidCredentials(isAuthenticated)
            }
        }, [isAuthenticated])
    
    
        return (
    
            // Show the component only when the user is logged in
            // Otherwise, redirect the user to /unauth page
            <Route {...rest} render={props => (
                validCredentials ?
                    <Component {...props} />
                    : <Redirect to="/unauth" />
            )} />
        );
    };
    

    【讨论】:

    • 感谢您的帮助,您说的更新上下文是什么意思?您需要删除此代码吗? return ( &lt;AuthContext.Provider value={{res}}&gt; {children} &lt;/AuthContext.Provider&gt; )
    • 我从未说过您应该删除该代码。你需要它来保存isAuthenticated。您需要 dispatch 更新以根据您的 api 响应将 isAuthenticated 更改为 true/false
    • @Andrew 我有一个类似的问题,我正在使用 Redux 进行全局身份验证状态。我有完全相同的PrivateRoute。我的问题是:当用户登录并单击刷新时,会呈现 Login 组件,因为身份验证状态为 false。我还在对我的后端进行 api 调用,当该调用返回时,如果用户被授权,则呈现 Dashboard 受保护的路由。所以有一个短暂的时间段,Login 被渲染,0.5 秒后,Dashbaord 被渲染。如何避免在从我的 API 获取结果之前显示 Login
    • @HarshitTrehan 我个人不会有一个完整的登录页面,而是有一个在 UI 上具有登录功能的主页。如果这不可能,那么将进程隐藏在加载程序后面是最简单的方法。
    • @Andrew by Loader 你的意思是一个单独的通用组件,它也可以在其他页面上重用吗?或者它是某种我不知道的内置 React 功能?
    【解决方案2】:

    我很好奇你为什么不使用“异步等待”,哈哈。

    您正在向端点“/api/auth”发出发布请求,但您没有给它任何要发布的数据,例如:

    try{
           axios.post('/api/auth',{username,password}).then(response => {
               var res = response.data.result;
               console.log(res)
               return res
           })
           } catch (error) {
               console.error(error);
               return false
           }
    

    【讨论】:

    • 由后端管理的身份验证端点/api/auth只返回true或false
    猜你喜欢
    • 2019-02-02
    • 1970-01-01
    • 2022-12-07
    • 2019-11-02
    • 2011-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多