реквизит reactjs теряется при создании маршрута

#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();
  

чтобы получить параметры.

Подробнее см. В официальной документации.