#javascript #reactjs #react-native #react-router #react-hooks
#javascript #reactjs #реагировать-родной #реагировать-маршрутизатор #реагирующие хуки
Вопрос:
Я пытаюсь создать страницу аутентификации пользователя. Здесь я пытаюсь перенаправить на домашнюю страницу, если токен уже хранится в безопасном хранилище, иначе перенаправить на страницу входа. Условие, которое я указал на странице приложения. Но когда аутентификация пользователя верна, приложение не перенаправляет на главную страницу, когда я закрываю и открываю приложение. Однако, когда я нажимаю на нового пользователя? и вернитесь на страницу входа, затем она перенаправляется на главную страницу. Я чувствую, что это что-то связанное с изменением состояния, и сначала страница отображает начальное состояние, а затем отображает измененное состояние, которое может вызывать проблему. Пожалуйста, помогите мне в этом отношении. Я вставил код для справки
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;
Ответ №1:
Похоже, классический случай необходимости состояния «загрузки».
- Добавьте
isAuthenticating
состояние. - Упростите логику установки флага, чтобы она была просто правдивой / ложной для данных.
- При получении токена завершено, в
isAuthtenticating
обратном вызове установленоfinally
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 amp;amp; userAuthenticated) ? <Redirect to="/main" />:<Login/>}
</Route>
<Route path='/login' component={Login}/>
<Route path="/main" component={Main}/>
<Route path="/about" component={Register}/>
</NativeRouter>
);
};
Ответ №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 amp;amp; (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;
Комментарии:
1. Я не использую react router в браузере, я использую мобильное приложение react native. Поэтому я думаю, что protectedroute недоступен в react native router.