useEffect钩子问题,使用redux从后端到前端获取数据



你好,我是新来的编程,我已经学会使用MERN来注册,我没有后端问题,但当我试图使用redux时,我在前端有这个问题

输入图片描述

这是SignInScreen.js 的代码
import React, { useEffect, useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { Link, useLocation, useNavigate } from 'react-router-dom'
import { login } from '../actions/userAction'
export const SignInScreen = (props, history) => {
const navigate = useNavigate
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const submitHandler = (e) => {
e.preventDefault()
dispatch(login(email, password))
}
const { search } = useLocation()
const redirectInUrl = new URLSearchParams(search).get('redirect')
const redirect = redirectInUrl ? redirectInUrl : '/'
const userlogin = useSelector((state) => state.userlogin)
const { userInfo, loading, error } = userlogin
const dispatch = useDispatch()
useEffect(() => {
if (userInfo) {
navigate(redirect)
}
}, [navigate, userInfo, redirect])

我不知道代码有什么问题,但我知道它与redux存储连接,其中有reducer,action和constant.这是redux store.js

import { createStore, combineReducers, applyMiddleware, compose } from 'redux'
import thunk from 'redux-thunk'
import {
userLoginReducer,
} from './reducers/userReducer'

const userInfo = localStorage.getItem('userInfo')
? JSON.parse(localStorage.getItem('userInfo'))
: null
const initialState = {
userLogin: { userInfo },
}
const reducer = combineReducers({
userLogin: userLoginReducer,
})
const middleware = [thunk]
const store = createStore(
reducer,
initialState,
compose(applyMiddleware(...middleware))
)
export default store

用于常量

export const USER_LOGIN_REQUEST = 'USER_LOGIN_REQUEST'
export const USER_LOGIN_SUCCESS = 'USER_LOGIN_SUCCESS'
export const USER_LOGIN_FAIL = 'USER_LOGIN_FAIL'
export const USER_LOGOUT = 'USER_LOGOUT'

这是userReducer.js

import {
USER_LOGIN_REQUEST,
USER_LOGIN_SUCCESS,
USER_LOGIN_FAIL,
USER_LOGOUT,
} from '../constants/userConstant'
function userLoginReducer(state = {}, action) {
switch (action.type) {
case USER_LOGIN_REQUEST:
return { loading: true }
case USER_LOGIN_SUCCESS:
return { loading: false, userInfo: action.payload }
case USER_LOGIN_FAIL:
return { loading: false, error: action.payload }
case USER_LOGOUT:
return {}
default:
return state
}
}
export userLoginReducer

最后是user.js

import Axios from 'axios'
import {
USER_LOGIN_REQUEST,
USER_LOGIN_SUCCESS,
USER_LOGIN_FAIL,
} from '../constants/userConstant'

const login = (email, password) => async (dispatch) => {
try {
dispatch({ type: USER_LOGIN_REQUEST })
const config = { headers: { 'Content-Type': 'application/json' } }
const { data } = await Axios.post(
'/api/users/login',
{ email, password },
config
)
dispatch({ type: USER_LOGIN_SUCCESS, payload: data })
localStorage.setItem('userInfo', JSON.stringify(data))
} catch (error) {
dispatch({
type: USER_LOGIN_FAIL,
payload:
error.response && error.response.data.message
? error.response.data.message
: error.message,
})
}
}
export login

我只是想让数据进入userInfo,但它不认识他们,说这是一个TypeError..我希望你能帮助我这个..我使用redux最新版本

问题在userLoginReducer。每个reducer都应该返回一个完整的store的新副本。

如果只返回更改,则返回的对象将替换整个状态。例如以下代码:

switch (action.type) {
case USER_LOGIN_REQUEST:
return { loading: true };
}

状态{ userLogin: { userInfo } }将被{ loading: true }取代。那么状态中就没有userLogin了。这就是为什么你会得到错误。

要克服这个问题,在返回对象中扩展前一个状态(对于所有操作):

switch (action.type) {
case USER_LOGIN_REQUEST:
return { ....state, loading: true }; // ...state copies exist state to the new copy of state
}

注意:为了方便以后解决类似的bug,我建议使用redux devtools扩展。这是一个很好的扩展,用于调试和查看redux存储的变化。

我已经尝试过了,但仍然无法解决我的问题,这是我的signinScreen的其余部分,js

import React, { useEffect, useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { Link, useLocation, useNavigate } from 'react-router-dom'
import { login } from '../actions/userAction'
export const SignInScreen = (props, history) => {
const navigate = useNavigate
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const submitHandler = (e) => {
e.preventDefault()
dispatch(login(email, password))
}
const { search } = useLocation()
const redirectInUrl = new URLSearchParams(search).get('redirect')
const redirect = redirectInUrl ? redirectInUrl : '/'
const userlogin = useSelector((state) => state.userlogin)
const { userInfo, loading, error } = userlogin
const dispatch = useDispatch()
useEffect(() => {
if (userInfo) {
navigate(redirect)
}
}, [navigate, userInfo, redirect])
return (
<Container className="small-container">
<h1 className="my-3">Sign In</h1>
<Form onSubmit={submitHandler}>
<Form.Group className="mb-3" controlId="email">
<Form.Label>Email</Form.Label>
<Form.Control
type="email"
required
onChange={(e) => setEmail(e.target.value)}
/>
</Form.Group>
<Form.Group className="mb-3" controlId="password">
<Form.Label>Password</Form.Label>
<Form.Control
type="password"
required
onChange={(e) => setPassword(e.target.value)}
/>
</Form.Group>
<div className="mb-3">
<Button type="submit">Sign In</Button>
</div>
<div className="mb-3">
New Customer?{' '}
<Link to={`/signup?redirect=${redirect}`}>Create new account</Link>
</div>
</Form>
</Container>
)
}

仍然显示和以前一样的错误,我不知道该怎么解决

相关内容

  • 没有找到相关文章

最新更新