【问题标题】:React memo creates rerenderReact 备忘录创建重新渲染
【发布时间】:2022-01-10 16:56:44
【问题描述】:

我在使用 nextjs 时遇到了 react memo 问题。在 _app 例如我有一个导入的按钮:

import { ChildComponent } from './ChildComponent';

export const Button = ({ classN }: { classN?: string }) => {
  const [counter, setCounter] = useState(1);
  
  const Parent = () => {
     <button onClick={() => setCounter(counter + 1)}>Click me</button>
  }
  
  return (
    <div>
      {counter}
      <Parent />
      <ChildComponent />
    </div>
  );
};

子组件:

import React from 'react';

export const ChildComponent = React.memo(
  () => {
    React.useEffect(() => {
      console.log('rerender child component');
    }, []);

    return <p>Prevent rerender</p>;
  },
  () => false
);

我做了一个在 React 中工作的程序在我自己的应用程序中无法解决: https://codesandbox.io/s/objective-goldwasser-83vb4?file=/src/ChildComponent.js

【问题讨论】:

    标签: javascript reactjs next.js


    【解决方案1】:

    React.memo() 的第二个参数必须是一个函数,如果组件不需要重新渲染,则返回true,否则返回false - 或in the original definition,旧道具和新道具是否相等。

    因此,在您的代码中,解决方案应该只是将第二个参数更改为:

    export const ChildComponent = React.memo(
      () => { ... },
      // this
      () => true
    );
    

    这会告诉 React “道具没有改变,因此不需要重新渲染这个组件”。

    【讨论】:

    • 感谢您对此进行调查,但不幸的是,这并没有解决我的问题
    • 您希望它只运行一次console.log(),对吗?这不是它在做什么吗?
    • 是的,但我的问题在于 Next.js 框架。以前没遇到过这个问题,很奇怪。我无法显示示例,因为代码和框不适用于 nextjs?
    【解决方案2】:

    所以我的问题是我创建了一个名为 Button 的函数并在按钮或链接中返回。所以我在按钮内有一个 mouseEnter ,它将更新状态并处理函数外的函数。有点尴尬这解决了它。所以唯一的改变是我将 usestate 和 handlemousehover 移到了按钮函数中。

    const Button = () => {
        const [hover, setHover] = useState(false);
    
        const handleMouseHover = (e: React.MouseEvent<HTMLElement>) => {
          if (e.type === 'mouseenter') {
            setHover(true);
          } else if (e.type === 'mouseleave') setHover(false);
        };
    
        return (
          <StyledPrimaryButton
            onMouseEnter={(e) => handleMouseHover(e)}
            onMouseLeave={(e) => handleMouseHover(e)}
          >
            <StyledTypography
              tag="span"
              size="typo-20"
            >
              {title}
            </StyledTypography>
            <ChildComponent />
          </StyledPrimaryButton>
        );
      };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-23
      • 1970-01-01
      • 1970-01-01
      • 2021-12-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多