TypeError:无法读取null

时间:2019-12-09 14:50:10

标签: javascript reactjs react-redux react-router mern

我试图同时显示化身和用户名,但是遇到此错误,我不知道自己在做什么错,我尝试声明一个 user 变量,以查看是否是原因,它不起作用,但这似乎不是问题。

  

TypeError:无法读取null的属性“头像”

我的后端路线

/**
 * @route GET api/profile/all
 * @desc Get all profile
 * @access Public
 */
router.get('/all', (req, res) => {
  const errors = {};

  Profile.find()
    .populate('user', ['name', 'avatar'])
    .then((profiles) => {
      if (!profiles) {
        errors.noprofile = 'There are no profiles';
        return res.status(404).json(errors);
      }
      res.json(profiles);
    })
    .catch((err) => res.status(404).json({
      profile: 'There are no profile',
    }));
});

我的个人资料操作

import axios from 'axios';

import {
  GET_PROFILE,
  GET_PROFILES,
  PROFILE_LOADING,
  CLEAR_CURRENT_PROFILE,
  GET_ERRORS,
  SET_CURRENT_USER
} from './types';

// Get current profile
export const getCurrentProfile = () => dispatch => {
  dispatch(setProfileLoading());
  axios
    .get('/api/profile')
    .then(res =>
      dispatch({
        type: GET_PROFILE,
        payload: res.data
      })
    )
    .catch(err =>
      dispatch({
        type: GET_PROFILE,
        payload: {}
      })
    );
};


// Get all profiles
export const getProfiles = () => dispatch => {
  dispatch(setProfileLoading());
  axios
    .get('/api/profile/all')
    .then(res =>
      dispatch({
        type: GET_PROFILES,
        payload: res.data
      })
    )
    .catch(err =>
      dispatch({
        type: GET_PROFILES,
        payload: null
      })
    );
};

我的ProfileItem组件

import React, { Component } from "react";
import PropTypes from "prop-types";
import { Link } from "react-router-dom";
import isEmpty from "../../validation/is-empty";

class ProfileItem extends Component {
  render() {
    const { profile } = this.props;

    return (
      <div className="card card-body bg-light mb-3">
        <div className="row">
          <div className="col-2">
            <img src={profile.user.avatar} alt="" className="rounded-circle" />
          </div>
          <div className="col-lg-6 col-md-4 col-8">
            <h3>{profile.user.name}</h3>
            <p>
              {profile.status}{" "}
              {isEmpty(profile.company) ? null : (
                <span>at {profile.company}</span>
              )}
            </p>
            <p>
              {isEmpty(profile.location) ? null : (
                <span>{profile.location}</span>
              )}
            </p>
            <Link to={`/profile/${profile.handle}`} className="btn btn-info ">
              View Profile
            </Link>
          </div>
          <div className="col-md-4 d-none d-md-block">
            <h4>Skill Set</h4>
            <ul className="list-group">
              {profile.skills.slice(0, 4).map((skill, index) => (
                <li key={index} className="list-group-item">
                  <i className="fa fa-check pr-1" />
                  {skill}
                </li>
              ))}
            </ul>
          </div>
        </div>
      </div>
    );
  }
}

ProfileItem.propTypes = {
  profile: PropTypes.object.isRequired
};

export default ProfileItem;

我的个人资料组件

import React, { Component } from "react";
import { connect } from "react-redux";
import PropTypes from "prop-types";
import Spinner from "../common/Spinner";
import { getProfiles } from "../../actions/profileActions";
import ProfileItem from "./ProfileItem";

class Profiles extends Component {
  componentDidMount() {
    this.props.getProfiles();
  }

  render() {
    const { profiles, loading } = this.props.profile;
    let profileItems;

    if (profiles === null || loading) {
      profileItems = <Spinner />;
    } else {
      if (profiles.length > 0) {
        profileItems = profiles.map(profile => (
          <ProfileItem key={profile._id} profile={profile} />
        ));
      } else {
        profileItems = <h4>No profile found...</h4>;
      }
    }


    return (
      <div className="profiles">
        <div className="container">
          <div className="row">
            <div className="col-md-12">
              <h1 className="display-4 text-center"> Developer Profile</h1>
              <p className="lead text-center">
                {" "}
                Browse and connect with other developers
              </p>
              {profileItems}
            </div>
          </div>
        </div>
      </div>
    );
  }
}

Profiles.propTypes = {
  getProfiles: PropTypes.func.isRequired,
  profile: PropTypes.object.isRequired
};

const mapStateToProps = state => ({
  profile: state.profile
});

export default connect(mapStateToProps, { getProfiles })(Profiles);

错误消息

ProfileItem.js:14 Uncaught TypeError: Cannot read property 'avatar' of null
    at ProfileItem.render (ProfileItem.js:14)
    at finishClassComponent (react-dom.development.js:18483)
    at updateClassComponent (react-dom.development.js:18438)
    at beginWork$1 (react-dom.development.js:20173)
    at HTMLUnknownElement.callCallback (react-dom.development.js:337)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:386)
    at invokeGuardedCallback (react-dom.development.js:439)
    at beginWork$$1 (react-dom.development.js:25768)
    at performUnitOfWork (react-dom.development.js:24682)
    at workLoopSync (react-dom.development.js:24658)
    at performSyncWorkOnRoot (react-dom.development.js:24247)
    at react-dom.development.js:12285
    at unstable_runWithPriority (scheduler.development.js:701)
    at runWithPriority$2 (react-dom.development.js:12231)
    at flushSyncCallbackQueueImpl (react-dom.development.js:12280)
    at flushSyncCallbackQueue (react-dom.development.js:12268)
    at batchedUpdates$1 (react-dom.development.js:24368)
    at Object.notify (Subscription.js:23)
    at Subscription.notifyNestedSubs (Subscription.js:65)
    at Subscription.handleChangeWrapper (Subscription.js:70)
    at Object.dispatch (redux.js:221)
    at e (<anonymous>:1:40553)
    at index.js:11
    at dispatch (redux.js:638)
    at profileActions.js:128
render @ ProfileItem.js:14
finishClassComponent @ react-dom.development.js:18483
updateClassComponent @ react-dom.development.js:18438
beginWork$1 @ react-dom.development.js:20173
callCallback @ react-dom.development.js:337
invokeGuardedCallbackDev @ react-dom.development.js:386
invokeGuardedCallback @ react-dom.development.js:439
beginWork$$1 @ react-dom.development.js:25768
performUnitOfWork @ react-dom.development.js:24682
workLoopSync @ react-dom.development.js:24658
performSyncWorkOnRoot @ react-dom.development.js:24247
(anonymous) @ react-dom.development.js:12285
unstable_runWithPriority @ scheduler.development.js:701
runWithPriority$2 @ react-dom.development.js:12231
flushSyncCallbackQueueImpl @ react-dom.development.js:12280
flushSyncCallbackQueue @ react-dom.development.js:12268
batchedUpdates$1 @ react-dom.development.js:24368
notify @ Subscription.js:23
notifyNestedSubs @ Subscription.js:65
handleChangeWrapper @ Subscription.js:70
dispatch @ redux.js:221
e @ VM3293:1
(anonymous) @ index.js:11
dispatch @ redux.js:638
(anonymous) @ profileActions.js:128
Promise.then (async)
(anonymous) @ profileActions.js:128
(anonymous) @ index.js:8
(anonymous) @ redux.js:476
componentDidMount @ Profiles.js:10
commitLifeCycles @ react-dom.development.js:22079
commitLayoutEffects @ react-dom.development.js:25331
callCallback @ react-dom.development.js:337
invokeGuardedCallbackDev @ react-dom.development.js:386
invokeGuardedCallback @ react-dom.development.js:439
commitRootImpl @ react-dom.development.js:25069
unstable_runWithPriority @ scheduler.development.js:701
runWithPriority$2 @ react-dom.development.js:12231
commitRoot @ react-dom.development.js:24909
finishSyncRender @ react-dom.development.js:24304
performSyncWorkOnRoot @ react-dom.development.js:24284
scheduleUpdateOnFiber @ react-dom.development.js:23674
updateContainer @ react-dom.development.js:27092
(anonymous) @ react-dom.development.js:27517
unbatchedUpdates @ react-dom.development.js:24412
legacyRenderSubtreeIntoContainer @ react-dom.development.js:27516
render @ react-dom.development.js:27596
./src/index.js @ index.js:7
__webpack_require__ @ bootstrap:785
fn @ bootstrap:150
0 @ is-empty.js:7
__webpack_require__ @ bootstrap:785
checkDeferredModules @ bootstrap:45
webpackJsonpCallback @ bootstrap:32
(anonymous) @ main.chunk.js:1
index.js:1375 The above error occurred in the <ProfileItem> component:
    in ProfileItem (at Profiles.js:22)
    in div (at Profiles.js:34)
    in div (at Profiles.js:33)
    in div (at Profiles.js:32)
    in div (at Profiles.js:31)
    in Profiles (created by ConnectFunction)
    in ConnectFunction (created by Context.Consumer)
    in Route (at App.js:60)
    in div (at App.js:57)
    in div (at App.js:53)
    in Router (created by BrowserRouter)
    in BrowserRouter (at App.js:52)
    in Provider (at App.js:51)
    in App (at src/index.js:7)
Consider adding an error boundary to your tree to customize error handling behavior.

2 个答案:

答案 0 :(得分:1)

在您的ProfileItem组件中,

<img src={profile.user.avatar} alt="" className="rounded-circle" />

可能profile.usernull,您无法访问它。

您应该进行检查

<img src={profile && profile.user ? profile.user.avatar : 'some default src'} alt="" className="rounded-circle" />

答案 1 :(得分:0)

您应该测试{profile}是否已作为属性传递(假设您的请求正确携带了所有内容)。

对于前端我该怎么做:

...
class ProfileItem extends Component {
  render() {
    const { profile } = this.props;

    return (
      <div className="card card-body bg-light mb-3">
        {profile && <> 
         {/*your html profile code here. maybe you can try the line below: */}
         {JSON.stringify(profile)}
      </>
    )
}