我正在Laravel中使用React,并且正在尝试构建一个简单的FriendsList组件以显示来自API的数据。 问题在于,Parent(配置文件)组件在获取数据之前已完成加载,因此FriendsList组件返回错误,因为道具第一次为空。务必要指出的是,无论API响应如何-父(配置文件)组件运行良好,第一次将其加载为空-然后添加数据。
Api通话
export const getProfile = () => {
return axios
.get('api/profile', {
headers: { Authorization: `Bearer ${localStorage.usertoken}` }
})
.then(response => {
// console.log(response.data)
return response.data
})
.catch(err => {
console.log(err)
})
}
父组件
import React, { Component } from 'react'
import { getProfile } from './UserFunctions'
import FriendsList from './FriendsList';
class Profile extends Component {
constructor() {
super()
this.state = {
name: '',
hobbies: '',
user_bday: '',
members: [],
error: '',
}
}
componentDidMount() {
getProfile().then(res => {
// console.log(JSON.parse(res))
this.setState({
name: res.user.name,
hobbies: res.user.hobbies,
user_bday: res.user.user_birthday,
related_friends: res.user.related_friends,
members: res.user.members,
})
})
}
render() {
return (
<div className="container">
<div className="jumbotron mt-5">
<div className="col-sm-4 mx-auto">
<h1 className="text-center">PROFILE</h1>
</div>
<table className="table col-md-4 mx-auto">
<tbody>
<tr>
<td>Name</td>
<td>{this.state.name}</td>
<td>{this.state.hobbies}</td>
<td>{this.state.user_bday}</td>
</tr>
</tbody>
</table>
<FriendsList members={this.state.members}>
</FriendsList>
</div>
</div>
)
}
}
export default Profile
import React from 'react';
class FriendsList extends React.Component {
render() {
console.log(this.props)
const { members } = this.props;
const listmembers = members.map((item, index) => (
<li key={item + index}>{item.name}</li>
));
return (
<div>
{listmembers}
</div>
);
}
}
export default FriendsList
答案 0 :(得分:1)
有两种方法可以解决这个问题。
第一种方法:
class Profile extends Component {
render() {
// check if your `state` has all the necessary values
// before rendering your JSX
const { name, hobbies, user_bday, members } = this.state
const shouldRender = name !== '' &&
hobbies !== '' &&
user_bday !== '' &&
Array.isArray(members) && members.length > 0
if (!shouldRender) {
return null;
}
return (...)
}
}
这样,您只有在JSX
拥有所需的一切时才渲染state
。
第二种方法:
class Profile extends Component {
constructor() {
// ...
this.setState = {
members: []
}
}
}
将members
设置为一个空数组,而不是一个空字符串,这样,当您将其作为prop
传递给FriendList
组件时,调用this.props.friends.map
实际上是正确的,但由于数组最初为空,因此不会呈现任何内容。
此外,看起来您从未在API调用完成后更新members
:
componentDidMount() {
getProfile().then(res => {
this.setState({
name: res.user.name,
hobbies: res.user.hobbies,
user_bday: res.user.user_birthday,
related_friends: res.user.related_friends,
})
})
}
因此,您的members
实际上是一个空字符串。确保您使用正确的类型(在这种情况下应为数组)更新状态。
答案 1 :(得分:0)
如果我正确理解了这个问题,那么您在谈论null props
...另外,注释中的Kellen是正确的...您应该将成员设置为空数组,而我看不到您正在更新您setState
...
尝试:
render() {
const friendsList =
this.props.firends &&
this.props.friends.map(function(item, index) {
<li key={index}>{item.name}</li>;
});
return (
<div>
<ul>{friendsList}</ul>
</div>
);
}
答案 2 :(得分:0)
如果我理解了您的问题,我想您需要看一下https://www.npmjs.com/package/prop-types,我认为您的问题在于默认的props值,并且该库可以帮助您实现所需的行为。
答案 3 :(得分:0)
这里的另一种方法是使用loading
状态,在此状态下,您将显示加载指示器等。
class Profile extends Component {
constructor() {
super();
this.state = {
name: "",
hobbies: "",
user_bday: "",
members: "",
error: "",
isMembers: false,
loading: true // Add loading state
};
}
componentDidMount() {
getProfile().then(res => {
// console.log(JSON.parse(res))
this.setState({
name: res.user.name,
hobbies: res.user.hobbies,
user_bday: res.user.user_birthday,
related_friends: res.user.related_friends,
loading: false // Remove the loading state when data is fetched
});
});
}
render() {
return this.state.loading ? (
<p> Loading... </p>
) : (
<div className="container">
<div className="jumbotron mt-5">
<div className="col-sm-4 mx-auto">
<h1 className="text-center">PROFILE</h1>
</div>
<table className="table col-md-4 mx-auto">
<tbody>
<tr>
<td>Name</td>
<td>{this.state.name}</td>
<td>{this.state.hobbies}</td>
<td>{this.state.user_bday}</td>
</tr>
</tbody>
</table>
{/*<FriendsList friends={this.state.members}></FriendsList>*/}
</div>
</div>
);
}
}