#reactjs #state
#reactjs #состояние
Вопрос:
В моем главном App.js
компоненте я пытаюсь обновить свое состояние
const[isAuthenticated, setIsAuthenticated] = useState(false)
значение true при загрузке моего пользователя с учетом токена, который у меня есть в локальном хранилище.
useEffect(() => {
const loadUser = async () => {
await fetch('http://localhost:5000/api/auth', {
method: 'GET',
headers: {
'x-auth-token': localStorage.token,
},
});
setIsAuthenticated(true);
};
loadUser();
}, []);
В моем возврате я отрисовываю частный компонент…
<PrivateRoute exact path='/upload' component={Upload} isAuthenticated={isAuthenticated} />
Мой PrivateRoute.js
файл выглядит следующим образом…
const PrivateRoute = ({ component: Component, isAuthenticated, ...rest }) => (
<Route
{...rest}
render={(props) =>
isAuthenticated ? <Component {...props} /> : <Redirect to='/login' />
}
/>
);
В значительной степени, передавая isAuthenticated
в качестве реквизита моему PrivateRoute
компоненту, я бы предположил, что isAuthenticated
следует обновить до true
. Я проверил, правильно ли я загружаю пользователя, проверив данные, которые я получаю из запроса, который я делаю, и действительно, я получаю пользователя и setIsAuthenticated
вызывается
Однако, когда я попытался проверить, что isAuthenticated
находится в моем PrivateRoute
после загрузки пользователя, я получаю, что isAuthenticated
это false
Я не уверен, почему это так, и был бы очень признателен за некоторую помощь и объяснение.
Мой App.js файл выглядит следующим образом…
const App = () => {
const [isAuthenticated, setIsAuthenticated] = useState(false);
useEffect(() => {
const loadUser = async () => {
await fetch('http://localhost:5000/api/auth', {
method: 'GET',
headers: {
'x-auth-token': localStorage.token,
},
});
localStorage.setItem('token', localStorage.token);
setIsAuthenticated(true);
};
loadUser();
}, []);
return (
<Router>
<div className='d-flex flex-row mb-5'>
<Menu />
<div className='d-flex flex-column mt-5 w-100'>
<Switch>
<Route exact path='/' component={Home} />
<Route exact path='/login' component={SignIn} />
<PrivateRoute
exact
path='/upload'
component={Upload}
isAuthenticated={isAuthenticated}
/>
</Switch>
</div>
</div>
</Router>
);
};
Комментарии:
1. Можете ли вы включить весь код компонента для рендеринга
PrivateRoute
компонента? Вы зарегистрировали перехват эффектаisAuthenticated
вPrivateRoute
, чтобы увидеть, получает ли он обновленное состояние? Какие сведения о попытках отладки вы можете предоставить?2. В
PrivateRoute
консоли я зарегистрировалсяisAuthenticated
, чтобы посмотреть, какое значение оно имеет. Я также добавил, как мой App.js файл выглядит как3. @MichaelTorres откуда ты знаешь консоль. журнал печатается после получения пользователя? или как вы проверяете
isAuthenticated
внутриPrivateRoute
?4. «В PrivateRoute я зарегистрировал консоль, прошедшую проверку подлинности, чтобы посмотреть, какое значение она имеет». И каково это значение? Вы видите, что оно обновляется в
App
состоянии? Вы видите, что оно обновляется при изменении состояния вApp
?5. Так и должно быть, вы уверены, что в выборке нет ошибок? Если в выборке ошибка, setIsAuthenticated не будет выполняться
Ответ №1:
Старайтесь не использовать свои реквизиты в функции обратного вызова, которые передаются.
Используйте реквизиты сразу, вот так:
const PrivateRoute = ({ component: Component, isAuthenticated, ...rest }) => {
return isAuthenticated ? (
<Route {...rest} render={(props) => <Component {...props} />} />
) : (
<Route {...rest} render={(props) => <Redirect to="/login" />} />
);
};
Или создайте функцию обратного вызова с помощью useCallback с зависимостями:
const PrivateRoute = ({ component: Component, isAuthenticated, ...rest }) => {
const component = useCallback(
(props) => {
isAuthenticated ? <Component {...props} /> : <Redirect to="/login" />;
},
[isAuthenticated]
);
return <Route {...rest} render={component}/>
};
Комментарии:
1. Спасибо @RobertTirta, я приму это к сведению, но это не решает мою проблему
Ответ №2:
для подобной проблемы лучшим решением является redux
в вашем app.js действие отправки для установки флага isAuthenticate
store.dispatch(setIsAuthenticated(true))
в других файлах, где требуется проверка подлинности, просто используйте
mapStateToProps
Комментарии:
1. Спасибо, но я сделал это с помощью redux. Я пытаюсь сделать это без redux