使用 react-router-dom 停止重新渲染页面中的侧边栏

IAm*_*RC1 7 reactjs react-redux react-router-dom

任何帮助将不胜感激,所以我有一个包含页眉、侧边栏、页脚和主页面的页面,其中侧边栏有静态链接,点击时会显示组件。这里的问题是点击链接,侧边栏,页眉和页脚正在重新呈现,这不是必需的。我在侧边栏中尝试过 shouldComponentUpdate 但它不起作用。项目使用的版本:"react": "^16.12.0", "react-dom": "^16.12.0", "react-router-dom": "^5.1.2",我来了在此问题解决之前,请随时提出任何问题

这是 myApp.js(根文件)

function App() {
  return (
    <Provider store={Store}>
        <Router history={history}>              
            <AppRoutes />
          </Router>             
    </Provider>
  );
}
Run Code Online (Sandbox Code Playgroud)

现在 AppRoutes 组件具有以下方法

const RouteList = [
    {
        path: "/",
        component: Dashboard,
        guest: false,
        exact: true
    },
    {
        path: "/security_info",
        component: SecurityInfoPage,
        guest: false,
        exact: true
    },
]

class AppRoutes extends Component {

    componentDidMount() {
        ...here we fetch the login info from store
        isAuthenticated = true
    }   

    render() {
        ...if it has access token, it 
        return (
            <Switch>
                {RouteList.map((route, i) => (
                    route.guest === false 
                    ? <PrivateRoute isAuthenticated={isAuthenticated} key={i} {...route} /> 
                    : <AppRoute key={i} {...route} />
                    )
                )}
            </Switch>
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

由于 is_authenticated 为真,它转到 AppRoute.js 文件中的私有路由

const PrivateRoute = ({isAuthenticated,  component: Component, ...rest }) => (
   <Route 
        {...rest} 
        render={(props) => (
            isAuthenticated === true
              ? <DashboardLayout>
                            <Component {...props}/>
                        </DashboardLayout>
              : <Redirect to='/login' />
        )} 
    />
)
Run Code Online (Sandbox Code Playgroud)

它转到仪表板布局,其中有多个组件

<div className={'wrapper'}>
                <Navigation />
                <div className="page-content">
                    <Sidebar />
                    <div className="content-wrapper">
                        {children}
                        <MessageSideBar />
                        <Footer />
                    </div>
                </div>
            </div>
Run Code Online (Sandbox Code Playgroud)

现在,当我点击一个不同的链接时,它会进入仪表板布局,在那里它的道具子项会发生变化,渲染整个仪表板,包括页眉、页脚、侧边栏。编辑 1:这是侧边栏文件

class Sidebar extends Component {

componentDidMount = () => {
        it is requesting data from 3 api's
        this.props.dispatch(sidebarAction.sidebarDetail())
        this.props.dispatch(settingAction.getCreditAmount())
        this.props.dispatch(messageAction.getUnReadMessageCount())
    }
render(){
return(
   <ul>
    <li>
     <NavLink 
        exact={true} 
        to="/" >
        <span>Dashboard</span>
     </NavLink>
    </li>
    <li>
      <NavLink to="/security_info">
        <span>Security Information</span>
      </NavLink>
    </li>
   </ul>
)}

Run Code Online (Sandbox Code Playgroud)

虽然有 10 多个 NavLink,但我只包含了 2 个并且还删除了不相关的类名

mle*_*ter 10

方式不对

您的路由的结构类似于以下代码段,这将导致Dashboard每次切换路由时重新渲染 组件。

<Route path="/subComponent" component={SubComponent}/>
Run Code Online (Sandbox Code Playgroud)
const SubComponent = () => {
    return (
        <Dashboard>
            // Here is your content place
        </Dashboard>
    )
}
Run Code Online (Sandbox Code Playgroud)

正确方式

但是,正确的解决方案是将路由直接放在Dashboard组件中,您希望在其中渲染由布局 ( Dashboard)包裹的组件,如下所示:

<Dashboard>
    <DashboardMenu>
        <SideNav /> // e.g. containing links with history.push()
    </DashboardMenu>

    // here is the place where the components wrapped by the layout should be rendered, so place the routes here
    <Route path={...} component={() => <ComponentInsideDashboard />}
</Dashboard>
Run Code Online (Sandbox Code Playgroud)

您应该呈现Dashboard已经在 Dashboard 中的实际内容(动态内容,而不是静态内容)。由于每条路由都返回包裹在 中的动态组件Dashboard,因此Dashboard将被多次渲染。

更简单地说:由于您希望Dashboard只渲染一次,因此您应该只在一个地方使用它。

不同布局的正确方式

如果您还想渲染没有布局 ( Dashboard) 或多个不同布局的内容,您可以简单地使用嵌套路由。

export const BaseApplicationRoutes = () => {
    return (
        <BrowserRouter>
            <Switch>
                <Route path="/dashboard1" component={<Dashboard1 />}/>
                <Route path="/dashboard2" component={<Dashboard2 />}/>
                <Route path="/noDashboard" component={<NoDashboard />}/>
            </Switch>
        </BrowserRouter>
    )
}
Run Code Online (Sandbox Code Playgroud)
export const BaseApplicationRoutes = () => {
    return (
        <BrowserRouter>
            <Switch>
                <Route path="/dashboard1" component={<Dashboard1 />}/>
                <Route path="/dashboard2" component={<Dashboard2 />}/>
                <Route path="/noDashboard" component={<NoDashboard />}/>
            </Switch>
        </BrowserRouter>
    )
}
Run Code Online (Sandbox Code Playgroud)
<Dashboard1> // Dashboard2 could also look like this
    <Dashboard1Menu>
        <SideNav /> // e.g. containing links with history.push()
    </Dashboard1Menu>

    // Routes containing dynamic content
    <Route path={...} component={() => <ComponentWithDashboard1 />}
</Dashboard1>
Run Code Online (Sandbox Code Playgroud)