控制台中未定义的 redux 值

Undefined redux values in console

我正在尝试检查用户是否已登录或未登录 Register.js 组件,但我在其中获得未定义的身份验证状态值。如果您能找到我做错的地方,请调查一下。我已经尝试做了很多改变,但我还是无法做到正确。

感谢大家的帮助。

忽略上下文文件

App.js

import { useEffect } from "react";
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";

import "./App.css";

import { Navbar } from "./components/layout/Navbar";
import { Home } from "./components/pages/Home";
import { MyList } from "./components/favorites/MyList";
import Register from "./components/auth/Register";
import Login from "./components/auth/Login";

import { Provider } from "react-redux";
import store from "./store";

import { loadUser } from "./actions/auth";


import { setAuthToken } from "./utils/setAuthToken";

if (localStorage.token) {
    setAuthToken(localStorage.token);
}

function App() {
    useEffect(() => {
        store.dispatch(loadUser());
    }, []);
    return (

        <Provider store={store}>
            <>
                <div>
                    <Navbar />
                    <Routes>
                        <Route path='/' element={<Home />} />
                        <Route path='/mylist' element={<MyList />} />
                        <Route path='/signin' element={<Login />} />
                        <Route path='/signup' element={<Register />} />
                    </Routes>
                </div>
            </>
        </Provider>

    );
}

export default App;


Register.js

import React, { useContext, useEffect, useState } from "react";
import { Link, Navigate, useNavigate } from "react-router-dom";
import { connect } from "react-redux";

import { register } from "../../actions/auth";
import axios from "axios";

const Register = ({ register, isAuthenticated, history, location, auth }) => {
    const navigate = useNavigate();
    const [user, setUser] = useState({
        name: "",
        email: "",
        password: "",
        password2: "",
    });

    const { name, email, password, password2 } = user;

    const onFormDataChange = (e) => {
        setUser({
            ...user,
            [e.target.name]: e.target.value,
        });
    };

    const onFormSubmit = async (e) => {
        e.preventDefault();
        register({ name, email, password });
    };

    console.log(auth);
    console.log(isAuthenticated);
    return (
        <div>
            <h1>Sign Up</h1>
            <form action='' onSubmit={onFormSubmit}>
                <div className='form-group'>
                    <label htmlFor='name'>Name</label>
                    <input
                        type='text'
                        name='name'
                        value={name}
                        onChange={onFormDataChange}
                    />
                </div>
                <div className='form-group'>
                    <label htmlFor='email'>Email</label>
                    <input
                        type='email'
                        name='email'
                        value={email}
                        onChange={onFormDataChange}
                    />
                </div>
                <div className='form-group'>
                    <label htmlFor='password'>Password</label>
                    <input
                        type='password'
                        name='password'
                        value={password}
                        onChange={onFormDataChange}
                    />
                </div>
                <div className='form-group'>
                    <label htmlFor='password2'>Password</label>
                    <input
                        type='password'
                        name='password2'
                        value={password2}
                        onChange={onFormDataChange}
                    />
                </div>
                <input type='submit' value='Signup' />
                <p>
                    Already have an account? <Link to='/signin'>Sign In</Link>
                </p>
            </form>
        </div>
    );
};
const mapStateToProps = (state) => {
    const { isAuthenticated } = state.auth.isAuthenticated;
    const { auth } = state.auth;

    return {
        isAuthenticated,
    };
};
export default connect(mapStateToProps, { register })(Register);

index.js

import { combineReducers } from "redux";
import auth from "./auth";
export default combineReducers({
    auth,
});

/auth/types.js

export const REGISTER_SUCCESS = "REGISTER_SUCCESS";
export const REGISTER_FAIL = "REGISTER_FAIL";
export const USER_LOADED = "USER_LOADED";
export const AUTH_ERROR = "AUTH_ERROR";
export const LOGIN_SUCCESS = "LOGIN_SUCCESS";
export const LOGIN_FAIL = "LOGIN_FAIL";
export const LOGOUT = "LOGOUT";
export const CLEAR_ERRORS = "CLEAR_ERRORS";

actions/auth.js

import axios from "axios";
import {
    REGISTER_SUCCESS,
    REGISTER_FAIL,
    USER_LOADED,
    AUTH_ERROR,
    LOGIN_SUCCESS,
    LOGIN_FAIL,
} from "./types";

import { setAuthToken } from "../utils/setAuthToken";

export const loadUser = () => async (dispatch) => {
    if (localStorage.token) {
        setAuthToken(localStorage.token);
    }

    try {
        const res = await axios.get("/api/auth");
        dispatch({
            type: USER_LOADED,
            payload: res.data,
        });
    } catch (error) {
        dispatch({
            type: AUTH_ERROR,
        });
    }
};

export const register =
    ({ name, email, password }) =>
    async (dispatch) => {
        const config = {
            headers: {
                "Content-Type": "application/json",
            },
        };

        const body = JSON.stringify({ name, email, password });

        try {
            const res = await axios.post("/api/users", body, config);
            dispatch({
                type: REGISTER_SUCCESS,
                payload: res.data,
            });
            dispatch(loadUser());
        } catch (error) {
            dispatch({
                type: REGISTER_FAIL,
            });
        }
    };

export const login = (email, password) => async (dispatch) => {
    const config = {
        headers: {
            "Content-Type": "application/json",
        },
    };

    const body = JSON.stringify({ email, password });

    try {
        const res = await axios.post("/api/auth", body, config);
        dispatch({
            type: LOGIN_SUCCESS,
            payload: res.data,
        });
        dispatch(loadUser());
    } catch (error) {
        dispatch({
            type: LOGIN_FAIL,
        });
    }
};

reducers/auth.js

/* eslint-disable default-case */
/* eslint-disable import/no-anonymous-default-export */
import {
    REGISTER_SUCCESS,
    REGISTER_FAIL,
    USER_LOADED,
    AUTH_ERROR,
    LOGIN_SUCCESS,
    LOGIN_FAIL,
} from "../actions/types";

const initalState = {
    token: localStorage.getItem("token"),
    isAuthenticated: false,
    loading: true,
    user: null,
};

export default function (state = initalState, action) {
    const { type, payload } = action;

    switch (type) {
        case USER_LOADED:
            return {
                ...state,
                user: payload,
                isAuthenticated: true,
                loading: false,
            };
        case REGISTER_SUCCESS:
        case LOGIN_SUCCESS:
            localStorage.setItem("token", payload.token);
            return {
                ...state,
                ...payload,
                isAuthenticated: true,
                loading: false,
            };
        case REGISTER_FAIL:
        case AUTH_ERROR:
        case LOGIN_FAIL:
            localStorage.removeItem("token");
            return {
                ...state,
                token: null,
                isAuthenticated: false,
                loading: true,
            };

        default:
            return state;
    }
}

store.js

import { createStore, applyMiddleware } from "redux";
import { composeWithDevTools } from "redux-devtools-extension";
import thunk from "redux-thunk";
import rootReducer from "./reducers";

const intialState = {};

const middleware = [thunk];

const store = createStore(
    rootReducer,
    intialState,
    composeWithDevTools(applyMiddleware(...middleware))
);

export default store;

我可能是错的,但在你 Register.js 中,在 mapStateToProps 中,你做了以下事情:

const { isAuthenticated } = state.auth.isAuthenticated;
const { auth } = state.auth;

这似乎是不正确的,除非你的州有以下结构:

{
 auth: {
   isAuthenticated: { isAuthenticated: *value here* },
   auth: *value here*
 }
}

我认为,这里可能是错误的,你应该按照以下方式解构值:

const { isAuthenticated } = state.auth;
const { auth } = state;