Итак, у меня проблема с реакт-редуксом. У меня есть экран входа в систему, где люди могут ввести свое имя пользователя и пароль. Эти учетные данные отправляются на сервер, и если они верны, клиенту отправляется токен авторизации. Я храню этот токен аутентификации в Redux. Чтобы «визуализировать» мою проблему, я добавил (упрощенный) код ниже. Ниже приведено более подробное объяснение кода.
// folder structure
// ----------------
// - App.js
// - screens/
// - SignIn.js
// - Main.js
// - navigators/
// - Stack.js (stack navigator for SignIn.js and Main.js)
// - store/
// - actions/
// - Auth.js
// - providers/
// - Auth.js
// App.js (simplified)
// -------------------
...
import { AuthProvider } from './providers/Auth'
import StackNavigator from './navigators/Stack'
...
const App = () => {
return (
<Provider store={store}>
<AuthProvider>
<StackNavigator />
</AuthProvider>
</Provider>
}
// screens/SignIn.js (simplified)
// ------------------------------
...
import { saveAuthToken } from '../store/actions/Auth'
...
let req = await fetch('URL_TO_SERVER', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
username,
password
}
let status = req.status
let res = await req.json()
if (status === 200) {
// everything is ok
dispatch(saveAuthToken(res.authToken))
props.navigation.navigate('Main')
}
// screens/Main.js (simplified)
// ----------------------------
...
import { AuthContext } from '../providers/Auth'
import { deleteAuthToken } from '../store/actions/Auth'
...
const { token, state } = useContext(AuthContext)
...
useEffect(() => {
if (state === 'unauthenticated') {
dispatch(deleteAuthToken())
props.navigation.navigate('SignIn')
}
}, [state])
// providers/Auth.js (simplified)
// ------------------------------
...
import React, { createContext } from 'react'
import { useDispatch, useSelector } from 'react-redux'
...
export const AuthContext = createContext()
export const AuthProvider = props => {
const dispatch = useDispatch()
const [token, setToken] = useState(useSelector(state => state.token.auth))
const [state, setState] = useState('pending')
const authenticateHandler = async () => {
// do stuff with a fetch to the server
// to validate the auth token
// let's say the state of the auth token is
// reflected in the status code of the response
let req = await fetch(...)
let status = req.status
let res = await req.json()
if (status === 400) {
setState('expired')
}
if (status === 200) {
setState('authenticated')
}
}
useEffect(() => {
if (token !== null) {
authenticateHandler()
} else {
setState('unauthenticated')
}
}, [state])
return (
<AuthContext.Provider value={{ token, state }}>
{props.children}
</AuthContext.Provider>
)
}
Когда пользователь успешно выполняет вход (экран) Вход , токен аутентификации сохраняется в редуксе через dispatch(saveAuthToken())
. После этого пользователь перенаправляется на (экран) Main . Здесь проблема возникает! Когда пользователь отправляется на (экран) Main , его состояние все еще «не аутентифицировано», потому что useSelector(state => state.token.auth)
возвращает null
в первый раз. Только когда я вручную обновляю sh код, токен успешно извлекается из резервной копии и состояние изменяется на «authenticated». Так что проблема в том, что я не могу проверить «реальное» состояние пользователя ( перед проверкой sh. Поскольку я удаляю токен (экран) Main , когда пользователь не прошел проверку подлинности, я застреваю в бесконечном l oop между SignIn и Main.
Может кто-нибудь помочь мне с этой проблемой