无法解构'user'的'undefined'或'null'属性

时间:2019-10-05 15:51:05

标签: javascript reactjs mongodb redux

使用redux检索用户信息时出错。 我想从数据库中获取用户信息(头像的名称,密码和地址),然后进行编辑。

我正在使用nodejs,express,react,redux和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

当我写用户:{user,loading}时,当我放置已经完成的另一个代码时,总是会出现问题,但是每当我写该页面失败时,问题就会出现。

2 个答案:

答案 0 :(得分:0)

cannot destructure property user of 'undefined' or 'null'。这意味着您第一次使用user data null or undefined来从服务器获取数据时。服务器的API调用是异步的。第二次,您会得到user data

我看到您从服务器上以res.data的身份使用redux作为道具。我不确定res.data的结构是什么?因此,在组件中,您应该像这样:

const EditUser = ({
    user, 
    getCurrentUser, 
    history
}) => {
    if (user) {
        const { loading, ... } = user // Get another key in user object
    }
...
...
...

答案 1 :(得分:0)

// 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;