首页 > 解决方案 > 使用时多次调用useEffect或 history.push()

问题描述

我遇到了一个小问题,因为当他保存在 localStorage 中时,我无法将登录的用户重定向到应用程序。两个 react-router-dom 函数都返回Maximum update depth exceeded.,但为什么呢?

import React, { useState, useEffect } from 'react'
import { authLocalUser } from 'actions/userActions'
import { connect } from 'react-redux'
import PropTypes from 'prop-types'
import { useHistory } from 'react-router-dom'

// components
import SigninForm from 'components/organisms/Forms/SigninForm'
import SignupForm from 'components/organisms/Forms/SignupForm'

// styles
import { Content, Footer, Wrapper, Header } from './styles'

const Landing = ({ fetchLocalStorage, userID }) => {
    const [isModalOpen, setModalOpen] = useState(false)
    const history = useHistory()

    useEffect(async () => {
        const userData = await JSON.parse(
            localStorage.getItem('userData'),
        )
        await fetchLocalStorage(userData)
    }, [])

    return (
        <>
            {userID && history.push('/app')}
            <Content>
                {isModalOpen && (
                    <div
                        style={{
                            zIndex: 300,
                            left: 0,
                            position: 'absolute',
                            width: '100%',
                            height: '100%',
                            background: 'rgb(0,0,0,0.5)',
                        }}
                    >
                        <SignupForm setModalOpen={setModalOpen} />
                    </div>
                )}
                <Wrapper w='60'>
                    <Header>
                        <h1>ChatterApp</h1>
                        <h3>
                            Chat with your friend in real-time using
                            magic of Web Sockets! Join our community
                            today!
                        </h3>
                    </Header>
                </Wrapper>
                <Wrapper signin w='40'>
                    <SigninForm setModalOpen={setModalOpen} />
                </Wrapper>
            </Content>
            <Footer>
                <Content>
                    <h3>ChatterApp</h3>
                    <h5>Dawid Szemborowski</h5>
                </Content>
            </Footer>
        </>
    )
}

const mapStateToProps = ({ user }) => ({
    userID: user._id,
})

const mapDispatchToProps = dispatch => ({
    fetchLocalStorage: localStorage =>
        dispatch(authLocalUser(localStorage)),
})

export default connect(mapStateToProps, mapDispatchToProps)(Landing)

Landing.propTypes = {
    userID: PropTypes.string,
    fetchLocalStorage: PropTypes.func.isRequired,
}

Landing.defaultProps = {
    userID: undefined,
}

我尝试在没有 async/await 的情况下调用此函数,我尝试提供 userID 和 localStorage 作为 componentDidUpdate 的最后一个参数。我的问题在哪里?我得到的错误显示问题出在 Lifecycle 组件内部

index.js:1 The above error occurred in the <Lifecycle> component:

    at Lifecycle (http://localhost:3000/static/js/vendors~main.chunk.js:47761:29)
    at Redirect (http://localhost:3000/static/js/vendors~main.chunk.js:47862:28)

authLocal用户代码

export const authLocalUser = userData => {
    return {
        type: 'FETCH_LOCAL_STORAGE',
        payload: userData,
    }
}

标签: javascriptreactjsreact-router-dom

解决方案


你可能想做这样的事情。

替换{userID && history.push('/app')}为:

useEffect(() => {
  if(userId) {
    history.push('/app')
  }
}, [userId])

作为建议,您的第一个useEffect电话可以更正。如果你做出callbackofuseEffect因为async它会返回一个不是useEffect工作方式的承诺。它返回一个cleanup function.

改为使用IIFE

    useEffect(() => {
    
      (async () => {
        const userData = JSON.parse(localStorage.getItem('userData'))
        await fetchLocalStorage(userData)
      })()
    
    }, [])

推荐阅读