首页 > 解决方案 > ReactJs: can't access object element

问题描述

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

标签: javascriptreactjs

解决方案


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>


推荐阅读