我是新的React和redux,所以我不能解决这个错误后,做了大量的研究很容易。我试图在一个单独的页面中显示用户的个人资料的形式卡,但我得到一个错误:
TypeError: Cannot read property 'name' of null
ProfileItem.render
src/components/profiles/Profileitem.js:15
12 | <div className="row">
13 |
14 | <div className="col-lg-6 col-md-4 col-8">
> 15 | <h3>{profile.user.name}</h3>
16 | <p>
17 | {profile.status}{' '}
18 | {isEmpty(profile.company) ? null : (
▶ 22 stack frames were collapsed.
(anonymous function)
src/actions/userprofileAction.js:77
74 | dispatch(profileLoading());
75 | axios
76 | .get('/api/userprofile/all')
> 77 | .then(res =>
78 | dispatch({
79 | type: GET_PROFILES,
80 | payload: res.data
//这是用户配置文件userprofile.js的后端
const express = require('express');
const router = express.Router();
const mongoose=require('mongoose');
const passport=require('passport');
//loading validation after creating the userprofie valdiation
const validateProfileInput=require('../../validation/userprofile');
const validateExperienceInput=require('../../validation/experience');
//bring profile schema model
const Profile=require('../../models/Profile');
//bringing user schema model
const User=require('../../models/User');
//testing this api
router.get('/demo', (req, res) => res.json({ msg: 'Profile Works' }));
//get request
//now need to check for the user who is trying to login
router.get('/',passport.authenticate('jwt', { session: false }),(req, res) => {
//initializing this as empty because need to add error msg
const errors = {};
//fetch current user's profile and finding from profile model
//findone is a mongoose method which will find a specifc{single} thing
Profile.findOne({ user: req.user.id }) .populate('user', ['name']).then(profile => {
//if not found display error msg
if (!profile) {
errors.noprofile = 'no profile exists for this person';
return res.status(404).json(errors);
}
//if found then show proifle
res.json(profile);
})
.catch(err => res.status(404).json(err));
}
)
//to see all profiles at api/userprofile/all
router.get('/all',(req,res)=>{
Profile.find()
.populate('user',['name'])
.then(profiles=>{
if(!profiles){
errors.noprofile='no profiles';
return res.status(404).json(errors);
}
res.json(profiles);
})
.catch(err=>res.status(404).json({profile:'no profiles'}));
})
//getting profile by name
router.get('/profilename/:profilename',(req,res)=>{
Profile.findOne({profiename:req.params.profiename})
.populate('user',['name'])
.then(profile=>{
if(!profile){
errors.noprofile='there is no profile';
res.status(400).json(errors);
}
res.json(profile);
})
.catch(err=>res.status(404).json(err));
})
//getting profile by id
router.get('/users/:users_id',(req,res)=>{
Profile.findOne({profiename:req.params.profiename})
.populate('user',['name'])
.then(profile=>{
if(!profile){
errors.noprofile='there is no profile';
res.status(400).json(errors);
}
res.json(profile);
})
.catch(err=>res.status(404).json(err));
})
//post request
router.post(
'/',
passport.authenticate('jwt', { session: false }),
(req, res) => {
const {errors,isValid}=validateProfileInput(req.body);
//check validation
if(!isValid){
return res.status(400).json(errors);
}
//getting fields and adding in an obj
const fields={};
fields.user=req.user.id;
//checking if its sent from handle
if(req.body.profilename)fields.profilename=req.body.profilename;
if(req.body.company)fields.company=req.body.company;
if(req.body.location)fields.location=req.body.location;
//so splitting skills into an array when seperated by ','
if(typeof req.body.skills!=='undefined')
fields.skills=req.body.skills.split(',');
//searching by id and if profile has then update
Profile.findOne({user:req.user.id}).then(profile=>{
if(profile){
Profile.findOneAndUpdate({user:req.user.id},{$set:fields},{new:true})
.then(profile=>res.json(profile));
}
else{
//checking if there
Profile.findOne({profiename:fields.profilename}).then(profile=>{
if(profile){
errors.profiename='profile already there'
res.status(400).json(errors);
}
//saving and making new if not
new Profile(fields).save().then(profile=>res.json(profile));
})
}
})
}
);
//post req to add exp
router.post(
'/experience',
passport.authenticate('jwt', { session: false }),
(req, res) => {
const { errors, isValid } = validateExperienceInput(req.body);
// Check Validation
if (!isValid) {
// Return any errors with 400 status
return res.status(400).json(errors);
}
//to add new experience
Profile.findOne({ user: req.user.id }).then(profile => {
const newExperience = {
title: req.body.title,
company: req.body.company,
location: req.body.location,
from: req.body.from,
to: req.body.to,
description: req.body.description
};
// Add to exp array
profile.experience.unshift(newExperience);
profile.save().then(profile => res.json(profile));
});
}
);
//after adding if user wants to delete the experience
router.delete(
'/experience/:exp_id',
passport.authenticate('jwt', { session: false }),
(req, res) => {
const { errors, isValid } = validateExperienceInput(req.body);
// Check Validation
if (!isValid) {
// Return any errors with 400 status
return res.status(400).json(errors);
}
Profile.findOne({ user: req.user.id }).then(profile => {
const remove=profile.experience
.map(item=>item.id)
.indexof(req.params.exp_id);
//splicing out of array at index 1
profile.experience.splice(remove,1)
//saving
profile.save().then(profile=>res.json(profile));
})
.catch(err=>res.status(404).json(err));
}
);
module.exports = router;
userprofileaction.js
import axios from 'axios';
import {GET_USERPROFILE,PROFILE_LOADING,GET_ERRORS,CLEAR_CURRENT_PROFILE,GET_PROFILES} from './types';
//getting current profile
export const getProfile=()=>dispatch=>{
//dispatching loading state before req
dispatch(profileLoading());
axios.get('/api/userprofile')
.then(res=>
dispatch({
type:GET_USERPROFILE,
payload:res.data
}))
.catch(err=>
dispatch({
type:GET_USERPROFILE,
payload:{}
}))
}
// Create Profile
export const createProfile = (profileData, history) => dispatch => {
axios
.post('/api/userprofile', profileData)
.then(res => history.push('/dashboard'))
.catch(err =>
dispatch({
type: GET_ERRORS,
payload: err.response.data
})
);
};
export const addExp=(experienceData,history)=>dispatch=>{
axios.post('/api/userprofile/experience',experienceData)
.then(res=>history.push('/dashboard'))
.catch(err=>dispatch({
type:GET_ERRORS,
payload:err.response.data
}))
}
export const deleteExperience = id => dispatch => {
axios
.delete(`/api/userprofile/experience/${id}`)
.then(res =>
dispatch({
type: GET_USERPROFILE,
payload: res.data
})
)
.catch(err =>
dispatch({
type: GET_ERRORS,
payload: err.response.data
})
);
};
//loading the profile
export const profileLoading=()=>{
return{
type:PROFILE_LOADING
}
}
//clearing profile
export const clearcurrentprofile=()=>{
return{
type:CLEAR_CURRENT_PROFILE
}
}
//getting profiles
export const getProfiles = () => dispatch => {
dispatch(profileLoading());
axios
.get('/api/userprofile/all')
.then(res =>
dispatch({
type: GET_PROFILES,
payload: res.data
})
)
.catch(err =>
dispatch({
type: GET_PROFILES,
payload: null
})
);
};
profileItem.js
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-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={`/userprofile/${profile.profilename}`} 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;
Profiles.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import ProfileItem from './ProfileItem';
import { getProfiles } from '../../actions/userprofileAction';
class Profiles extends Component {
componentDidMount() {
this.props.getProfiles();
}
render() {
const { profiles, loading } = this.props.profile;
let profileItems;
if (profiles === null || loading) {
profileItems = <h3>Profiles are loading..........</h3>;
} else {
if (profiles.length > 0) {
profileItems = profiles.map(profile => (
<ProfileItem key={profile._id} profile={profile} />
));
} else {
profileItems = <h4>No profiles found.....</h4>;
}
}
return (
<div className="profiles">
<div className="container">
<div className="row">
<div className="col-md-12">
<h1 className="display-4 text-center">Job Seeker's profiles</h1>
<p className="lead text-center">
Explore and get in touch with a Job seeker for free!
</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);
userprofileReducer.js
import {GET_USERPROFILE,PROFILE_LOADING,CLEAR_CURRENT_PROFILE,GET_PROFILES} from '../actions/types';
//import { stat } from 'fs';
const initialstate={
//will have profile
profile:null,
profiles:null,
loading:false
}
export default function(state=initialstate, action){
switch(action.type){
case PROFILE_LOADING:
return{
...state,
loading:true
}
case GET_USERPROFILE:
return{
...state,
profile:action.payload,
loading:false
}
case GET_PROFILES:
return{
...state,
profiles:action.payload,
loading:false
}
case CLEAR_CURRENT_PROFILE:
return{
...state,
profile:null
}
default:
return state;
}
}
6条答案
按热度按时间zour9fqk1#
你首先需要检查profile是未定义的还是空的,然后才能访问它的键。在这种情况下,你通常会使用三元或&&运算符。
下面的代码应该适合您
yyhrrdl82#
看起来您在设置值之前尝试正确读取。尝试在调用它之前添加检查。类似于:
cx6n0qe33#
尝试console.log(这个.props)在进入render的第一件事。
通常,当初始渲染完成且 prop 中的值尚不存在时,会出现此类错误。
解决方案是检查此.props和this.props.xxx,如果它们为空,则显示a“正在加载”消息/ a微调框。
jmp7cifd4#
当错误突出显示时,错误位于以下行:
您正在尝试访问对象用户的名称,但问题是该对象与您预期的不同。其值为null,因此不包含属性名称。您需要在用户中填充服务响应的位置进行调试。
13z8s7eq5#
对我来说,我已经涵盖了try catch块,它的工作
nuypyhwy6#
嗨,现在重播已经晚了,你可以使用三元运算符,这将是最简单的解决方案。感谢@Dmytro Huz