reactjs - 当我尝试在组件中打印时,redux 状态变为 null
问题描述
我试图在仪表板组件上显示用户的信息,只是简单的:
const mapStateToProps = state => ({
user: state.authReducer.user
})
当我登录或注册时,会调用适当的操作以及 USER_LOADED 操作;所有用户信息都显示在 redux-logger 中,用户对象显示“name”、“id”和其他信息。但是,当我尝试发布用户名时
const Dashboard = ({ user, isAuthenticated }) => {
return (
<div>
{user.name}
</div>
)
}
一切都变为空,包括 isAuthenticated 值(在成功登录后最初设置为 true 。)名称,我得到下面显示的相同错误,其中值变为空。为什么我会尝试列出用户 redux 状态导致它的值变为空?我正在使用 redux-persist (我不知道这是否与它有关)
Dashboard.js(组件):
import React from 'react'
import { connect } from 'react-redux';
const Dashboard = ({ user, isAuthenticated, token }) => {
return (
<div>
{user.name}
</div>
)
}
const mapStateToProps = state => ({
user: state.authReducer.user
})
export default connect(mapStateToProps)(Dashboard);
authReducer.js:
import {
REGISTER_SUCCESS,
REGISTER_FAIL,
USER_LOADED,
AUTH_ERROR,
LOGIN_FAIL,
LOGIN_SUCCESS,
LOGOUT,
ACCOUNT_DELETED
} from '../../actions/types';
const initialState = {
token: localStorage.getItem('token'),
isAuthenticated: null,
loading: true,
user: null
}
const authReducer = (state = initialState, action) => {
const { type, payload } = action;
switch (type) {
case USER_LOADED:
return {
...state,
isAuthenticated: true,
loading: false,
user: payload
}
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:
case LOGOUT:
case ACCOUNT_DELETED:
localStorage.removeItem('token');
return {
...state,
token: null,
isAuthenticated: false,
loading: false
}
default:
return state;
}
}
export default authReducer;
身份验证(操作):
import axios from 'axios';
import { setAlert } from './alert';
import {
REGISTER_SUCCESS,
REGISTER_FAIL,
USER_LOADED,
AUTH_ERROR,
LOGIN_FAIL,
LOGIN_SUCCESS,
LOGOUT,
CLEAR_PROFILE
} from './types';
import setAuthToken from '../utils/setAuthToken';
//LOAD USER
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 (err) {
dispatch({
type: AUTH_ERROR
})
}
}
//Register user
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 (err) {
const errors = err.response.data.errors;
if (errors) {
errors.forEach(error => dispatch(setAlert(error.msg, 'danger')));
}
dispatch({
type: REGISTER_FAIL
})
}
}
//Login user
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 (err) {
const errors = err.response.data.errors;
if (errors) {
errors.forEach(error => dispatch(setAlert(error.msg, 'danger')));
}
dispatch({
type: LOGIN_FAIL
})
}
}
//Logout clear profile
export const logout = () => dispatch => {
dispatch({
type: CLEAR_PROFILE
});
dispatch({
type: LOGOUT
});
}
auth.js(验证用户/获取令牌的路由):
const express = require('express');
const router = express.Router();
const auth = require('../../middleware/auth');
const User = require('../../models/User');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
const config = require('config');
const { check, validationResult } = require('express-validator');
//@route GET api/auth
//@desc Test route
//@access Public
router.get('/', auth, async (req, res) => {
try {
const user = await User.findById(req.user.id).select('-password');
res.json(user);
} catch (err) {
console.error(err.message);
res.status(500).send('Server error');
}
});
//@route POST api/auth
//@desc Authenticate user and get token
//@access Public
router.post('/', [
check('email', 'Please include a valid email').isEmail(),
check('password', 'Password is required').exists()
], async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() })
}
const { email, password } = req.body;
try {
let user = await User.findOne({ email })
if (!user) {
return res.status(400).json({ errors: [{ msg: 'Invalid credentials' }] })
}
const isMatch = await bcrypt.compare(password, user.password);
if (!isMatch) {
return res.status(400).json({ errors: [{ msg: 'Invalid credentials' }] });
}
const payload = {
user: {
id: user.id
}
}
jwt.sign(payload,
config.get('jwtSecret'),
{ expiresIn: 360000 },
(err, token) => {
if (err) throw error;
res.json({ token })
});
} catch (err) {
console.error(err.message);
res.status(500).send('Server error');
}
});
module.exports = router;
解决方案
回答我的根减速器中的persistConfig 对象的白名单中没有我的auth 减速器。数据没有持久化,因为它没有被列为持久化 facepalm
推荐阅读
- web-testing - 解析时 JSON 输入意外结束
- python - 从端点打印出每个 JSON 更新的机器人?
- javascript - 如何在 sdk [Java 脚本] 的测试菜单中显示 jasmin UI
- graphql - 你如何测试 Hasura 授权?
- java - 如何下载和查看每部电影的多个图像文件?
- windows - 文件或程序集名称 'System.Data.SqlServerCe,版本 = 3.5.1.0 - Windows Mobile
- javascript - 如何检查给定的字符串任何西班牙字符是否可用或不使用javascript
- javascript - js 宏任务顺序,两个脚本标签,第一个带有 settimout,仍然在第二个脚本之后
- c# - 部署到 Azure 应用服务时,Asp.net 成员资格提供程序无法连接到本地 SQL Server
- android - 底部 Appbar 始终可见