Immutable.js 使用 React 纯组件
Immutable.js with React Pure Components
我在使用 React PureComponent
s 和 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
我在使用 React PureComponent
s 和 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