react-cookies 中的 useCookies 导致渲染循环

问题描述 投票:0回答:1

我有一个代码之前可以工作,但在我更新了所有库之后,它开始连续渲染应用程序组件,并且 React 抛出无限渲染循环错误:Minified React error #185

这是我的代码:

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);

考虑到用户详细信息收集会导致重新渲染,我尝试添加一个标志以仅调用一次存储函数,但没有成功。

我还注释掉了整个cookie检查,但没有成功。

如果我尝试注释掉该行

const [cookies] = useCookies([AUTHENTICATION_COOKIE]);
并且它无法控制地停止渲染,但这意味着我需要另一种方法来在应用程序启动时检查 cookie。

reactjs cookies react-hooks infinite-loop react-cookie
1个回答
0
投票

store.dispatch(getUserDetailsByToken());
i18n.changeLanguage('en');
调用都是副作用,应该是渲染的一部分。

当您调用

store.dispatch(getUserDetailsByToken());
时,它可能会启动一个导致重新渲染的进程,从而再次触发调度,依此类推...

此外,您应该使用react-redux

useDispatch
useSelector
钩子,而不是使用
connect
HoC 包装组件,并通过导入 store 来获取
dispatch

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

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

const AUTHENTICATION_COOKIE = 'authat';

function App(props) {
  const dispatch = useDispatch();
  const userDetailsLoaded = useSelector(state => state.userReducers.userDetailsLoaded);
  const { i18n } = props;
  const [cookies] = useCookies([AUTHENTICATION_COOKIE]);
  
  const authCookie = cookies[AUTHENTICATION_COOKIE];
  
  // an effect that gets called on mount or whenever authCookie or userDetailsLoaded change
  useEffect(() => {
    if (cookies[AUTHENTICATION_COOKIE] && !userDetailsLoaded) {
      dispatch(getUserDetailsByToken());
    }
  }, [dispatch, authCookie, userDetailsLoaded]);

  // a one time effect on mount
  useEffect(() => {
    i18n.changeLanguage('en');
  }, []);

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

export default App;
© www.soinside.com 2019 - 2024. All rights reserved.