我有一个代码之前可以工作,但在我更新了所有库之后,它开始连续渲染应用程序组件,并且 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。
store.dispatch(getUserDetailsByToken());
和i18n.changeLanguage('en');
调用都是副作用,应该是渲染的一部分。
当您调用
store.dispatch(getUserDetailsByToken());
时,它可能会启动一个导致重新渲染的进程,从而再次触发调度,依此类推...
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;