I have a problem, I don't know how I can fix it. I am doint a request to my api and it responds with an object like this :
{"_id":"5a806648300caf0072c7254a","mail":"[email protected]"}
I want to print to my react ponent the mail. In my "ponentDidMount()" function I get the mail, so there is no problem with my api. But when I want to set the state of my "users" variable, I can not print the variable in my ponent... It says that it's undefined.
Here is my code :
class UserList extends Component {
constructor(props){
super(props);
this.state = {users:[]}
}
ponentDidMount() {
//here my function that store the response from my api
GetData('http://localhost:3333/users', 'username=admin',
(res) =>
{
this.setState({users: JSON.parse(res)});
//Here I can log the mail
console.log(this.state.users[0].mail);
})
}
render() {
return (
<table>
<thead>
<tr>
<th>EMAIL</th>
</tr>
</thead>
<tbody>
<tr>
//Here it is 'undefined'
<td>{this.state.users[0].mail}</td>
</tr>
</tbody>
</table>
);
}
}
Thank you for your help !
I have a problem, I don't know how I can fix it. I am doint a request to my api and it responds with an object like this :
{"_id":"5a806648300caf0072c7254a","mail":"[email protected]"}
I want to print to my react ponent the mail. In my "ponentDidMount()" function I get the mail, so there is no problem with my api. But when I want to set the state of my "users" variable, I can not print the variable in my ponent... It says that it's undefined.
Here is my code :
class UserList extends Component {
constructor(props){
super(props);
this.state = {users:[]}
}
ponentDidMount() {
//here my function that store the response from my api
GetData('http://localhost:3333/users', 'username=admin',
(res) =>
{
this.setState({users: JSON.parse(res)});
//Here I can log the mail
console.log(this.state.users[0].mail);
})
}
render() {
return (
<table>
<thead>
<tr>
<th>EMAIL</th>
</tr>
</thead>
<tbody>
<tr>
//Here it is 'undefined'
<td>{this.state.users[0].mail}</td>
</tr>
</tbody>
</table>
);
}
}
Thank you for your help !
Share Improve this question asked Feb 11, 2018 at 16:28 RbejotRbejot 671 gold badge1 silver badge10 bronze badges3 Answers
Reset to default 1React mounting ponent lifecycle is:
- constructor
- ponentWillMount
- render
- ponentDidMount
See more here: https://reactjs/docs/react-ponent.html#mounting
When your ponent is mounting this.state.users is an empty array.
You can change the render method:
class UserList extends Component {
constructor(props){
super(props);
this.state = {users:[]}
}
ponentDidMount() {
//here my function that store the response from my api
GetData('http://localhost:3333/users', 'username=admin',
(res) =>
{
// After setState react runs updating lifecycle methods (https://reactjs/docs/react-ponent.html#updating)
this.setState({users: JSON.parse(res)});
//Here I can log the mail
console.log(this.state.users[0].mail);
})
}
render() {
// if users are not loaded, we return null from render function
if (this.state.users.length === 0) {
return null;
}
return (
<table>
<thead>
<tr>
<th>EMAIL</th>
</tr>
</thead>
<tbody>
<tr>
<td>{this.state.users[0].mail}</td>
</tr>
</tbody>
</table>
);
}
}
You should not directly use the values from an asynchronous action.
As the GetData
in ponentDidMount() is asynchronous function, it will take some time to get data. So in the initial render the user
in state is empty.
It is better to use loading indicator untill the data is fetched and show the data only when the data is received.
You may use as below.
class UserList extends Component {
constructor(props){
super(props);
this.state = {users:[]},
loading: false
}
ponentDidMount() {
//here my function that store the response from my api
this.setState({loading: true});
GetData('http://localhost:3333/users', 'username=admin',
(res) =>
{
this.setState({users: JSON.parse(res), loading: false});
//Here I can log the mail
console.log(this.state.users[0].mail);
})
}
render() {
if(this.state.loading){
return (<div> Loading... </div>)
}
return (
<div>
<table>
<thead>
<tr>
<th>EMAIL</th>
</tr>
</thead>
<tbody>
{this.state.users.length > 0 &&
<tr>
<td>{this.state.users[0].mail || ''}</td>
</tr>
}
</tbody>
</table>
</div>
);
}
}
use may use map to loop as below
{this.state.users.length > 0 && this.state.users.map(user =>
return(
<tr>
<td>{user.mail || ''}</td>
</tr>)
}
In the above case, the problem is with understanding Component Lifecycle of React.
Please take a look at the reference.
ComponentDidMount occurs after the render has occurred.
Hierarchy will be 1. constructor 2. ponentWillMount 3. render 4. ponentDidMount
if the code is modified with replacing ComponentDidMount with ComponentWillMount
ponentWillMount() {
//here my function that store the response from my api
GetData('http://localhost:3333/users', 'username=admin',
(res) =>
{
this.setState({users: JSON.parse(res)});
//Here I can log the mail
console.log(this.state.users.mail);
})
}
if the api is working correctly it will give the data.
But wait as the response from the api is an object and initializing the state with an array is also conceptually not correct I think so.
As I work most of project in Typescript, initialization of state is important to me.
constructor(props){
super(props);
this.state = {users:{
mail: ''
}}
}
Personal preference is the checking the user state is undefined or not this will surely not allow you to lead any undefined or errors.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744834170a4596162.html
评论列表(0条)