You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React类组件实现的Provider Context中如何正确更新state

根因分析

你遇到的警告是因为在组件渲染流程中直接触发了状态更新:你在Index组件的顶层作用域直接调用setItemsArray,这段代码会在组件每次渲染时同步执行,而setItemsArray内部触发了DragAndDropProvider的setState,导致Provider重渲染,进而触发所有消费该Context的子组件(包括Index组件)再次渲染,形成「渲染→更新状态→渲染」的循环,React检测到这个风险后抛出了对应警告。

修复方案

1. 调整Index组件的状态更新时机

把setItemsArray的调用包裹在useEffect钩子中,仅当documents发生变化时才触发更新,避免每次渲染都执行状态变更逻辑:

import { useEffect } from 'react';

// 原有逻辑保留
const documents = UseGetDocuments();
const { state, setItemsArray } = useContext(DragAndDropContext);

// 新增useEffect包裹更新逻辑
useEffect(() => {
  // 可选:如果documents是异步获取的,可加判断避免空值覆盖
  if (documents?.length) {
    setItemsArray(documents);
  }
}, [documents, setItemsArray]);

2. 可选优化:避免DragAndDropProvider不必要的重渲染

你当前的实现中,每次Provider渲染都会生成全新的Context value对象,哪怕items没有变化,也会触发所有消费该Context的组件强制重渲染,可按如下方式调整Provider实现:

export class DragAndDropProvider extends Component<any, any> {
    constructor(props: any) {
        super(props);
        // 提前绑定方法引用,避免重复创建
        this.an_independent_function = this.an_independent_function.bind(this);
        this.moveItem = this.moveItem.bind(this);
        this.setItems = this.setItems.bind(this);
        
        // 将Context value存入state,仅在需要时更新
        this.state = {
            items: [],
            moveItem: this.moveItem,
            setItems: this.setItems,
            contextValue: {
                state: this.state,
                setItemsArray: this.an_independent_function
            }
        };
    }

    an_independent_function(documents: any) {
        console.log(documents);
        this.setState(prevState => ({
            items: documents,
            // 仅更新contextValue中的state部分,保留其他引用不变
            contextValue: {
                ...prevState.contextValue,
                state: {
                    ...prevState.contextValue.state,
                    items: documents
                }
            }
        }))
    }

    render() {
        return (
            <DragAndDropContext.Provider value={this.state.contextValue}>
                {this.props.children}
            </DragAndDropContext.Provider>
        );
    }
}

内容的提问来源于stack exchange,提问作者Janio Carvalho

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 00:06:05