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

react-cookies的useCookies引发React无限渲染循环问题

问题描述

更新所有依赖库后,App组件出现持续渲染的无限循环,React抛出Minified React error #185错误。注释掉const [cookies] = useCookies([AUTHENTICATION_COOKIE]);后循环停止,但需要在应用启动时检查cookie。

相关代码:

import React from 'react';
import { CookiesProvider, useCookies } from 'react-cookie';
import { withTranslation } from 'react-i18next';
import { connect } from 'react-redux';

import store from './redux/store';

import { getUserDetailsByToken } from './redux/actions/user-actions';

const AUTHENTICATION_COOKIE = 'authat';

function App(props) {
  const { i18n, userDetailsLoaded } = props;
  const [cookies] = useCookies([AUTHENTICATION_COOKIE]);

  if (cookies[AUTHENTICATION_COOKIE] && !userDetailsLoaded) {
    store.dispatch(getUserDetailsByToken());
  }

  i18n.changeLanguage('en');

  return (
    <CookiesProvider>
      <div className="app">
        <Header />
        <main className="app-content full-height">
          ...
        </main>
      </div>
    </CookiesProvider>
  );
}

function mapStateToProps(state) {
  return {
    userDetailsLoaded: state.userReducers.userDetailsLoaded,
  };
}

export default connect(mapStateToProps)(App);

解决方案

1. 修正CookiesProvider的位置

当前useCookies在CookiesProvider外部调用,违反了react-cookie的使用规则——必须在CookiesProvider上下文内使用useCookies。更新依赖后该问题被严格校验,直接触发无限渲染。

需要把CookiesProvider移到App组件外层,比如在入口文件(如index.js)中包裹App:

// index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import { CookiesProvider } from 'react-cookie';
import App from './App';

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

同时移除App组件return中的CookiesProvider。

2. 避免每次渲染都执行语言切换

i18n.changeLanguage('en')在组件每次渲染时都会执行,会触发组件重新渲染,形成循环。用useEffect包裹,只在组件挂载时执行一次:

import React, { useEffect } from 'react';

function App(props) {
  const { i18n, userDetailsLoaded, dispatch } = props;
  const [cookies] = useCookies([AUTHENTICATION_COOKIE]);

  useEffect(() => {
    i18n.changeLanguage('en');
  }, [i18n]);
  // 其他逻辑
}

3. 正确处理Redux dispatch逻辑

不要直接调用store.dispatch,改用connect注入的dispatch,并把dispatch逻辑放到useEffect中,避免每次渲染都触发:

useEffect(() => {
  if (cookies[AUTHENTICATION_COOKIE] && !userDetailsLoaded) {
    dispatch(getUserDetailsByToken());
  }
}, [cookies, userDetailsLoaded, dispatch]);

完整修复后的App组件代码

import React, { useEffect } from 'react';
import { useCookies } from 'react-cookie';
import { withTranslation } from 'react-i18next';
import { connect } from 'react-redux';

import { getUserDetailsByToken } from './redux/actions/user-actions';

const AUTHENTICATION_COOKIE = 'authat';

function App(props) {
  const { i18n, userDetailsLoaded, dispatch } = props;
  const [cookies] = useCookies([AUTHENTICATION_COOKIE]);

  useEffect(() => {
    i18n.changeLanguage('en');
  }, [i18n]);

  useEffect(() => {
    if (cookies[AUTHENTICATION_COOKIE] && !userDetailsLoaded) {
      dispatch(getUserDetailsByToken());
    }
  }, [cookies, userDetailsLoaded, dispatch]);

  return (
    <div className="app">
      <Header />
      <main className="app-content full-height">
        ...
      </main>
    </div>
  );
}

function mapStateToProps(state) {
  return {
    userDetailsLoaded: state.userReducers.userDetailsLoaded,
  };
}

export default connect(mapStateToProps)(withTranslation()(App));

内容的提问来源于stack exchange,提问作者Cosmin Glodean

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 08:55:28