javascript - React JS : this.setState and JSON.parse - Stack Overflow

I have a problem, I don't know how I can fix it. I am doint a request to my api and it responds wi

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 badges
Add a ment  | 

3 Answers 3

Reset to default 1

React 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

相关推荐

  • javascript - React JS : this.setState and JSON.parse - Stack Overflow

    I have a problem, I don't know how I can fix it. I am doint a request to my api and it responds wi

    2天前
    30

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信