#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. это очень мило, спасибо!