Immutable.js 使用 React 纯组件

Immutable.js with React Pure Components

我在使用 React PureComponents 和 Immutable.js 时遇到了一些问题。考虑以下演示:

https://codepen.io/SandoCalrissian/pen/QaEmeX

其中渲染了 2 个组件。第一个 (NoramlPure) 是一个普通的 PureComponent,而第二个 (ImmutablePure) 是一个普通的 Component,带有一个自定义的 shouldComponentUpdate,用于检查 equals 方法。两者都采用单个 Immutable Map 作为在每个渲染周期中重新形成的道具。每次重新渲染时,两者都会向控制台打印一条消息。

然后我触发两个渲染周期。

我希望两者都只渲染一次。 然而,控制台显示如下:

rendering
    rendering normal pure component
    rendering immutable pure component
rendering
    rendering normal pure component

我的自定义组件按预期工作,但内置 PureComponent 两次呈现(尽管获得相同的数据)。

看到 React 链接到 Immutable.js in the documentation for PureComponent(并且因为它们都是由 Facebook 制作的)我希望两者能够自然地协同工作,但尽我所能告诉 PureComponent 永远不要调用任何 Immutable.js 等式检查器。

有什么方法可以让 PureComponent 与 Immutable.js 对象一起工作吗? 还是我一直在使用我的 PureImmutable 组件作为整个项目的基础-class?

嗨桑迪,问题是在每个渲染中你都在重新创建地图道具,React.PureComponent 基本上是在检查 props.map === nextProps.map。它们不同,因此重新渲染。

检查这个:

class NormalPure extends React.PureComponent<any, any> {
  public render() {
    console.log("\trendering normal pure component");
    return <div />;
  }
}

class ImmutablePure extends React.Component<any, any> {
  public shouldComponentUpdate(nextProps) {
    return !Object.keys(this.props).every((key) => {
      const val = this.props[key];
      const nextVal = nextProps[key];

      if (typeof val.equals === "function")  {
        return val.equals(nextVal);
      } else {
        return val === nextVal;
      }
    });
  }

  public render() {
    console.log("\trendering immutable pure component");
    return <div />;
  }
}

const wrapper = document.getElementById("wrapper");

const obj = {
  "a": 1,
  "b": 2,
  "c": 3,
};

const immutableMap = Immutable.fromJS(obj);

function render() {
  console.log("rendering");

  ReactDOM.render(
    <div>
      <NormalPure map={immutableMap} />
      <ImmutablePure map={Immutable.fromJS(obj)} />
    </div>,
    wrapper
  );
}

render();
render();

是否有任何方法可以使 PureComponents 与 Immutable.js 对象一起工作? 不能。PureComponent 使用严格的相等比较 (===)。它不知道 Immutablejs

还是我在整个项目中一直使用我的 PureImmutable 组件作为基础-class? 是的,如果您想使用 equals 方法检查 Immutablejs 对象.

目前您可以使用此 ImmutablePureComponent 实现而不是标准 PureComponent:

https://www.npmjs.com/package/react-immutable-pure-component