首页 > 解决方案 > 当来自 redux 商店的 prop 更改时,React DOM 未更新

问题描述

这让我发疯了好几个小时......我有一个模块,它显示一个从服务器获取并在按下按钮时加载到 redux 商店的列表。这工作正常。我提到这一点是因为这就是我不理解以下行为的原因。

来自商店的这个对象数组被映射到我的组件中

const mapStateToProps = (state) => {
    return {
        extracted_templates: state.extracted_templates
    }
}

并用于render()如下...我删除了一些其他 DOM 部分以保持简单

render(){
    return(
        <div className="main-container">
            {Object.values(this.props.extracted_templates).length > 0 ?
                <ExtractedTemplatesList templates={Object.entries(this.props.extracted_templates)} clickHandler={this.clickHandler} /> : '' }
        </div>
    );
}

clickHandler使用与 fetch 函数相同的操作修改存储。

clickHandler(action, id, parent){
    console.log(action+" "+parent)
    switch(action){
        case 'dismiss':
            let new_template_list = this.props.extracted_templates
            delete new_template_list[id]
            // console.log(new_template_list)
            this.props.dispatch(setExtractedTemplates(new_template_list))
            break;
        default: 
            break;
    }
}

一切都被正确调用,商店正确更新(正如我在我的 web-dev 控制台中看到的那样),但这次 DOM 没有得到更新。为了完整起见,这里是动作和减速器的实现

行动:

export const setExtractedTemplates = (templates) => ({
    type: actions.SET_EXTRACTED_TEMPLATES,
    payload: templates
    });

减速器:

case actions.SET_EXTRACTED_TEMPLATES:
    console.log({action})
    return {
        ...state, 
        extracted_templates: action.payload
}

标签: reactjsdomredux

解决方案


您正在改变现有数据,并将完全相同的对象放回商店:

let new_template_list = this.props.extracted_templates
delete new_template_list[id]
this.props.dispatch(setExtractedTemplates(new_template_list))

这两个都是bug。您永远不应该改变存储中的数据,并且操作的结果应该是存储中的数据。

这就是为什么我们建议将尽可能多的逻辑放入 reducer的原因之一。此外,您应该使用我们的官方 Redux Toolkit 包,它既可以在此处捕获这种意外突变,又可以简化 reducer 中的更新逻辑。


推荐阅读