我在使用Reutable PureComponent
和Immutable.js时遇到了一些麻烦。请考虑以下演示:
https://codepen.io/SandoCalrissian/pen/QaEmeX
在其中呈现2个组件。第一个(NoramlPure
)是正常PureComponent
,而第二个(ImmutablePure
)是普通Component
,其自定义shouldComponentUpdate
检查道具equals
1}}方法。两者都采用单个不可变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
组件作为基类?
答案 0 :(得分:3)
嗨桑迪问题是,在每个渲染中你都在重建地图道具和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对象一起使用? No. PureComponent使用严格的相等比较(===)。它不了解Immutablejs
还是我在整个项目中使用我的PureImmutable组件作为基类?是的,如果你想用equals方法检查Immutablejs对象。
答案 1 :(得分:0)
当前,您可以使用此ImmutablePureComponent
实现代替标准的PureComponent
:
https://www.npmjs.com/package/react-immutable-pure-component