【问题标题】:React component not rendering after checking for Authentication检查身份验证后反应组件未呈现
【发布时间】:2021-01-08 17:57:07
【问题描述】:

所以基本上我正在尝试为我的应用程序创建一个受保护的路由,并且我还有另一个函数可以检查服务器 API 是否正确地验证了客户端。 不幸的是,由于 React Hooks 的工作方式,状态不会直接更新,如果我在用户未通过身份验证时尝试重定向,它只会将我发送到那里。 因此,当您重新加载页面时,由于状态也已重置,因此在第一次渲染时,它会将我视为未登录(即使我已登录)并将我发送到登录页面。

所以我想我可以等待,直到它得到响应,然后用 isAuth(ctx).then(...) 渲染,但是,它只是不渲染任何东西。

这是我的路由器结构:

    <BrowserRouter>
        <AppContext.Provider value={ctx}>
            <Route path="/dashboard">
                <Switch>
                    <LoginRoute exact path="/dashboard/login" component={LogInDash} />
                    <ProtectedRoute exact path="/dashboard/create" component={CreateProperty} />
                    <ProtectedRoute exact path="/dashboard/list" component={ListDash} />
                    <ProtectedRoute exact path="/dashboard/edit/:id" component={EditProperty} />
                    <ProtectedRoute exact path="/dashboard/delete/:id" component={DeleteProperty} />
                </Switch>
            </Route>
        </AppContext.Provider>
    </BrowserRouter>

这是从 API 获取的函数:

export const isAuth = async (ctx: React.ComponentState): Promise<boolean> => {
const fetchRes = fetch(`${APIURL}/api/auth`, {
    method: 'GET',
    headers: { 'Content-Type': 'application/json' },
    credentials: 'include',
})
    .then((res) => {
        res.json();
        if (res.status === 200) {
            ctx.auth.set(true);
            console.log('successful verification');
            return true;
        } else {
            ctx.auth.set(false);
            console.log('Token not verified');
            return false;
        }
    })
    .catch((error) => {
        console.log(error);
        return false;
    });
return fetchRes;

};

最后,这里是 ProtectedRouter 代码:

export function ProtectedRoute({ component: Component, ...rest }: any): any {
    const ctx = React.useContext(AppContext);
    return (
        <Route
            {...rest}
            render={(props) => {
                isAuth(ctx);
                /* isAuth(ctx).then((res) => { */
                if (ctx.auth.get) {
                    return <Component {...rest} {...props} />;
                } else {
                    /* return <Unauthorized />; */
                    return <Redirect to="/dashboard/login" />;
                    /* window.location.href = '/dashboard/login'; */
                }
                /* }); */
            }}
        />
    );
}

我觉得我只是错过了一些愚蠢的东西,或者我试图应用的概念有一些错误。

感谢您读到这里!

【问题讨论】:

    标签: javascript reactjs react-hooks jsx react-component


    【解决方案1】:

    我将引入一个新的isReady 状态和await 用于useEffect 挂钩中的身份验证。例如,在尚未准备好之前,应用程序可以显示正在加载的&lt;span&gt;

    我的建议如下:

    export function ProtectedRoute({ component: Component, ...rest }: any): any {
        const ctx = React.useContext(AppContext);
        const [isReady, setIsReady] = useState(false);
    
        useEffect(() => {
           const runAuth = async () => {
               await isAuth(ctx);
               setIsReady(true);
           }
    
           runAuth();
        }, [])
    
        return (
            <Route
                {...rest}
                render={(props) => {
                    if (!isReady} {
                       return <span>Loading ...</span>
                    }
    
                    if (ctx.auth.get) {
                        return <Component {...rest} {...props} />;
                    } else {
                        /* return <Unauthorized />; */
                        return <Redirect to="/dashboard/login" />;
                        /* window.location.href = '/dashboard/login'; */
                    }
                    /* }); */
                }}
            />
        );
    }
    

    建议阅读是Using the Effect Hook

    【讨论】:

    • 这就像一个魅力,添加一个新的状态变量并使用 UseEffect 就可以了。我正在考虑一种实现异步函数的方法,该函数也可以访问ctx,但没有考虑使用 useEffect...谢谢!
    • @Belf 真棒,乐于助人!
    【解决方案2】:
    // NOTE: Is this firing correctly.. doesn't seem to fire if signed in .... and then try to go to profile or inventory page directly .... always redirects to '/' it seems
    const AuthedRoute = ({ component: Component, user, ...rest }) => (
        <Route
            {...rest}
            render={(props) =>
              user.authenticated === null ? null : user.authenticated ? <Component {...props} /> : <Redirect to="/" />
            }
        />
    );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-30
      • 1970-01-01
      • 2017-05-12
      • 2021-11-04
      • 2019-01-01
      • 1970-01-01
      • 2017-11-11
      相关资源
      最近更新 更多