0

In componentDidMount (), I get the data and pass it to the state.

componentDidMount() {
    const url = fetch('http://localhost:8000/posts/')
        .then(response => response.json())
        .then(response => {
            this.setState({ data: response });
        })
}

Next I try to get the data of this.state.data[0].id In this case, I get the error

TypeError: cannot read property 'id' of undefined

But if I try to get data through this.state.data[0], then an object comes in, where there is a property id

5
  • 1
    Try this.state.data.length>0?this.state.data[0].id:'' " Commented Dec 17, 2018 at 21:37
  • Probably you are trying to access the data before it comes back from the server. Rohit's suggestion should help. Commented Dec 17, 2018 at 21:38
  • how does your initial state look like? Commented Dec 17, 2018 at 21:39
  • Can you post the whole component? Commented Dec 17, 2018 at 21:42
  • Please show a complete code example. Where do you use this.state.data[0].id? Is it in your render() function? Commented Dec 17, 2018 at 22:04

1 Answer 1

2

You are fetching your data from a remote source and this fetch operation is asynchronous. In the initial render of your app you don't have this data yet.componentDidMount triggers the fetch and your data lands in your app. So, you should use a conditional rendering as recommended in the comments. Here is a simple example:

class App extends React.Component {
  state = {
    posts: []
  };
  componentDidMount() {
    fetch("https://jsonplaceholder.typicode.com/posts")
      .then(response => response.json())
      .then(posts => {
        this.setState({ posts });
      });
  }
  render() {
    const { posts } = this.state;
    return <div>{!!posts.length && posts[0].title}</div>;
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

And with a little enhancement. Because I'm pretty sure that you won't use a single data item in your app. As a future reference, you can use this simple logic. A better approach would be refactoring this code and writing a separate Post component.

class App extends React.Component {
  state = {
    posts: []
  };
  componentDidMount() {
    fetch("https://jsonplaceholder.typicode.com/posts")
      .then(response => response.json())
      .then(posts => {
        this.setState({ posts });
      });
  }
  render() {
    const { posts } = this.state;
    if (!posts.length) return <p>Loading...</p>;
    return (
      <div>
        {posts.map(post => (
          <div key={post.id}>
            <p>{post.title}</p>
          </div>
        ))}
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.