#reactjs #react-router
#reactjs #react-маршрутизатор
Вопрос:
Я пытаюсь создать маршрут, к которому могут получить доступ только люди с определенной ролью. Эта роль устанавливается в состоянии (я использую redux) после входа пользователя в систему, однако кажется, что компонент Private Route получает только начальное состояние. Мне нужен компонент PrivateAdminRoute для обновления при изменении состояния, и, похоже, он этого не делает. Это мой App.js:
function App() {
const dispatch = useDispatch();
const loggedInData = useSelector(state => state.loggedInData.loggedIn);
useEffect(() => {
axios.get('/api/users/current')
.then(res => {
if (res.data === "") {
dispatch(signOut());
} else {
dispatch(signIn(res.data.role, res.data.firstName));
}
});
}, [dispatch]);
return (
<div className="App">
<NavBar />
<Switch>
<PrivateAdminRoute path="/admin" component={Admin} role={loggedInData.role} />
</Switch>
</div>
);
}
export default App;
И это мой компонент PrivateAdminRoute:
const PrivateAdminRoute = (props) => {
return <Route path={props.path} render={(props) => (
props.role === 'Admin' ? <Admin /> : <Redirect to='/' />
)}
/>
}
export default PrivateAdminRoute;
И вот мой редуктор:
const loggedReducer = (state = initialState, action) => {
switch(action.type) {
case 'SIGN_IN':
return {
...state,
loggedIn: {
isLogged: true,
role: action.payload.role,
username: action.payload.name
}
}
case 'SIGN_OUT':
return {
...state,
loggedIn: {
isLogged: false,
role: "None",
username: ""
}
}
default:
return state;
}
}
Любая помощь будет оценена!
Комментарии:
1. Это вызвано вашими затененными именами параметров? У вас есть
props
дляPrivateAdminRoute
компонента, а затем у вас естьprops
снова дляrender
свойстваRoute
компонента.props
предоставленный дляrender
функции, имеет только свойства, предоставленные маршрутизатором, и не включает те, которые предоставлены вашемуPrivateAdminRoute
компоненту.2. Это хорошая уловка — вы знаете, как я должен передать
props
то, что я хочу, в функцию рендеринга? Я изменил имя того, что я передавал, но это не решило мою текущую проблему.3. Достаточно было просто изменить имя одного из параметров, а затем получить доступ к свойству с использованием правильного имени, если бы это было проблемой. Обычно я бы попытался свести к минимуму количество анонимных функций и вместо выполнения подкачки при рендеринге маршрута сделать что-то еще в духе
props.role === 'Admin' ? <route path={props.path} component={Admin} /> : <Redirect to="/" />
. Вы убедились, что значение было обновлено в Redux и что вы создаете новое состояние, а не обновляете старое состояние?4. Похоже, что ваш редуктор должен функционировать так, как вы ожидаете. Я создал быстрый пример тестового примера, используя useReducer вместо хранилища redux, и, похоже, он функционирует так, как вы ожидаете: stackblitz.com/edit/react-ts-ebbpws?file=index.tsx
5. Ввод правильного URL-адреса заставил бы его проверять роль и перенаправлять перед загрузкой пользователя. Вам нужно будет добавить состояние загрузки и не отображать маршруты до тех пор, пока пользователь не войдет в систему.