【问题标题】:React nested component not updating with props change?反应嵌套组件不随道具更改而更新?
【发布时间】:2018-11-01 01:04:03
【问题描述】:

这是一个经常搜索的问题,但我似乎没有遇到常见的陷阱(据我所知)。

我有一个控制所有状态的主要组件。它有一个方法作为 props 传入其子组件以更新其状态,如下所示:

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>
        ));
    }
}

我在这里做错了什么?

【问题讨论】:

  • 您能否简化代码以仅包含与问题相关的部分?
  • 你能突出显示哪个组件没有更新以及期望的行为吗?

标签: reactjs


【解决方案1】:

好的,我知道我的问题是什么。我对不变性助手的功能存在误解。当我这样做时:

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}}},
            }
        }
    ))

我相信确切的问题是组件首先以原始状态绘制,然后我清除了导致它绘制的原始引用。我认为这会导致它被删除,但显然不是。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-25
    • 1970-01-01
    • 1970-01-01
    • 2018-01-15
    • 1970-01-01
    • 2021-01-19
    • 1970-01-01
    相关资源
    最近更新 更多