#javascript #reactjs #react-router #react-props
#javascript #reactjs #реагировать-маршрутизатор #react-props
Вопрос:
Я пытаюсь передать состояние авторизации пользователя компонентам через react-router-dom
блок переключения (я считаю, что мне следует рассмотреть реализацию redux
, но это вопрос на потом).
Существует Home
представление, которому передается вся информация для входа после аутентификации пользователя, и я могу видеть authState
объект как реквизит в домашнем компоненте с помощью react devtools:
import React from "react";
import Dashboard from "../Dashboard";
import {Switch, Route} from "react-router-dom";
import NoMatch from "../NoMatch";
function Home(props) {
// authState exists
return (
<Switch {...props}>
// authState exists
<Route exact path="/" render={(...props) => <Dashboard {...props} />} /> // authState gone
<Route component={NoMatch} />
</Switch>
);
}
export default Home;
после выполнения этого он отображает Dashboard
и отслеживает цепочку компонентов с помощью react devtools, я вижу, что реквизит был успешно передан от Home
компонента к Switch
компоненту. Однако, как только он попадает в Route
реквизит, пропадает, и единственными реквизитами, доступными в Dashboard
компоненте, являются history
, location
и match
реквизит.
Почему отсутствуют реквизиты и как правильно их передать?
Комментарии:
1. У вас есть
props
в пределахHome
и в пределах функции рендерингаRoute
. Переменная с более высокой областью действия будет затенена более низкой. Вы можете переименовать один и распространить оба:(renderProps) => <Dashbaord {...props} {...renderProps} />
Ответ №1:
Пара улучшений, необходимых в вашем коде:
- Передача реквизита
Switch
компоненту не требуется - Нет необходимости собирать реквизит маршрутизатора, используя синтаксис rest, только для их последующего распространения
Основная проблема:
props
внутри функции, переданной вrender
prop, ссылается на реквизит маршрутизатора, а не на реквизит, переданныйHome
компоненту. Вы используете один и тот же идентификатор для двух разных вещей.
Решение
Используйте разные имена для реквизита маршрутизатора и реквизита, переданного Home
компоненту, который вы хотите передать Dashboard
компоненту
function Home(props) {
return (
<Switch>
<Route
exact
path="/"
render={(routerProps) => <Dashboard {...routerProps} {...props} />}
/>
<Route component={NoMatch} />
</Switch>
);
}
В качестве альтернативы, если вам не нужен доступ к реквизиту маршрутизатора в Dashboard
компоненте, удалите props
параметр из функции render
prop .
<Route
exact
path="/"
render={() => <Dashboard {...props} />}
/>
Теперь у вас не будет доступа к реквизитам маршрутизатора внутри Dashboard
компонента, но состояние авторизации пользователя будет передано Dashboard
компоненту.
Ответ №2:
В самых последних версиях react-router-dom
вы должны заменить render
component
атрибуты и на element
. Вы больше не можете передавать туда функцию обратного вызова, в которой были указаны реквизиты маршрута.
Вместо этого вы можете использовать перехват в своем маршрутизируемом компоненте:
const params = useParams();
чтобы получить параметры.
Подробнее см. В официальной документации.