问题
Error retrieving user information with redux. I want to get the user information (name, password and address of the avatar from the db) and then edit it.
I'm using nodejs, express, react, redux and jwt.
Actions/user.js
import axios from 'axios';
import {setAlert} from './alert';
import {GET_USER, USER_ERROR} from './types';
//Get current users profile
export const getCurrentUser = () => 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}
});
}
};
Reducers/user.js
import {GET_USER, USER_ERROR, CLEAR_USER} from '../actions/types';
const initialState = {
user: null,
users: [],
loading: true,
error: {}
}
export default function(state = initialState, action) {
const {type, payload} = action;
switch(type){
case GET_USER:
return{
...state,
loading:false,
user:payload
};
case USER_ERROR:
return{
...state,
error:payload,
loading: false
};
default:
return state;
}
}
Components/edituser/EditUser.js
import React, {useState, Fragment, useEffect} from 'react';
import PropTypes from 'prop-types';
import {connect} from 'react-redux';
import {getCurrentUser} from '../../actions/user';
import {Link, withRouter} from 'react-router-dom';
import Alert from '../layout/Alert';
import InputSelector from '../util/InputSelector';
const EditUser = ({
user:{user,loading},
getCurrentUser,
history}) => {
const [formData, setFormData] = useState({
name: '',
email: '',
password: ''
});
useEffect(()=>{
getCurrentUser();
});
return (
<Fragment>
<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={'/uploads/noImg.jpg'} />
</div>
</div>
<div className="col-md-9">
<form>
<div className="form-group">
<label><i className="fas fa-user"></i> Username</label>
<input
type="text"
name="skills"
className="form-control"
placeholder="Edita tu nombre de usuario"
/>
</div>
<div className="form-group">
<label><i className="fas fa-envelope"></i> Email</label>
<input
type="text"
name="skills"
className="form-control"
placeholder="Edita tu email"
/>
</div>
<div className="form-group">
<label><i className="fas fa-key"></i> Contraseña</label>
<input
type="text"
name="skills"
className="form-control"
placeholder="Edita tu nombre de contraseña"
/>
</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>
</Fragment>
);
};
EditUser.propTypes = {
getCurrentUser: PropTypes.func.isRequired,
user: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
user: state.user
});
export default connect(mapStateToProps, {getCurrentUser})
(withRouter(EditUser));
https://imgur.com/xLzAu1A
The problem always happens when I write user: {user, loading}, when I put another code that I already have done it works fine, but whenever I write that the page fails.
回答1:
cannot destructure property user of 'undefined' or 'null'
. This mean user data
null or undefined
at the first time when you use fetch data from server. The API call to server is async. At the second time, you will got user data
.
I see the user that you take as props with redux is res.data
from server. I'm uncertain structure of res.data
what is? So in component, you should be do like:
const EditUser = ({
user,
getCurrentUser,
history
}) => {
if (user) {
const { loading, ... } = user // Get another key in user object
}
...
...
...
回答2:
// When you try to destructure action object by default for the first time it would not have contain any keys defined by us, However it would contain default keys that redux provides. While Destructring this object would result in undefined or null because there is no matching key. So destructure inside the condition where it matches.
export const addBug = desc => ({
type: actions.BUG_ADDED,
payload: {
description: desc
}
});
// i am dispatching the action in the below line
store.dispatch(addBug('button is not clickable'));
// below i have destructred the action.payload object
let lastId = 0;
function reducer(state = [], action) {
console.log(action);
switch(action.type) {
case actions.BUG_ADDED:
const {description} = action.payload;
return [
...state,
{
id: ++lastId,
description,
resolved: false,
},
];
case actions.BUG_REMOVED:
return state.filter(bug => action.payload.id !== bug.id);
default: return state;
}
}
export default reducer;
来源:https://stackoverflow.com/questions/58249931/cannot-destructure-property-user-of-undefined-or-null