错误:使用 react-hooks 时超出最大更新深度
Posted
技术标签:
【中文标题】错误:使用 react-hooks 时超出最大更新深度【英文标题】:Error: Maximum update depth exceeded when using react-hooks 【发布时间】:2020-03-26 16:05:35 【问题描述】:我正在尝试将我的所有源代码从使用 react with redux 更改为 react-hook with redux 并将其与 firebase 连接:
当我重定向到 localhost:3000/blogs 时出现此警告,
index.js:1375 Warning: Maximum update depth exceeded. This can happen when a
component calls
setState inside useEffect, but useEffect either doesn't have a dependency
array, or one of the
dependencies changes on every render.
in BlogDashboard (created by Context.Consumer)
in Route (at App.jsx:32)
in Switch (at App.jsx:31)
in div (created by Container)
in Container (at App.jsx:30)
in Route (at App.jsx:27)
in App (at src/index.js:44)
in Router (created by BrowserRouter)
in BrowserRouter (at src/index.js:40)
in ReduxFirestoreProvider (created by ReactReduxFirebaseProvider)
in ReactReduxFirebaseProvider (at src/index.js:39)
in Provider (at src/index.js:38)
在 Index.js 中:
ReactDOM.render(
<Provider store=store>
<ReactReduxFirebaseProvider ...rrfProps> // firebase worked fine
<BrowserRouter>
<ReduxToastr timeOut=2000 preventDuplicates position="bottom-right"
transitionIn="fadeIn" transitionOut="fadeOut" />
<App />
</BrowserRouter>
</ReactReduxFirebaseProvider>
</Provider>,
document.getElementById('root');
);
在 App.jsx 中:
const App = () =>
const auth = useSelector(state => state.firebase.auth, []);
if(!auth.isLoaded && auth.isEmpty) return <LoadingComponent />
return (
<Fragment>
<ModalManager />
<Switch>
<Route exact path='/' component=HomePage/>
</Switch>
<Route path='/(.+)' render=() => (
<Fragment>
<NavBar />
<Container className="main">
<Switch>
<Route exact path='/blogs' component=BlogDashboard />
<Route path='/blogs/:id' component=BlogDetailedPage />
</Switch>
</Container>
</Fragment>
)
/>
</Fragment>
);
在 BlogDashboard.jsx 中:
const BlogDashboard = () =>
const dispatch = useDispatch();
const firestore = useFirestore();
const blogs = useSelector(state => CastToArray(state.firestore.data.blogs) || []);//this worked fine
const moreBlogs = useSelector(state => state.blogs.moreBlogs);
const loading = useSelector(state => state.async.loading);
useEffect(() =>
const getBlogs = async () =>
await dispatch(getPagedBlogs(firestore));
;
if(blogs.length === 0)
getBlogs();
else
, [dispatch, firestore, blogs]);
const handleGetNextBlogs = async () =>
await dispatch(getPagedBlogs(firestore));
;
return (
<Grid>
<Grid.Column width=10>
<BlogList blogs=blogs loading=loading moreBlogs =moreBlogs getNextBlogs=
handleGetNextBlogs />
</Grid.Column>
<Grid.Column width=10>
<Loader active=loading />
</Grid.Column>
</Grid>
);
;
export default BlogDashboard;
在 BlogActions 中:
export const getPagedBlogs = (firestore) =>
async (dispatch, getState) =>
dispatch(StartAction());
const LIMIT = 5;
let nextBlog = null;
const firestore: data: blogs: items = getState();
if (items && Object.keys(items).length >= LIMIT)
let itemsArray = objectToArray(items);
nextBlog = await firestore.collection('blogs').doc(itemsArray[itemsArray.length -
1].id).get();
let query = await firestore.get(
collection: 'blogs',
limit: LIMIT,
where: ['date', '<=', new Date()],
startAfter: nextBlog,
storeAs: 'blogs'
);
if(query.docs.length < LIMIT)
dispatch(type: MORE_BLOGS);
dispatch(FinishAction());
;
在 BlogReducer.js 中:
const initialState =
blogs: [],
moreBlogs: true,
;
export const moreBlogs = (state) =>
return
...state.blogs,
moreBlogs: true
export default createReducer(initialState,
[MORE_BLOGS]: moreBlogs
);
在 BlogList.jsx 中:
const BlogList = (blogs, moreBlogs, getNextBlogs, loading) =>
<Fragment>
blogs && blogs.length !== 0 &&
//Load blogs, using 'react-scroll-infinite'.
<InfiniteScroll pageStart=0 loadMore=getNextBlogs hasMore=
!loading && moreBlogs initialLoad=false>
blogs && blogs.map(blog => (
<BlogListItem key=blog.id blog=blog />
))
</InfiniteScroll>
</Fragment>
export default BlogList;
我明白警告的意思,但对 react hook 没有太多经验。
【问题讨论】:
好像你在渲染方法里面做 setState 。尝试在渲染之外使用 setState 你在哪里设置状态?您提供的代码都没有显示您在哪里使用 Firestore 数据并将其设置为状态。我假设这是在BlogList
内。请告诉我们您在哪里使用setState
@JoshPittman,谢谢你提醒我,我更新了我的帖子。目前我没有在 react 中使用任何 setState 方法,我只是在 blogReducer 中创建了一个 intialState 并且 blogs 是一个空数组。
我使用“const blogs = useSelector(...)”从 Firestore 获取数据,在 BlogDashboard.jsx 中声明,博客列表运行良好
太棒了。请接受下面添加的答案,以帮助遇到类似问题的其他人。
【参考方案1】:
您提供的代码均未显示您在何处使用 Firestore 数据并将其设置为状态。使用 setState 将数据实际存储在您的 react 应用中。
【讨论】:
以上是关于错误:使用 react-hooks 时超出最大更新深度的主要内容,如果未能解决你的问题,请参考以下文章
小部件更新的 RemoteViews 超出最大位图内存使用错误
React Typescript with hooks:最大更新深度超出错误