Как исправить ошибку, появившуюся после обновления до react-router v6

#reactjs #react-router-dom

#реагирует на #реагировать-маршрутизатор-дом

Вопрос:

Перед обновлением до v6 у меня была эта часть кода, которая работала так, как должна была:

 //before return (  lt;BrowserRoutergt;  lt;Route render={(props) =gt; (  lt;div className={`layout ${themeReducer.mode}`}gt;  lt;Sidebar {...props}/gt;  lt;div className="layout__content"gt;  lt;TopNav/gt;  lt;div className="layout__content-main"gt;  lt;Switchgt;  lt;Route path='/' exact component={Dashboard} /gt;  lt;Route path='/activity' component={Activity} /gt;  lt;/Switchgt;  lt;/divgt;  lt;/divgt;  lt;/divgt;  )}/gt;  lt;/BrowserRoutergt;  )  

После обновления я изменил только Switch на Routes и component на element и ожидал, что это сработает, но этого не произошло.

 Error: A lt;Routegt; is only ever to be used as the child of lt;Routesgt; element, never rendered directly. Please wrap your lt;Routegt; in a lt;Routesgt;.  

Перепробовал много вещей, но ничего не помогло. Как я могу заставить его работать так, как он работал до обновления?

 //after return (  lt;BrowserRoutergt;  lt;Route render={(props) =gt; (  lt;div className={`layout ${themeReducer.mode}`}gt;  lt;Sidebar {...props}/gt;  lt;div className="layout__content"gt;  lt;TopNav/gt;  lt;div className="layout__content-main"gt;  lt;Routesgt;  lt;Route path='/' element={lt;Dashboard/gt;} /gt;  lt;Route path='/activity' element={lt;Activity/gt;} /gt;  lt;/Routesgt;  lt;/divgt;  lt;/divgt;  lt;/divgt;  )}/gt;  lt;/BrowserRoutergt;  )  

Комментарии:

1. То Route , что является прямым потомком BrowserRouter , должно быть завернуто Routes .

2. Мне просто интересно , почему до обновления до v6 Route был снаружи Switch , но все еще работал

3. В Route компонентах RRDv6 требуется только контекст маршрутизации где -то над ним в дереве реакции. Switch Компонент действительно использовался только для переключения с инклюзивной маршрутизации, т. е. отображения всех совпадающих путей, на эксклюзивную маршрутизацию, т. е. отображение только первого совпадающего пути. Routes Компонент заменяет Switch , а также выполняет двойную работу по сопоставлению маршрутов. В RRDv6 все маршруты/пути теперь всегда точно совпадают, но вы можете отображать столько совпадений, сколько вам нужно. Между компонентами и просто не может быть ничего Routes Route , кроме этих компонентов макета/оболочки.

4. теперь ясно, tnx!

Ответ №1:

На самом деле, Route визуализируемый BrowserRouter объект должен быть завернут в Routes компонент, а также визуализировать JSX на element опоре или обернуть дочерний компонент React.

Похоже, что это компонент макета, поэтому абстрагируйте его в свой собственный компонент, который отображает Outlet для вложенных Route компонентов. Если Sidebar не является функциональным компонентом для использования крючков React, то используйте крючки в компоненте компоновки и передайте их в качестве реквизитов Sidebar , как и раньше. Обратите внимание, что если Sidebar ранее использовался history объект, то он был заменен navigate функцией в RRDv6.

 import { Outlet, useLocation, useMatch, useNavigate } from 'react-router-dom';  const Layout = () =gt; {  const navigate = useNavigate();  const location = useLocation();  const match = useMatch();  // ... etc....   return (  lt;div className={`layout ${themeReducer.mode}`}gt;  lt;Sidebar   location={location}  match={match}  navigate={navigate}  ...... etc....  /gt;  lt;div className="layout__content"gt;  lt;TopNav/gt;  lt;div className="layout__content-main"gt;  lt;Outlet /gt; // lt;-- nested routes render here  lt;/divgt;  lt;/divgt;  lt;/divgt;  ); };  

 return (  lt;BrowserRoutergt;  lt;Routesgt;  lt;Route path="/" element={lt;Layout /gt;} gt;  lt;Route index element={lt;Dashboard /gt;} /gt;  lt;Route path="/activity" element={lt;Activity /gt;} /gt;  lt;/Routegt;  lt;/Routesgt;  lt;/BrowserRoutergt; )  

Комментарии:

1. это очень мило, спасибо!