Ошибка: максимальная глубина обновления превышена при использовании реакционных хуков - PullRequest
2 голосов
/ 02 декабря 2019

Я пытаюсь изменить весь свой исходный код с использования «реагировать с редуксом» на «перехватывать с редуксом» и подключать его с помощью 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;

Я понимаю, что пытается сказать предупреждение, но не так много опыта с реагирующим крючком.

1 Ответ

2 голосов
/ 02 декабря 2019

Ни один из представленных вами кодов не показывает, где вы используете данные своего пожарного депо и устанавливаете их в состояние. Используйте setState для фактического хранения данных в вашем приложении реакции.

...