【问题标题】:React.memo and withRouterReact.memo 和 withRouter
【发布时间】:2020-03-28 04:40:36
【问题描述】:

我不想在某些路径上重新渲染我的组件,尝试使用 React.memo 执行此操作并使用 withRouter HOC 检查当前路径。

React.memo 中的比较函数没有被调用。

function compare(prevProps, nextProps) {
  console.log(prevProps,nextProps)
  return (prevProps.location.pathname !== '/' && nextProps.location.pathname !== '/')
}
export default React.memo( withRouter(MyComponent), compare);

【问题讨论】:

  • 来自React docs上的React.memo:此方法仅作为性能优化存在。不要依赖它来“阻止”渲染,因为这可能会导致错误。
  • 为什么你试图阻止重新渲染?其他一些潜在的问题?也许还有其他方式来构建您的组件,这样特定的组件就不会不必要地渲染。
  • 为了优化,我必须防止不必要的重新渲染。 compare 函数具有特定目的 - 检查是否需要渲染。但我无法调用它。
  • 你应该在 MyComponent 中 use the hooks 因为 withRouter 不会重新渲染,除非父级重新渲染。
  • @HMR 感谢您的回答。由于备忘录无法访问状态值,因此无法渲染的问题仍然存在。

标签: reactjs react-router react-memo


【解决方案1】:

就这样用吧

function compare(prevProps, nextProps) {
  console.log(prevProps,nextProps)
  return (prevProps.location.pathname == nextProps.location.pathname)
}
export default withRouter(React.memo(MyComponent, compare));

小心您即将进行的比较

你的比较有一个流程,如果你在主页面中,路由是/,那么比较函数将总是返回false,导致一直重新渲染(就像memo没有'首先不存在),并且如果您在/ 以外的子路由中,例如/articles,那么比较将始终返回true,从而导致组件一直重新渲染,就像如果memo 本来就不存在。

你想要的是一个比较,它取决于 newold 道具具有 equal 的东西导致保存重新渲染或有不相等的东西导致新的重新渲染来渲染为您提供最新数据。

所以比较应该是这样的

prevProps.location.pathname == nextProps.location.pathname

【讨论】:

    【解决方案2】:

    谢谢你的问题,两个月前对我很有帮助。

    memo 函数接受一个组件和一个 function 来决定 React 是否需要重新渲染,如果函数返回 true 组件将不会重新渲染,如果函数返回 false 然后道具现在不同,React 对您的组件执行 re-render

    现在:要在传递给memofunction 中正确访问pathname,那么memo 应该用withRouter 包装,而不是相反,withRouter 包装一个组件(它不知道它是否是组件的记忆版本,它只是包装它)并将其传递给路由道具。

    function 作为第二个参数传递给 memo 现在可以访问 previousnew 道具并按照我们之前讨论的那样进行比较(其中每个道具在其中包含您想要的完整路由细节)。

    import { memo } from 'react';
    
    function propsAreEqualBasedOnPathname(prevProps, nextProps) {
        return prevProps.location.pathname == nextProps.location.pathname;
    }
    
    withRouter(memo(MyComponent), propsAreEqualBasedOnPathname);
    

    最后,请特别注意在 compare function 中进行比较的方式,因为某些错误可能会阻止您的组件在未来永远重新渲染。

    我发现使用 memowithRouter 对改进 React 组件的 performance 非常重要,特别是如果组件是一个充满细节和获取逻辑的页面,可能会花费你一些时间来渲染,所以每次重新- 渲染您保存,提高您的页面性能

    【讨论】:

    • 需要知道如何使用 React Router v6 做到这一点,因为 V6 中没有更多的 withRouter 组件。
    猜你喜欢
    • 1970-01-01
    • 2018-03-11
    • 2019-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多