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

React Context传值时出现Too many re-renders错误的解决方法

解决React Context结合i18n时的无限渲染问题

问题原因分析

你的代码触发"Too many re-renders"无限循环,核心问题有两个:

  1. i18n初始化逻辑放在组件内部:每次Context组件渲染时,都会重复执行i18n.init(),这会触发i18n状态变更,进而导致组件重新渲染,形成循环。
  2. 不必要的状态更新(可选):onChange里的setCount如果不是业务必需,会额外触发组件渲染,放大循环问题。

具体修复步骤

1. 抽离i18n初始化到独立文件

创建单独的i18n.js文件,把初始化逻辑移到这里,确保全局只执行一次初始化:

// i18n.js
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import translationsEn from './path-to-en-translations';
import translationsBn from './path-to-bn-translations';

i18n
  .use(initReactI18next)
  .init({
    resources: {
      en: { translation: translationsEn },
      bn: { translation: translationsBn },
    },
    lng: "bn",
    fallbackLng: "bn",
    interpolation: { escapeValue: false },
  });

export default i18n;

然后在项目入口文件(比如index.js)引入该文件,完成全局初始化:

// index.js
import './i18n';
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);

2. 优化Context组件逻辑

在Context组件中移除重复初始化逻辑,并缓存Context的value对象,避免不必要的子组件渲染:

// Context.js
import React, { createContext, useContext, useState, useMemo } from 'react';
import { useTranslation } from 'react-i18next';

const LanguageContext = createContext();

export const LanguageProvider = ({ children }) => {
  const { t, i18n } = useTranslation();
  // 如果count不是业务必需,建议直接移除
  const [count, setCount] = useState(0);

  const onChange = (event) => {
    i18n.changeLanguage(event.target.value);
    // 非必需的count更新可以删除
    setCount(prev => prev + 1);
  };

  // 用useMemo缓存Context值,避免每次渲染创建新对象
  const contextValue = useMemo(() => ({
    t,
    onChange,
    count
  }), [t, count]);

  return (
    <LanguageContext.Provider value={contextValue}>
      {children}
    </LanguageContext.Provider>
  );
};

export const useLanguage = () => useContext(LanguageContext);

3. 组件中正确使用Context

在Component.js中通过自定义hook获取Context提供的方法:

// Component.js
import React from 'react';
import { Select, MenuItem } from '@mui/material';
import { useLanguage } from './Context';

const LanguageSelector = () => {
  const { onChange } = useLanguage();

  return (
    <Select
      defaultValue={"en"}
      variant="outlined"
      displayEmpty
      name="language"
      notched={false}
      size="small"
      onChange={onChange}
      sx={{
        color: "other.white",
        border: "2px",
        "&:hover": {
          border: "2px",
        },
      }}
    >
      <MenuItem value="en">English</MenuItem>
      <MenuItem value="bn">বাংলা</MenuItem>
    </Select>
  );
};

export default LanguageSelector;

额外注意事项

  • 如果count状态不是业务必需,直接移除它,减少不必要的状态更新触发的渲染。
  • 传递给Context的value如果是对象或数组,必须用useMemo缓存,避免每次组件渲染都创建新对象,导致所有消费Context的子组件重复渲染。
  • 确保useTranslation的使用符合react-i18next最佳实践,不要在非必要的地方重复调用。

内容的提问来源于stack exchange,提问作者MD. Istiak Shamim Shishir

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 20:31:34