React setState 更新道具
React setState updates props
我正在开发一个组件,其中包含多个可以选择的子组件(或 'activated',正如此处的命名所示。)。我有一个 ID 数组,应该使用所有被选中的 ID 进行初始化,因此 this.state.activeSensors
指的是传感器的总列表:this.props.mainViewSensors
。
函数 sensorSelect
获取 ID,并且应该能够确定它是否被选中。我的方法是检查它是否在 activeSensors 列表中——如果存在则删除它,如果不存在则添加它。设置新状态。
当我从新列表 newActiveSensors
中删除一个项目并调用 setState 时,被点击的项目也会以某种方式从道具中消失。我不知道这是可能的。这是我做错了什么吗?
这是我所做的:
const propTypes = {
mainViewSensors: PropTypes.arrayOf(PropTypes.string),
};
const defaultProps = {
mainViewSensors: [
'21EL',
'05LO',
'08HT',
'81EL',
'05TF',
],
}
class Multiselect extends React.Component {
constructor(props) {
super(props);
this.sensorSelect = this.sensorSelect.bind(this);
this.state = {
activeSensors: this.props.mainViewSensors,
selectedSensors: this.props.mainViewSensors,
};
}
sensorSelect(sensor) {
const newActiveSensors = this.state.activeSensors;
if (newActiveSensors.includes(sensor)) {
const index = newActiveSensors.indexOf(sensor);
newActiveSensors.splice(index, 1);
} else {
newActiveSensors.push(sensor);
}
this.setState({
activeSensors: newActiveSensors,
});
}
render() {
const { selectedSensors, activeSensors } = this.state;
return (
<div className="wrapper">
{this.state.selectedSensors.map((tag) => (
<div key={tag} role="button" className="main-gauge-holder" onClick={this.sensorSelect(tag)}>
<MainGauge tag={tag} />
</div>
))}
</div>
);
}
}
Multiselect.propTypes = propTypes;
Multiselect.defaultProps = defaultProps;
React.render(<Multiselect />, document.getElementById('container'));
为了清楚起见,我正在做这样的事情,其中绿色箭头显示选择了哪一个(这里我手动更改了子组件中的活动状态):
这实际上不是 React 问题,你只是在你身上使用了相同的数组实例 class。您必须 make a new array 才能使用它的副本。
请参阅我的示例进行说明:
var primaryArray = [1, 2, 3];
console.log('Init :');
console.log(primaryArray);
var obj = {
array: primaryArray, // Same instance
clonedArray: primaryArray.slice() // Clone
};
console.log(obj);
console.log('Poping from the same instance :');
obj.array.pop();
console.log(obj);
console.log(primaryArray);
console.log('Poping from the cloned array doesn\'t affect primary one :');
obj.clonedArray.pop();
console.log(obj);
console.log(primaryArray);
我正在开发一个组件,其中包含多个可以选择的子组件(或 'activated',正如此处的命名所示。)。我有一个 ID 数组,应该使用所有被选中的 ID 进行初始化,因此 this.state.activeSensors
指的是传感器的总列表:this.props.mainViewSensors
。
函数 sensorSelect
获取 ID,并且应该能够确定它是否被选中。我的方法是检查它是否在 activeSensors 列表中——如果存在则删除它,如果不存在则添加它。设置新状态。
当我从新列表 newActiveSensors
中删除一个项目并调用 setState 时,被点击的项目也会以某种方式从道具中消失。我不知道这是可能的。这是我做错了什么吗?
这是我所做的:
const propTypes = {
mainViewSensors: PropTypes.arrayOf(PropTypes.string),
};
const defaultProps = {
mainViewSensors: [
'21EL',
'05LO',
'08HT',
'81EL',
'05TF',
],
}
class Multiselect extends React.Component {
constructor(props) {
super(props);
this.sensorSelect = this.sensorSelect.bind(this);
this.state = {
activeSensors: this.props.mainViewSensors,
selectedSensors: this.props.mainViewSensors,
};
}
sensorSelect(sensor) {
const newActiveSensors = this.state.activeSensors;
if (newActiveSensors.includes(sensor)) {
const index = newActiveSensors.indexOf(sensor);
newActiveSensors.splice(index, 1);
} else {
newActiveSensors.push(sensor);
}
this.setState({
activeSensors: newActiveSensors,
});
}
render() {
const { selectedSensors, activeSensors } = this.state;
return (
<div className="wrapper">
{this.state.selectedSensors.map((tag) => (
<div key={tag} role="button" className="main-gauge-holder" onClick={this.sensorSelect(tag)}>
<MainGauge tag={tag} />
</div>
))}
</div>
);
}
}
Multiselect.propTypes = propTypes;
Multiselect.defaultProps = defaultProps;
React.render(<Multiselect />, document.getElementById('container'));
为了清楚起见,我正在做这样的事情,其中绿色箭头显示选择了哪一个(这里我手动更改了子组件中的活动状态):
这实际上不是 React 问题,你只是在你身上使用了相同的数组实例 class。您必须 make a new array 才能使用它的副本。
请参阅我的示例进行说明:
var primaryArray = [1, 2, 3];
console.log('Init :');
console.log(primaryArray);
var obj = {
array: primaryArray, // Same instance
clonedArray: primaryArray.slice() // Clone
};
console.log(obj);
console.log('Poping from the same instance :');
obj.array.pop();
console.log(obj);
console.log(primaryArray);
console.log('Poping from the cloned array doesn\'t affect primary one :');
obj.clonedArray.pop();
console.log(obj);
console.log(primaryArray);