父组件:
import React, { Component } from 'react';
import { Child } from './Child';
const testObject = {
test: {
one: false,
two: false,
three: false,
},
};
export class Parent extends Component {
constructor() {
super();
this.state = {
test: testObject.test,
};
}
render() {
return (
<Child test={ this.state.test } />
)
}
子组件:
import React, { Component, PropTypes } from 'react';
export class Child extends Component {
shouldComponentUpdate(nextProps) {
return nextProps.test !== this.props.test;
}
render() {
console.log('hey! i\'m rendering!!');
return (
<div>Child</div>
);
}
}
Child.propTypes = {
test: PropTypes.object.isRequired,
};
问题: 现在,它不起作用。当让我们说test.one变为true时,shouldComponentUpdate仍会重新渲染。我阅读了关于immutablejs和反应文档的文档,但我仍然不理解。对你们来说应该很容易,有人可以帮忙吗?
答案 0 :(得分:1)
testObject
不是一成不变的。当然它不能被另一个对象替换:testObject = anotherTestObject
被禁止,但可以修改one
,two
或three
:testObject.one = true
就可以了。 ImmutableJS提供禁止testObject
值修改的mecanismes。
调用SetState将创建一个新的this.state.test
,因此,nextProps.test !== this.props.test
始终会重新生成。
答案 1 :(得分:0)
您的组件会重新呈现,因为评估nextProps.test !== this.props.test
将始终返回true
,因为值或类型都不会更改。
您似乎只更改了one
对象的two
,three
和test
的属性值。这里的问题是你试图将一个对象的属性评估到另一个对象,而这不能用(严格)比较运算符(例如==
或===
)来完成。
解决此问题的一种方法是将对象转换为JSON进行比较:
return JSON.stringify(nextProps.test) !== JSON.stringify(this.props.test);
另一个解决方案是逐个比较每个属性:
for(let key in this.props.test) {
if(!(key in nextProps.test) || this.props.test[key] !== nextProps.test[key]) {
return true; //the current property didn't evaluate - component should update
}
}
for(var key in nextProps.test) {
if(!(key in this.props.test) || nextProps.test[key] !== this.props.test[key]) {
return true; //the current property didn't evaluate - component should update
}
}
return false; //the objects are equal - component shouldn't update
编辑: Damien Leroux正确指出您的testObject
是不可变的,因为您已将其声明为常量。你可能想改变它。