【问题标题】:How to render page only after setstate如何仅在 setstate 之后渲染页面
【发布时间】:2021-01-02 20:45:51
【问题描述】:

我正在尝试创建用户身份验证页面。在这里,如果令牌已经存储在安全存储中,我将尝试重定向到主页,否则重定向到登录页面。我在应用页面中指定的条件。但是,当用户身份验证为真时,当我关闭并打开应用程序时,应用程序不会重定向到主页。但是,当我点击 new user? 并返回登录页面时,它会重定向到主页。我觉得这与状态更改有关,首先页面呈现初始状态,然后呈现可能导致问题的更改状态。请在这方面帮助我。我已经粘贴了代码供参考

App.js

import React, {useState,useEffect} from 'react';
import {
  SafeAreaView,
  StyleSheet,
  View,
  Text,
  StatusBar
} from 'react-native';


import { NativeRouter, Route,Redirect } from 'react-router-native';
import Login from './login';
import Register from './register';
import Main from './main';
import tokenGetter from './utils/auth';

const App = () => {

const [userAuthenticated,setFlag] = useState(false);

useEffect(()=>{
   tokenGetter('token','peer','peerId').then((data)=>{
     if(data){
       setFlag(true)
     }else{
       setFlag(false)
     }
   }).catch((e)=>{
     console.log(e)
   })
},[userAuthenticated]);

 return (
  <NativeRouter>
   <StatusBar barStyle="dark-content" />
   <Route exact path="/">
   {(userAuthenticated)?<Redirect to="/main" />:<Login/>}
   </Route>
     <Route path='/login' component={Login}/>
     <Route path="/main" component={Main}/>
     <Route path="/about" component={Register}/>
   </NativeRouter>
  );
};

const styles = StyleSheet.create({
 bigBlue: {
  color: 'blue',
  fontWeight: 'bold',
  fontSize: 30,
 },
 red: {
   color: 'red',
  },
});

export default App;

【问题讨论】:

    标签: javascript reactjs react-native react-router react-hooks


    【解决方案1】:

    似乎是需要“加载”状态的经典案例。

    • 添加isAuthenticating 状态。
    • 将设置标志逻辑简化为仅对数据进行真/假。
    • 获取令牌完成后,在finally 回调中设置isAuthtenticating false。
    • 仅当当前未进行身份验证且用户已通过身份验证时,才会有条件地呈现重定向。

    代码建议

    const App = () => {
      const [isAuthtenticating, setIsAuthenticating] = useState(true);
      const [userAuthenticated, setFlag] = useState(false);
    
      useEffect(()=>{
        tokenGetter('token','peer','peerId')
          .then((data) => {
            setFlag(!!data);
          })
          .catch((e)=>{
            console.log(e)
          })
          .finally(() => {
            setIsAuthenticating(false);
          });
      }, []);
    
      return (
        <NativeRouter>
          <StatusBar barStyle="dark-content" />
          <Route exact path="/">
            {(!isAuthtenticating && userAuthenticated) ? <Redirect to="/main" />:<Login/>}
          </Route>
          <Route path='/login' component={Login}/>
          <Route path="/main" component={Main}/>
          <Route path="/about" component={Register}/>
        </NativeRouter>
      );
    };
    

    【讨论】:

    • @SriharshaK 太棒了!如果您发现解释清楚且有帮助,那么也请投票。干杯!
    【解决方案2】:

    问题是您检查userAuthenticated 并转到Login,如果它是false,但您没有等待直到tokenGetter 解决。修复的简单方法是添加loading 状态并等待tokenGetter 解决:

    // HERE
    let [loading, setLoading] = useState(true);
    
    useEffect(()=> {
       tokenGetter('token','peer','peerId').then((data)=>{
         setLoading(false); // <= HERE
         if (data) {
           setFlag(true);
         } else {
           setFlag(false)
         }
       }).catch((e)=>{
         setLoading(false); // <= HERE
         console.log(e)
       })
    },[userAuthenticated]);
    
     return (
      <NativeRouter>
       <StatusBar barStyle="dark-content" />
       <Route exact path="/">
       {!loading && (userAuthenticated ? <Redirect to="/main" />:<Login/>)}
       // ^ HERE
       </Route>
         <Route path='/login' component={Login}/>
         <Route path="/main" component={Main}/>
         <Route path="/about" component={Register}/>
       </NativeRouter>
      );
    };
    

    【讨论】:

      【解决方案3】:

      您可以轻松使用受保护的路由https://www.npmjs.com/package/react-protected-route-compone

      import { BrowserRouter, Switch, Route } from "react-router-dom";
      import ProtectedRoute from "react-protected-route-component";
      
      const Routes = () => {
        return (
          <BrowserRouter>
            <Switch>
              <Route path="/" component={() => <h1>UnProtected Route</h1>} exact />
      
              <ProtectedRoute
                path="/protected"
                redirectRoute="/"
                guardFunction={() => {
                  const token = localStorage.getItem('authToken');
                  if(token){
                    return true;
                  }else{
                    return false;
                  }
                }}
                component={() => <h1>Protected Route</h1>}
                exact
              />
      
            </Switch>
          </BrowserRouter>
        );
      };
      
      export default Routes;
      

      【讨论】:

      • 我没有在浏览器中使用 react 路由器我正在使用 react 原生移动应用程序。所以我认为protectedroute在react native路由器中不可用。
      猜你喜欢
      • 2020-08-08
      • 2017-11-01
      • 2012-02-12
      • 2017-11-22
      • 2022-11-02
      • 2018-04-26
      • 2018-07-17
      • 2011-07-15
      • 2020-05-06
      相关资源
      最近更新 更多