How to consume an API with REACTJS?

2

I have an application created with reactjs which I must consume an api that returns me x data. The problem I have is that I do not know how to do it through reactjs, I've reviewed the Internet how to do it and I've replicated exactly the same in my project but it does not work out for me. I do not know if I'm doing something wrong or I'm missing.

I am using the latest stable version of reactjs.

My code:

import React, { Component } from 'react';

class Home extends Component {
    constructor() {
        super();
        this.state = { items: [] };
    }

    componentDidMount() {
        fetch('http://localhost:44308/api/persona')
        .then(result=>result.json())
        .then(items=>this.setState({items}))
    }

    render() {
        return(
            <div>
                <ul>
                    {
                         this.state.items.map((item) =>{
                            return(
                                 <li></li>
                            )
                        })
                    }
                </ul>
            </div>
        )
    }
}

export default Home

At first I was trying to render n <li> depending on the amount of data returned by the json but I did not even paint the <li> in my view ... then try painting data, but it worked less.

If someone can help me please.

    
asked by vcasas 05.12.2018 в 14:13
source

4 answers

2

As I see in your code, two things are missing that can help you solve the error you have, I comment:

  • In the query 'fetch' you need to pass the options indicating the method you need (GET, POST, ...) and the header if you need it:

    fetch('http://localhost:44308/api/persona', {method: 'GET'}) //Ejemplo con 'GET'
      .then(result=>result.json())
      .then(items=>this.setState({items}))
    
  • Where the HTML is rendered you need to return the item in the 'map':

    <ul>
        {this.state.items.map( item => <li>{item}</li>)}
    </ul>
    

I think with these changes should work, as long as you receive the info from the api.

Could you confirm it?

Greetings

    
answered by 05.12.2018 в 15:34
1

From what I see in your code, you want to return an Array of objects using Fech within a list in React.

The main failure of your code is not to return the value, I have edited your code a bit and I leave it to you below to explain the differences.

import React, { Component } from 'react';

const List = (props) => (
    <ul>
        {
            props.items.map((item, i) => {
                return <li key={i}>{item}</li>
            })
        }
    </ul>
)

class Home extends Component {
    constructor() {
        super();
        this.state = { 
            done: false,
            items: []
        };
    }

    componentDidMount() {
        fetch('http://localhost:44308/api/persona')
        .then(result=>result.json())
        .then(items=>this.setState({
            done: true,
            items
        }))
    }

    render() {
        return(
            <div>
                {this.state.done && this.state.items.isArray() ? (
                    <List items={...this.state.items} />
                ) : (
                    <p>Cargando resultados...</p>
                )}
            </div>
        )
    }
}

export default Home

The first thing we have done before defining the class [Component] that is to be exported as an element of the DOM, is to define a stateless Component, which will be the one that returns the list with the data.

const List = (props) => (
    <ul>
        {
            props.items.map((item, i) => {
                return <li key={i}>{item}</li>
            })
        }
    </ul>
)

In each <li /> we have to define a key, which helps react not to make mistakes when rendering data from a list.

In the main class we have defined two variables, which are Done that will help us determine if the call to the API has been completed and the variable items .

Now when we make the call to the API using fetch, and this is successful, we modify the two state variables that we had defined at the beginning.

  

We can define another state variable in case the call to the API returns a .catch (), which could be by default success: true which would help us solve many errors that can be produced, by doing this we would have to do the following.

componentDidMount() {
        fetch('http://localhost:44308/api/persona')
        .then(result=>result.json())
        .then(items=>this.setState({
            done: true,
            items
        }))
        .catch(() => {
            this.setState({
                done: true,
                success: false
            })
        })
    }

Now in the rendering method, what we have avoided is for the user to see everything blank until the API returns the values by means of the asynchronous fetch function.

render() {
        return(
            <div>
                {this.state.done && this.state.items.isArray() ? (
                    <List items={...this.state.items} />
                ) : (
                    <p>Cargando resultados...</p>
                )}
            </div>
        )
    }
  

If we want the application to return something else in case of error, we can do the following

render() {
        if(this.state.done) {
            return (
                <div>
                    {
                        this.state.done && this.state.success ? (
                            <List items={...this.state.items} />
                        ) : (
                            <p>No se han podido recuperar los datos del servidor</p>
                        )
                    }
                </div>
            )
        } else {
            return (<p>Cargando contenidos...</p>)
        }
    }

It is from this point that the stateless component that we have defined at the beginning of the code comes into play.

For the component to be functional we have to include the state variable items in their entirety using:

<List items={...this.state.items} />

And this realizes all the logic of creating the tables with the values of the items property.

{
    props.items.map((item, i) => {
        return <li key={i}>{item}</li>
    })
}

I hope I have been a great help !! : D

    
answered by 13.12.2018 в 05:23
0

You can add a console.log just before painting the array for the li:

{
console.log(this.state.items) || this.state.items.map(item => <li>{item}</li>) }

This way you can see if you are getting the data just before traversing them.

    
answered by 11.12.2018 в 00:28
0

The best solution is to use fetch, if possible use Redux to store the information and receive the components as property is a bit more complex but the code is better organized.

    
answered by 21.01.2019 в 21:38