简体   繁体   English

react-router V6“网址更改但组件未呈现”

[英]react-router V6 "url changes but component does not render"

Despite checking all the answers already posted on stack overflow I coudn't find the solution for my case, so I'll post it.尽管检查了已经在堆栈溢出上发布的所有答案,但我找不到适合我的案例的解决方案,所以我会发布它。

I'm using {Router} from 'react-router (v6) to be able to use a custom history object to be able to navigate in my redux actions.我正在使用“react-router (v6) 中的 {Router}

Here are my files:这是我的文件:

index.tsx索引.tsx

import { Router } from 'react-router';
import myHistory from './utils/history';

ReactDOM.render(
   <Provider store={store}>
      <Router navigator={myHistory} location={myHistory.location}>
         <App />
      </Router>
   </Provider>,
   document.getElementById('root')
);

App.tsx应用程序.tsx

import MainNavigation from './components/navigations/MainNavigation';
import Routes from './routes/Routes';

const App = () => {
   return (
      <>
         <MainNavigation />
         <Routes />
      </>
   );
};

export default App;

MainNavigation.tsx MainNavigation.tsx

import { Link } from 'react-router-dom';

const MainNavigation = () => {
   return (
      <nav className='navigation'>
         <ul>
            <li>
               <Link to='/'>Home</Link>
            </li>
            <li>
               <Link to='/contact'>Contact</Link>
            </li>

            <li>
               <Link to='/about'>A propos</Link>
            </li>

            <li>
               <Link to='/user-profile'>Votre compte</Link>
            </li>
         </ul>
      </nav>
   );
};

export default MainNavigation;

Route.ts路由.ts

import { Route, Routes as Routing } from 'react-router';

const Routes = () => {
   return (
      <Routing>
         <Route path='/' element={<Home />} />
         <Route path='/about' element={<About />} />
         <Route path='/contact' element={<ContactForm />} />
         <Route path='/user-profile' element={<UserAccount />} />
         {/* <Route path='*' component={Error404} /> */}
         {/* <Navigate to='/' /> */}
      </Routing>
   );
};

export default Routes;

The issue: when I click on one of the link the url changes to the corresponding path but the component doesn't render.问题:当我单击其中一个链接时,url 会更改为相应的路径,但组件不会呈现。 I have to refresh the page to actually make it appear.我必须刷新页面才能真正显示它。 I really don't know what's going on.我真的不知道发生了什么事。

Thank you.谢谢你。

you need to include 'index' if you wish to use the '/' route.如果您希望使用“/”路线,则需要包含“索引”。

<Route path='/about' index element={<About />} />

Also, React Router v6 is radically different to v5.此外,React Router v6 与 v5 完全不同。 it switches to the new Outlet based routing.它切换到新的基于插座的路由。 In order to display your pages, you need to have an Outlet in your registered Route component.为了显示您的页面,您需要在注册的 Route 组件中有一个 Outlet。 For example, in the app.js component, you need to add <Outlet /> in order to render these pages.例如,在 app.js 组件中,您需要添加<Outlet />才能呈现这些页面。

I like to think of the new routing as Container-based navigation.我喜欢将新路由视为基于容器的导航。 So create a component called AboutContainer.因此,创建一个名为 AboutContainer 的组件。 Include <Outlet /> in this component.在此组件中包含<Outlet />

export const AboutContainer = () => (
  <Outlet />
)

Then, add a component called AboutPage and put your about page logic inside.然后,添加一个名为 AboutPage 的组件并将您的 about 页面逻辑放入其中。 In your Routes, nest this About page as a new route inside your AboutContainer Router logic;在您的 Routes 中,将此 About 页面作为新路由嵌套在您的 AboutContainer Router 逻辑中;

<Routes>
  <Route path='/about' element={<AboutContainer />}>
    <Route path='/' index element={<AboutPage />} />
  </Route>
...
</Routes>

This means that every time you navigate to /about, you are shown the AboutPage component.这意味着每次导航到 /about 时,都会显示 AboutPage 组件。 Take it a step further and add an additional route更进一步,添加一条额外的路线

<Routes>
  <Route path='/about' element={<AboutContainer />}>
    <Route path='/' index element={<AboutPage />} />
    <Route path='/you' index element={<AboutYouPage />} />
  </Route>
...
</Routes>

This is how routing is now handled in React Router 6这就是 React Router 6 现在处理路由的方式

You can use your routes inherited way like;您可以使用您的路线继承方式,例如;

 <Routes> <Route path="/"> <Route index element={<Home />} /> <Route path="about" element={<About />} /> <Route path="contact" element={<ContactForm />} /> <Route path="user-profile" element={<UserAccount />} /> <Route path="*" element={<NoMatch />} /> </Route> </Routes>

From what I can tell you've not correctly implemented your Router component.据我所知,您没有正确实现Router组件。

Router路由器

If you examine one of the higher-level routers, like BrowserRouter you'll notice they internalize the history object and also store the current location from the result of a navigating action ( history.listen ).如果您检查更高级别的路由器之一,例如BrowserRouter ,您会注意到它们将history object 内部化,并根据导航操作 ( history.listen ) 的结果存储当前位置。

 export function BrowserRouter({ basename, children, window }: BrowserRouterProps) { let historyRef = React.useRef<BrowserHistory>(); if (historyRef.current == null) { historyRef.current = createBrowserHistory({ window }); } let history = historyRef.current; let [state, setState] = React.useState({ action: history.action, location: history.location }); React.useLayoutEffect(() => history.listen(setState), [history]); return ( <Router basename={basename} children={children} location={state.location} navigationType={state.action} navigator={history} /> ); }

Create a CustomRouter that consumes a custom history object and manages the state:创建一个使用自定义history object 并管理 state 的CustomRouter

const CustomRouter = ({ history, ...props }) => {
  const [state, setState] = useState({
    action: history.action,
    location: history.location
  });

  useLayoutEffect(() => history.listen(setState), [history]);

  return (
    <Router
      {...props}
      location={state.location}
      navigationType={state.action}
      navigator={history}
    />
  );
};

Import and use your new custom router instead.导入并改用新的自定义路由器。

import { CustomRouter } from './components/router';
import myHistory from './utils/history';

ReactDOM.render(
  <Provider store={store}>
    <Router history={myHistory}>
      <App />
    </Router>
  </Provider>,
  document.getElementById('root')
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM