Search code examples
javascriptjsonreactjsaxiosreact-dom

Json Data not rendering in ReactJS class after setting its state through axios library method?


I am trying to read JSON data through axios library function axios.get() method.It works fine and logs the correct username in console and properly sets the state of users variable.But when I try to render the same object in render method() it stops working. Link to CODE on codepen .

class TableData extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      users:[],
      count: 0
    };
  }
  componentDidMount() {
    axios
      .get(`https://fcctop100.herokuapp.com/api/fccusers/top/recent`)
      .then(response => {
        this.setState({ users: response.data });
        console.log(this.state.users[2].username);
      });
  }
  render() {
    return (
      <div>Hello {this.state.users[2].username}</div>
    );
  }
}
ReactDOM.render(<TableData />, document.getElementById("container"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.12.0/axios.min.js"></script>
<div class="container" id="container">

</div>

The URL for JSON data return object of type

Object {
  alltime: 388,
  img: "https://avatars3.githubusercontent.com/u/36005?v=3",
  lastUpdate: "2017-10-17T08:05:51.276Z",
  recent: 124,
  username: "korzo"
}

Please Help me.


Solution

  • There's a period of time in which this.state.users is an empty array. So when your render function accesses this.state.users[2].username, this.state.users[2] can be undefined, throwing an exception. You just have to alter your render function to handle the case where the array is empty.

    Also be aware that this.setState can be asynchronous, so the log statement that you have after calling setState may not see the new state. If you want to wait until setState completes, you can pass in a callback function to this.setState

    class TableData extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          users:[],
          count: 0
        };
      }
      componentDidMount() {
        axios
          .get(`https://fcctop100.herokuapp.com/api/fccusers/top/recent`)
          .then(response => {
            this.setState({ users: response.data }, function () {
              console.log(this.state.users[2].username);
            });
          });
      }
      render() {
        return (
          <div>Hello {this.state.users[2] && this.state.users[2].username}</div>
        );
      }
    }
    ReactDOM.render(<TableData />, document.getElementById("container"));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.12.0/axios.min.js"></script>
    <div class="container" id="container">
    
    </div>