这是一个经常搜索的问题,但据我所知,我似乎并没有遇到常见的陷阱。
我有一个控制所有状态的主要部件。它有一个方法作为道具传入其子组件以更新其状态,如下所示:
changeAttackerAI = (target, index) => {
this.setState(update(this.state.attackers,
{
[index]: {$set: {'ai': {[target.name]: target.value}}},
}
))
}
在这个父组件下面有一个嵌套的组件,它存在另一个只是为了循环并输出列表。看起来像这样:
class Attackers extends Component {
render() {
return (
<div className="attackers">
{this.props.models.map((model, index) => {
console.log(model)
return <Attacker key={index}
index={index}
modelData={model}
removeAttacker={this.props.removeAttacker}
reorderAttackers={this.props.reorderAttackers}
changeAttackerAI={this.props.changeAttackerAI}
/>
})}
</div>
);
}
}
调用changeAttackerAI时,此console.log运行,并且我的更新数据可用。
最后,我有了拒绝更新的组件。最初的渲染之后再也不会调用它的渲染函数,也不会调用componentWillReceiveProps或类似函数。看起来像这样:
class Attacker extends Component {
removeAttacker = () => {
this.props.removeAttacker(this.props.index)
}
changeAttackerAI = (e) => {
this.props.changeAttackerAI(e.target, this.props.index)
}
radioButtonOption = (name, value, label) => {
const existingValue = _.get(this.props.modelData, 'ai.' + name, null)
return <label><input type="radio" name={name} checked={existingValue === value} value={value} onChange={this.changeAttackerAI} /> {label}</label>
}
render() {
const {isDragging, connectDragSource, connectDropTarget, modelData} = this.props
console.log(modelData)
const opacity = isDragging ? 0 : 1
return connectDragSource(connectDropTarget(
<div className="attacker" style={{'opacity': opacity}}>
{modelData.modelName}
<button onClick={this.removeAttacker}>x</button>
<div className="boost_hit">
<h3>Boost Hit</h3>
{this.radioButtonOption('boost_hit', 'none', 'None')}
{this.radioButtonOption('boost_hit', 'all', 'All')}
{this.radioButtonOption('boost_hit', 'initials', 'Initials')}
{this.radioButtonOption('boost_hit', 'chain_attack', 'Chain Attack')}
<label><input type="checkbox" name="free_hit_boosts" value="1" onChange={this.changeAttackerAI} /> Free boosts?</label>
</div>
<div className="boost_damage">
<h3>Boost Damage</h3>
{this.radioButtonOption('boost_damage', 'none', 'None')}
{this.radioButtonOption('boost_damage', 'all', 'All')}
{this.radioButtonOption('boost_damage', 'initials', 'Initials')}
{this.radioButtonOption('boost_damage', 'chain_attack', 'Chain Attack')}
<label><input type="checkbox" name="free_damage_boosts" value="1" onChange={this.changeAttackerAI} /> Free boosts?</label>
</div>
</div>
));
}
}
我在这里做错了什么?
答案 0 :(得分:0)
好的,我知道了我的问题所在。我对不变性助手的功能有误解。当我这样做时:
this.setState(update(this.state.attackers,
{
[index]: {$set: {'ai': {[target.name]: target.value}}},
}
))
我正在用状态的子集覆盖状态。
我需要的是:
this.setState(update(this.state,
{
attackers: {
[index]: {'ai': {$merge: {[target.name]: target.value}}},
}
}
))
我认为确切的问题是该组件首先以原始状态绘制,然后擦除了导致其绘制的原始引用。我认为这会导致将其删除,但显然不会删除。