user11700058
user11700058

Reputation:

How to do fetch in react?

Good afternoon, I get json from the server, I process it, but the call to render occurs 2 times.Google, make an empty object in the constructor.And if the object has no property, then undefined is returned, but I also have arrays, from which the application crashes.I attach the code. How to get the data out of the state? Is it possible to fetch in the render and write?

export default class Forma extends React.Component {
  constructor(props) {
    super(props);
    this.state = { data: [] };
  }

  componentWillMount() {
    fetch("http://localhost:3001")
      .then(response => response.json())
      .then(result => this.setState({ data: result }))
      .catch(e => console.log(e));
  }

  render() {
    const { data } = this.state;

    return <h1>{console.log(data.goals[0].gs_id)}</h1>; //падает
  }
}

Upvotes: 3

Views: 436

Answers (2)

Cat_Enthusiast
Cat_Enthusiast

Reputation: 15688

Use an extra state-value that you can toggle when the data has finished fetching. That will help prevent the attempt of using an object property inside an empty array.

export default class Forma extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      loading: true,
      data: []
    };
  }
  componentDidMount() {
    fetch('http://localhost:3001')
      .then(response => response.json())
      .then(result => this.setState({ loading: false, data: result }))
      .catch(e => {
        this.setState({ loading: false })
        console.log(e)
      });
  }

  render() {
    const { loading, data } = this.state;

    if (loading) {
      return <span>Loading</span>;
    }

    if (!data || data.length === 0) {
      return <span>No items found</span>;
    }

    return <h1>{data.goals[0].gs_id}</h1>;
  }
}

Upvotes: 4

Dhaval Jardosh
Dhaval Jardosh

Reputation: 7299

Use componentDidMount instead of componentWillMount, it's deprecated.

And that's a really good addition in Christopher's answer to handle async operation.

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: []
    };
  }
  componentDidMount() {
    fetch("https://jsonplaceholder.typicode.com/todos")
      .then(response => response.json())
      .then(result =>
        this.setState({
          data: result
        })
      )
      .catch(e => console.log(e));
  }
  render() {
    const { data } = this.state;

    return <h1> {data[0] ? data[0].title : 'Loading'} </h1>;
  }
}
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>

Upvotes: 6

Related Questions