Javascript TypeError:无法读取属性';名称';在REACTE with redux中使用null
每次我离开一个用户并希望输入另一个用户时,都会发生此错误 当我自动登录时,用户和用户的配置文件都会被清除,所以我不知道每次我更改用户时都会出现什么问题 如果我删除了“Clear_user”,当我登录并再次登录时,新用户仍然拥有上一个用户的信息,直到我刷新页面 重新加载页面后,此错误停止出现 组件/perfil/perfil.jsJavascript TypeError:无法读取属性';名称';在REACTE with redux中使用null,javascript,reactjs,redux,Javascript,Reactjs,Redux,每次我离开一个用户并希望输入另一个用户时,都会发生此错误 当我自动登录时,用户和用户的配置文件都会被清除,所以我不知道每次我更改用户时都会出现什么问题 如果我删除了“Clear_user”,当我登录并再次登录时,新用户仍然拥有上一个用户的信息,直到我刷新页面 重新加载页面后,此错误停止出现 组件/perfil/perfil.js import React, {useEffect, Fragment, useState} from 'react'; import PropTypes from '
import React, {useEffect, Fragment, useState} from 'react';
import PropTypes from 'prop-types';
import {getCurrentProfile, deleteAccount} from '../../actions/profile';
import {connect} from 'react-redux';
import {logout} from '../../actions/auth';
import Spinner from '../layout/Spinner';
import {Link, withRouter} from 'react-router-dom';
import InputSelector from '../util/InputSelector';
import {getUser, editUser} from '../../actions/user';
const Perfil = ({ user:{user,loading}, getUser, editUser, deleteAccount, getCurrentProfile, profile: {profile}, logout,
history }) => {
const [formData, setFormData] = useState({
name: '',
email: '',
avatar:''
});
useEffect(()=>{
getCurrentProfile();
getUser();
setFormData({
name: loading || !user.name ? '' : user.name,
email: loading || !user.email ? '' : user.email,
avatar: loading || !user.avatar ? '' : user.avatar,
});
}, [loading]);
const {
name,
email,
avatar
} = formData;
const hasPerfil = (
<div>hola</div>
);
const hasNotPerfil = (
<div className="text-center">
<p>Aun no has establecido tu perfil, porfavor agrega algo de información.</p>
<Link to="/crear-perfil" className="btn btn-primary my-1"> Crear un perfil</Link>
</div>
);
const onSubmit = async e => {
e.preventDefault();
editUser(formData, history, true);
};
const onChange = e => setFormData({...formData,[e.target.name]: e.target.value});
return loading && profile === null ? <Spinner/> : <Fragment>
<div className="container">
<div className="card user-con-col mb-4">
<div className="card-body">
<div className="d-flex align-items-center justify-content-between">
<h5 className="card-title mb-0"><i className="fas fa-user"></i> Usuario: {user && user.name}</h5>
<button onClick={logout} className="btn btn-info my-1"><i class="fas fa-sign-out-alt"></i> Salir</button>
</div>
</div>
</div>
<div className="card user-con-col mb-4">
<div className="card-body user-con-col-1">
<div className="container">
<div className="row">
<div className="col-md-12 text-center mb-3">
<div className="card">
<div className="card-body">
<div className="Botones">
<Link className="btn btn-primary my-1 mr-1" to="/perfiles"><i class="fas fa-border-all"></i> Más perfiles</Link>
<Link className="btn btn-primary my-1 mr-1" to="/editar-perfil"><i className="fas fa-pen"></i> Editar Perfil</Link>
</div>
</div>
</div>
</div>
{profile !== null ? hasPerfil : hasNotPerfil }
<div className="col-md-12 mb-3">
<div className="card">
<div className="card-body">
<div className="row">
<div className="col-md-3 d-flex align-items-center">
<div className="img">
<img className="img-fluid" src={avatar} />
</div>
</div>
<div className="col-md-9">
<form onSubmit={e => onSubmit(e)}>
<div className="form-group">
<label><i className="fas fa-user"></i> Username</label>
<input
type="text"
name="name"
className="form-control"
placeholder="Edita tu nombre de usuario"
value={name}
onChange={e => onChange(e)}
/>
</div>
<div className="form-group">
<label><i className="fas fa-envelope"></i> Email</label>
<input
type="text"
name="email"
className="form-control"
placeholder="Edita tu email"
value={email}
onChange={e => onChange(e)}
/>
</div>
<div className="form-group" >
<label><i class="fas fa-upload"></i> Imagen De Perfil</label>
<InputSelector/>
</div>
<div className="col-md-12 text-center">
<button className="btn btn-primary btn-block"><i class="fas fa-check"></i> Guardar</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<div className="col-md-12 text-center">
<div className="card">
<div className="card-body">
<div className="Botones">
<button onClick={() => deleteAccount()} className="btn btn-danger my-1 mr-1"><i class="fas fa-sign-out-alt"></i> Borrar cuenta</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</Fragment>;
};
Perfil.propTypes = {
getCurrentProfile: PropTypes.func.isRequired,
logout: PropTypes.func.isRequired,
deleteAccount: PropTypes.func.isRequired,
profile: PropTypes.object.isRequired,
editUser:PropTypes.func.isRequired,
getUser: PropTypes.func.isRequired,
user: PropTypes.object.isRequired
}
const mapStateToProps = state =>({
profile: state.profile,
user: state.user
});
export default connect(mapStateToProps, {getCurrentProfile, getUser, editUser, logout, deleteAccount})(withRouter(Perfil));
actions/user.js
import axios from 'axios';
import {setAlert} from './alert';
import {GET_USER, USER_ERROR} from './types';
//Get current users profile
export const getUser = () => async dispatch => {
try {
const res = await axios.get('/api/users/me');
dispatch({
type: GET_USER,
payload: res.data
});
} catch (err) {
dispatch({
type:USER_ERROR,
payload:{msg: err.response.statusText, status: err.response.status}
});
}
};
//Create or update user
export const editUser = (formData, history, edit = false) => async dispatch => {
try {
const config = {
headers: {
'Content-Type': 'application/json',
}
}
const res = await axios.post('/api/usersedit', formData, config);
dispatch({
type: GET_USER,
payload: res.data
});
dispatch(setAlert(edit ? 'User update' : 'User created', 'success'));
if(!edit){
history.push('/perfil');
}
} catch (err) {
const errors = err.response.data.errors;
if(errors){
errors.forEach(error => dispatch(setAlert(error.msg, 'danger')));
}
dispatch({
type:USER_ERROR,
payload:{msg: err.response.statusText, status: err.response.status}
});
}
};
route
/api/users.js
const express = require('express');
const router = express.Router();
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const config = require('config');
const {check, validationResult} = require('express-validator');
const auth = require('../../middlewares/auth');
const User = require('../../models/User');
//@Route GET api/users
//@desc Test route
//@access Public
router.get('/', (req, res) => res.send('User Route'));
//@Route GET api/users/me
//@desc Get Current User
//@access Private
router.get('/me', auth, async (req, res) => {
try {
const user = await User.findOne({_id: req.user.id});
if(!user){
return res.status(400).json({msg: 'There is no user'});
}
res.json(user);
} catch (err) {
console.error(err.message);
res.status(500).send('Server Error');
}
});
//@Route POST api/users
//@desc Register user
//@access Public
router.post('/', [
check('name', 'Name is required').not().isEmpty(),
check('email', 'Please enter an email').isEmail(),
check('password', 'Please enter a password with 6 or more characters').isLength({min: 6})
], async (req, res) => {
const errors = validationResult(req);
if(!errors.isEmpty()){
return res.status(400).json({errors: errors.array()});
}
const {name, password, email} = req.body;
//See if user exists
try {
let user = await User.findOne({email});
if(user){
return res.status(400).json({errors: [{msg: 'User already exists'}]});
}
user = new User({
name,
email,
avatar:'/uploads/noImg.jpg',
password
});
//Encrypt password
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(password, salt);
await user.save();
//Return jsonwebtoken
const payload = {
user:{
id: user.id
}
};
jwt.sign(payload, config.get('jwtSecret'),{expiresIn: 360000}, (err, token) =>{
if(err) throw err;
res.json({token});
}
);
} catch (err) {
console.error(err.message);
res.status(500).send('Server error');
}
});
module.exports = router;
似乎是因为name对象为空或null,但我找不到解决方案,请帮助。问题将出现在异步函数和加载状态
在存储中加载
最初设置为true。在第一次渲染中,它是否正常。只计算条件的第一部分(加载
),跳过第二部分(!user.name
)。
我认为您需要在等待异步响应时将加载设置回true。
这通常通过以下方式完成:
load
设置为false(您已经这样做了)useffect(()=>{
getCurrentProfile();
//这是一个异步函数,在调用getUser后不会立即加载用户。
//因此,props中的用户不能初始化(仍然设置为null)。
//这就是为什么在接下来的几行(`setFormData`)中会出现该错误。
getUser();
setFormData({
名称:正在加载| |!user.name?'':user.name,
电子邮件:正在加载| |!user.email?'':user.email,
化身:加载| |!user.avatar?'':user.avatar,
});
},[装载];
问题将出现在异步函数和加载状态
在存储中加载
最初设置为true。在第一次渲染中,它是否正常。只计算条件的第一部分(加载
),跳过第二部分(!user.name
)。
我认为您需要在等待异步响应时将加载设置回true。
这通常通过以下方式完成:
load
设置为false(您已经这样做了)useffect(()=>{
getCurrentProfile();
//这是一个异步函数,在调用getUser后不会立即加载用户。
//因此,props中的用户不能初始化(仍然设置为null)。
//这就是为什么在接下来的几行(`setFormData`)中会出现该错误。
getUser();
setFormData({
名称:正在加载| |!user.name?'':user.name,
电子邮件:正在加载| |!user.email?'':user.email,
化身:加载| |!user.avatar?'':user.avatar,
});
},[装载];
const express = require('express');
const router = express.Router();
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const config = require('config');
const {check, validationResult} = require('express-validator');
const auth = require('../../middlewares/auth');
const User = require('../../models/User');
//@Route GET api/users
//@desc Test route
//@access Public
router.get('/', (req, res) => res.send('User Route'));
//@Route GET api/users/me
//@desc Get Current User
//@access Private
router.get('/me', auth, async (req, res) => {
try {
const user = await User.findOne({_id: req.user.id});
if(!user){
return res.status(400).json({msg: 'There is no user'});
}
res.json(user);
} catch (err) {
console.error(err.message);
res.status(500).send('Server Error');
}
});
//@Route POST api/users
//@desc Register user
//@access Public
router.post('/', [
check('name', 'Name is required').not().isEmpty(),
check('email', 'Please enter an email').isEmail(),
check('password', 'Please enter a password with 6 or more characters').isLength({min: 6})
], async (req, res) => {
const errors = validationResult(req);
if(!errors.isEmpty()){
return res.status(400).json({errors: errors.array()});
}
const {name, password, email} = req.body;
//See if user exists
try {
let user = await User.findOne({email});
if(user){
return res.status(400).json({errors: [{msg: 'User already exists'}]});
}
user = new User({
name,
email,
avatar:'/uploads/noImg.jpg',
password
});
//Encrypt password
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(password, salt);
await user.save();
//Return jsonwebtoken
const payload = {
user:{
id: user.id
}
};
jwt.sign(payload, config.get('jwtSecret'),{expiresIn: 360000}, (err, token) =>{
if(err) throw err;
res.json({token});
}
);
} catch (err) {
console.error(err.message);
res.status(500).send('Server error');
}
});
module.exports = router;