我正在尝试使用 useReducer 和 useContext 进行身份验证登录:
减速器:
export const state = { loading: false } // initial state
export function userSigninReducer(state, action) {
switch (action.type) {
case USER_SIGNIN_REQUEST:
return { loading: true }
case USER_SIGNIN_SUCCESS:
return { loading: false, userInfo: action.payload }
case USER_SIGNIN_FAIL:
return { loading: false, error: action.payload }
default:
return state
}
}
动作:
import Axios from 'axios'
import Cookie from 'js-cookie'
import {
USER_SIGNIN_FAIL,
USER_SIGNIN_REQUEST,
USER_SIGNIN_SUCCESS,
} from '../constants/userConstants'
export const signin = (email, password) => async dispatch => {
dispatch({ type: USER_SIGNIN_REQUEST, payload: { email, password } })
try {
const { data } = await Axios.post('/api/users/signin', {
email,
password,
})
dispatch({ type: USER_SIGNIN_SUCCESS, payload: data })
Cookie.set('userInfo', JSON.stringify(data))
} catch (error) {
dispatch({ type: USER_SIGNIN_FAIL, payload: error.message })
console.log('error')
}
}
我通过 context.provider 将调度和初始状态传递给所有组件
import React, { useReducer } from 'react'
import { userSigninReducer, state } from './userReducer'
const AuthStateContext = React.createContext()
const AuthDispatchContext = React.createContext()
export function useAuthState() {
const context = React.useContext(AuthStateContext)
if (context === undefined) {
throw new Error('useAuthState must be used within a AuthProvider')
}
return context
}
export function useAuthDispatch() {
const context = React.useContext(AuthDispatchContext)
if (context === undefined) {
throw new Error('useAuthDispatch must be used within a AuthProvider')
}
return context
}
export const AuthProvider = ({ children }) => {
const [user, dispatch] = useReducer(userSigninReducer, state)
return (
<AuthStateContext.Provider value={user}>
<AuthDispatchContext.Provider value={dispatch}>
{children}
</AuthDispatchContext.Provider>
</AuthStateContext.Provider>
)
}
在 SigninPage 上,我可以读取初始状态对象,但调用 reducer 类型(调用 submitHandler)没有结果。
import React, { useState, useContext } from 'react'
import { Link } from 'react-router-dom'
import { signin } from './context/actions/userActions'
import { useAuthState, useAuthDispatch } from './context/context'
function SignInScreen() {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const dispatch = useAuthDispatch()
const user = useAuthState()
const { loading, userInfo, error } = user
const submitHandler = e => {
e.preventDefault()
dispatch(signin(email, password))
console.log('email', email, 'password', password)
}
return (
[...]
<li>
{loading && <div>Loading...</div>}
{error && <div>{error}</div>}
</li>
<li>
<label htmlFor='email'>Email</label>
<input
type='email'
name='email'
id='email'
onChange={e => setEmail(e.target.value)}
value={email}
/>
</li>
<li>
<label htmlFor='password'>Password</label>
<input
type='password'
name='password'
id='password'
onChange={e => setPassword(e.target.value)}
value={password}
/>
</li>
<li>
<button onClick={submitHandler} className='button signin'>
SignIn
</button>
</li>
<li>New to ReactShop?</li>
<li>
<Link to='/register'>
<button className='button register'>
Create your ReactShop account
</button>
</Link>
</li>
</ul>
</div>
)
}
export default SignInScreen
任何想法如何触发减速器动作?几天以来,我一直在为此苦苦挣扎。
您好,
洛伦兹