如何防止导航栏菜单在导航时重新呈现?反应路由器 v4

Str*_*ike 6 reactjs react-router react-router-v4

我正在从 API 服务器获取数据以动态生成 NavBar 菜单。

问题是每次我浏览页面时菜单都会重新呈现。无法弄清楚为什么会这样。我为react-routerv4尝试了不同的例子,比如使用,但菜单总是重新渲染。

动态生成菜单时,您使用什么模式来防止 NavBar 菜单重新呈现?

以下是基本设置文件:

Main.js 文件:

import React from 'react'
import { Route } from 'react-router-dom'
import Home2 from './Home'
import Head from './Head'
import Rules from './Rules'

const Main = () => (
  <main>
    <Route  path='/' component={Head}/>
    <Route exact path='/' component={Home}/>
    <Route exact path='/rules' component={Rules}/>
  </main>
)

export default Main
Run Code Online (Sandbox Code Playgroud)

head.js 文件:

import React, { Component } from 'react'
import Menu from 'semantic-ui-react'

class Head extends Component {
  constructor(props) {
   super(props);
  }

  getInitialData() {
    //fetch data from server
  }

  componentWillMount() {
    this.getInitialData();
  }

  render() {
    return (
      <header>
        <nav>
          <Menu>
            {/* fetched data */}
        </nav>
      </header>
    )
  }
}

export default Head
Run Code Online (Sandbox Code Playgroud)

Index.js 文件:

import React from 'react'
import { render } from 'react-dom'
import Main from './components/Main'
import { BrowserRouter } from 'react-router-dom'

render((
  <BrowserRouter>
    <Main />
  </BrowserRouter>
), document.getElementById('root'));
Run Code Online (Sandbox Code Playgroud)

使用 React Router v3 这段代码工作正常:

var Routes = (
  <Router>
    <Route path="/" component={Head}>
      <IndexRoute component={Home} />
    </Route>
  </Router>
);
Run Code Online (Sandbox Code Playgroud)

但是在 v4 中我不能嵌套路由。

小智 7

尽管已经很晚了,但我想我应该在这里为其他可能为此苦苦挣扎的人发布答案。

首先,根据 @JulesDupont 的回答,您的<Head />组件应该位于路线之外​​。

const App = () => (
  <>
    <Head />
    <Switch>
      <Route exact path='/' component={Component 1}/>
      // Add any other routes goes here
    </Switch>
  </>
)

export default App;
Run Code Online (Sandbox Code Playgroud)

此外,您正在搜索的模式是使用<Link>中的标签react-router-dom。如果您能在这里发布您的 Head 组件,那就太好了。您很有可能使用<a href='/#'>标签来重定向,而不是<Link to='/#'>使用<Menu />.

<a>标签会触发整个页面重新加载,导致<Head />每次导航到新页面时重新安装组件,从而重新获取所有数据。但是,该<Link>标记不会触发整页重新加载。

例子:

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

const Head = () => {
    return (
        <ul>
            <Link to='/your-route'>Item 1 (fetches data)<Link>
            <Link to='/your-other-route'>Item 2 (fetches data)</Link>
        </ul>
    )
}

export default Head;

Run Code Online (Sandbox Code Playgroud)

这将确保您的 Head 组件在导航到另一条路线时不会重新渲染或重新获取数据。


Jul*_*ont 5

因为您将标头作为路由包含在内,所以每次路由更改时都会重新渲染。只需将标题从路由中拉出,它就会在基于路由的组件发生变化时保持一致:

import React from 'react'
import { Route, Switch } from 'react-router-dom'
import Home2 from './Home'
import Head from './Head'

const Main = () => (
  <main>
    <Head />
    <Switch>
      <Route exact path='/' component={Home}/>
      // Add any other routes you want here
    </Switch>
  </main>
)

export default Main;
Run Code Online (Sandbox Code Playgroud)