我在将 React PureComponent
与 Immutable.js 结合使用时遇到了一些问题。考虑以下演示:
https://codepen.io/SandoCalrissian/pen/QaEmeX
其中渲染了 2 个组件。第一个 (NoramlPure
) 是一个普通的 PureComponent
而第二个 (ImmutablePure
) 是一个带有自定义的普通 Component
shouldComponentUpdate
检查 equals
方法的 Prop 。两者都采用单个 Immutable Map
作为 prop,它在每个渲染周期重新形成。每次重新渲染时,两者都会向控制台打印一条消息。
然后我触发两个渲染周期。
我希望两者都只渲染一次。 但是,控制台显示如下:
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
组件作为整个项目的基类?
最佳答案
嗨,桑迪,问题是在每个渲染中你都在重新创建 map Prop ,而 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 组件作为基类?是的,如果您想使用 equals 方法检查 Immutablejs 对象。
关于javascript - Immutable.js 与 React 纯组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47924559/