每次我离开一个用户并想输入另一个用户时,都会发生该错误。
当我自动登录时,该用户和该用户的个人资料都会被清除,因此我不知道是什么问题导致每次我更改用户时都会发生。
如果删除“ Clear_user”,则在登录并再次登录时,新用户仍然拥有上一个用户的信息,直到刷新页面为止。
此错误在我重新加载页面后停止。
components / perfil / Perfil.js
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));
reducer / user.js
import {GET_USER, USER_ERROR, CLEAR_USER, UPDATE_USER} from '../actions/types';
const initialState = {
user: null,
loading: true,
error: {}
}
export default function(state = initialState, action) {
const {type, payload} = action;
switch(type){
case GET_USER:
case UPDATE_USER:
return{
...state,
loading:false,
user:payload
};
case USER_ERROR:
return{
...state,
error:payload,
loading: false
};
case CLEAR_USER:
return {
...state,
loading:false,
user:null
}
default:
return state;
}
}
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;
似乎是因为名称对象为空或null,但找不到解决方案,请帮忙。
答案 0 :(得分:0)
问题将出在异步函数和加载状态。
商店中的 loading
最初设置为true。在第一个渲染中就可以了。仅评估条件的第一部分(loading
),第二部分(!user.name
)被跳过。
我认为您在等待异步响应时需要将loading
设置为true。这通常是通过以下方式完成的:
loading
设置为true(缺少此部分-为此您需要其他操作和操作类型)。 loading
设置为false(您已经这样做)。 useEffect(()=>{
getCurrentProfile();
// this is asynchronous function, the user is not loaded right after you call getUser.
// Hence the user from props could be not initalized (still set to null).
// This is why you are getting that error in the next lines (`setFormData`).
getUser();
setFormData({
name: loading || !user.name ? '' : user.name,
email: loading || !user.email ? '' : user.email,
avatar: loading || !user.avatar ? '' : user.avatar,
});
}, [loading]);