del*_*jah 5 javascript reactjs
当我创建一个react类的几个实例时(通过在同一个类上使用React.createElement),一些成员变量在实例之间共享(数组和对象是共享的,字符串和布尔值等等).
对我来说,这感觉太可怕,可怕和错误.这是一个错误还是有另一种方法可以做我想做的事情?
请看一下:http: //jsbin.com/kanayiguxu/1/edit?html,js,console,output
And*_*ahl 11
您应该做的是在组件上设置状态,而不是在React组件上将状态作为任意属性.
所以不要这样做:
var MyComponent = React.createClass({
myArray: [1, 2, 3],
componentWillMount() {
this.myArray.push(this.myArray.length + 1);
},
render() {
return (
<span>{this.myArray.length}</span>
);
}
});
Run Code Online (Sandbox Code Playgroud)
你应该这样做:
var MyComponent = React.createClass({
getInitialState() {
return {
myArray: [1, 2, 3]
};
},
componentWillMount() {
this.setState(state => {
state.myArray.push(state.myArray.length + 1);
return state;
});
},
render() {
return (
<span>{this.myArray.length}</span>
);
}
});
Run Code Online (Sandbox Code Playgroud)
原因是,所有一组件状态和数据的应驻留在this.state和this.props被控制,并通过阵营处理.
使用道具和状态获得的好处是,React会知道这些更改的时间,并且从中可以判断何时需要重新渲染组件.如果将状态存储为任意属性或全局变量,React将不知道何时更改,并且无法为您重新渲染.
您所看到的行为的原因是组件的每个实例都使用您提供的对象React.createClass()作为其原型.因此,组件的所有实例都具有myArray属性,但它位于原型链上,因此由所有实例共享.
如果你真的想要这样的东西并且你想要避免this.state,你应该componentWillMount在该方法中使用类似的东西,分配属性this.这将确保此类数据仅在该特定实例上,而不在原型链上.
编辑
为了进一步澄清,最好知道传递给的对象React.createClass()不是原型上的实际对象.React做的是迭代该对象上的所有属性,并将它们复制到React元素对象的原型上.这可以通过这个例子来说明:
var obj = {
myArray: [1, 2, 3],
title: 'My title',
componentWillMount() {
this.myArray.push(this.myArray.length + 1);
},
render() {
return (
<span>{this.myArray.length}</span>
);
}
}
var MyComponent = React.createClass(obj);
// This doesn't change the component, since 'obj' isn't used anymore
// by React, it has already copied all properties.
obj.title = 'New title';
// This however affects the component, because the reference to the array
// was copied to the component prototype, and any changes to what the
// reference points to will affect everyone who has access to it.
obj.myArray.push(666);
Run Code Online (Sandbox Code Playgroud)