useReducer useContext 不调用 reducer

时间:2021-03-25 22:19:16

标签: node.js reactjs express

我正在尝试使用 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

任何想法如何触发减速器动作?几天以来,我一直在为此苦苦挣扎。

您好,

洛伦兹

0 个答案:

没有答案