This is an oft-searched issue, but I don't seem to be running into the common pitfalls (as far as I can tell).
I have a main component which controls all state. It has a method which is passed in as props to its child component for updating its state that looks like this:
changeAttackerAI = (target, index) => {
this.setState(update(this.state.attackers,
{
[index]: {$set: {'ai': {[target.name]: target.value}}},
}
))
}
Nested beneath this parent component I have another which exists just to loop through and output a list. Looks like this:
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>
);
}
}
When changeAttackerAI is called, this console.log runs and my updated data is available.
And finally I have the component that refuses to update. Its render function is never called after the initial render, and componentWillReceiveProps or similar never get called. Looks like this:
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>
));
}
}
What am I doing wrong here?