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

React给Context赋值触发Maximum Update Depth Exceeded错误如何解决

错误原因

你在render渲染方法的map遍历中直接调用了修改Context状态的setCurrency方法,触发了无限更新循环:

  • 调用setCurrency会更新CurrencyContext的全局状态
  • Context状态变更会触发所有消费该Context的组件重新渲染,你的CurrencySelector组件也会重新执行render方法
  • 重新执行render时又会走到遍历货币列表的逻辑,再次调用setCurrency,循环往复直到超出React的最大更新深度限制,触发报错。
    补充:React的渲染函数必须是纯函数,不能包含修改状态这类副作用操作

修复方案

将设置默认货币的逻辑从渲染阶段移到接口请求完成的生命周期中执行:

  1. 给CurrencySelector类添加contextType配置,方便在生命周期方法中直接访问Context
  2. 在componentDidMount拿到接口返回的货币列表后,再执行默认货币的设置逻辑
  3. 删除render方法map遍历中调用setCurrency的判断代码

修改后完整代码

import React, { Component, createContext } from "react";

const CurrencyContext = createContext();

class CurrencyContextProvider extends Component {
  state = { selectedCurrency: "uuu" };
  setCurrency = (c) => {
    this.setState({ selectedCurrency: c });
  };

  render() {
    return (
      <CurrencyContext.Provider
        value={{ ...this.state, setCurrency: this.setCurrency }}
      >
        {this.props.children}
      </CurrencyContext.Provider>
    );
  }
}

class CurrencySelector extends React.Component {
  // 新增:配置contextType,用于在生命周期中访问Context
  static contextType = CurrencyContext;

  constructor(props) {
    super(props);
    console.log("CurrencySelector constructor");
    this.state = { currencies: [] };
  }

  async componentDidMount() {
    let currencies = (await this.getCurrencies()).data.currencies;
    this.setState({ currencies: currencies });
    // 新增:在这里设置默认货币
    if (currencies.length > 0) {
      const { setCurrency, selectedCurrency } = this.context;
      // 加判断避免不必要的重复更新
      if (selectedCurrency !== currencies[0]) {
        setCurrency(currencies[0]);
      }
    }
  }

  async getCurrencies() {
    return await fetchAnyQuery(`query{ currencies }`);
  }

  render() {
    return (
      <CurrencyContext.Consumer>
        {(currencyContext) => {
          const {
            selectedCurrency,
            setCurrency,
          } = currencyContext;
          return (
            <select
              name="currency-selector"
              value={selectedCurrency}
              onChange={(event) => {
                setCurrency(event.target.value);
              }}
            >
              {this.state.currencies.map((currency, index) => {
                // 删除了原来在这里的setCurrency调用逻辑
                return (
                  <option value={currency} key={currency}>{currency}</option>
                );
              })}
            </select>
          );
        }}
      </CurrencyContext.Consumer>
    );
  }
}

补充:还额外给select加了value绑定和option加了key属性,都是React列表渲染和表单组件的最佳实践


内容的提问来源于stack exchange,提问作者asem shaat

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 09:57:02