为什么要重新渲染 Route 之外的 React 元素?

Why do react elements outside of Route re-render?

打开react router官方文档中的sidebar example。您可以看到 ul 在没有 Route 的情况下呈现,因为无论 url 是什么,它都应该出现在屏幕上。打开 React DevTools,选中 Highlight updates 复选框并单击侧栏中的任意菜单项。您会注意到 ul 下的元素会在每次点击时重新呈现。在我看来,这不是理智的行为,ul 下的反应元素不应该随着路由变化而重新渲染,因为它们不是由反应路由器 Route 组件渲染的。有什么办法可以阻止它们重新渲染吗?

Router 组件依赖于上下文进行更改,每当更新上下文值时,它都会触发子项的重新呈现以进行匹配并呈现适当的路由。现在,由于 ul element 直接写为 child of Router,它也会重新呈现。尽管 React 执行虚拟-dom 比较并且不会重新渲染 DOM,但您可以通过使用 PureComponent 并在其中写入 ul 元素来避免它 Component

const SidebarExample = () => (
  <Router>
    <div style={{ display: "flex" }}>
      <div
        style={{
          padding: "10px",
          width: "40%",
          background: "#f0f0f0"
        }}
      >
        <Route component={Elements}/>
        {routes.map((route, index) => (
          // You can render a <Route> in as many places
          // as you want in your app. It will render along
          // with any other <Route>s that also match the URL.
          // So, a sidebar or breadcrumbs or anything else
          // that requires you to render multiple things
          // in multiple places at the same URL is nothing
          // more than multiple <Route>s.
          <Route
            key={index}
            path={route.path}
            exact={route.exact}
            component={route.sidebar}
          />
        ))}
      </div>

      <div style={{ flex: 1, padding: "10px" }}>
        {routes.map((route, index) => (
          // Render more <Route>s with the same paths as
          // above, but different components this time.
          <Route
            key={index}
            path={route.path}
            exact={route.exact}
            component={route.main}
          />
        ))}
      </div>
    </div>
  </Router>

)

class Elements extends React.PureComponent {
    render() {
        return (
          <ul style={{ listStyleType: "none", padding: 0 }}>
            <li>
              <Link to="/">Home</Link>
            </li>
            <li>
              <Link to="/bubblegum">Bubblegum</Link>
            </li>
            <li>
              <Link to="/shoelaces">Shoelaces</Link>
            </li>
          </ul>
        )
    }
}