ReactJs:防止包装组件的重新渲染

ReactJs: Prevent Rerender of wrapped component

我现在几个小时都在尝试阻止 re-render 使用自定义挂钩 -.-,需要一些帮助;O|

(不知道我是否应该调用这个自定义钩子或函数 hoc)

我有一个显示包含在 WithAvatarHeader 中的 SimpleMessage 的 MessageList 组件。 这是我的探查器结果:

每次我向列表中添加一条消息时,所有消息都会重新呈现。

当我只在 MessageList 中使用 SimpleMessage 时,这不会发生

有没有memo(WithAvatarHeader)的方法?

消息列表:

import React from "react";
import SimpleMessage from "./SimpleMessage";
import WithAvatarHeader from "./WithAvatarHeader";


const MessageList = props => {
  const Message = WithAvatarHeader(SimpleMessage);
  return (
    <div className="message-list">
      {props.messages.map(message => {
        return <Message message={message} key={message._id}/>;
      })}
    </div>
  );
};

简单消息:

import React, { memo } from "react";

const SimpleMessage = props => {
  return (
    <div className="simple-message">
      {props.message}
    </div>
  );
};

export default memo(SimpleMessage);

使用头像标题:

import React from "react";

const WithAvatarHeader = WrappedComponent => props => {
  return <WrappedComponent {...props} />;
};

export default WithAvatarHeader;

感谢您的帮助:-)

您不应在另一个组件内声明组件。

一旦你将声明移到外面:

const Message = WithAvatarHeader(SimpleMessage);
const MessageList = props => {
  return (
    <div className="message-list">
      {props.messages.map(message => {
        return <Message message={message} key={message._id}/>;
      })}
    </div>
  );
};

你会没事的。

原因是 reconciliation 决定删除什么、创建什么以及更新什么的过程。

除了你的 JSX 说它仍然是相同的元素 <Message> React 检查组件的构造函数(它不适用于 JSX 的文本表示)。并且它将在引用上有所不同(因为您在下一次渲染时重新声明了此构造函数)。所以 React 删除每个 <Message> 并从头开始创建它们。将声明保持在 MessageList 之外意味着构造函数在引用上是相同的,因此 React 不会重新创建 <Message> 直到 key 相同。