Sam B.
Sam B.

Reputation: 3033

Using Fetch with ReactJS

I'm pretty new to ReactJS so this is my implementation of using Fetch inside of it.

class App extends React.Component {
  function postData(url, data) {
      // Default options are marked with *
      return fetch(url, {
        body: JSON.stringify(data), // must match 'Content-Type' header
        cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
        credentials: 'same-origin', // include, same-origin, *omit
        headers: {
          'user-agent': 'Mozilla/4.0 MDN Example',
          'content-type': 'application/json'
        },
        method: 'POST', // *GET, POST, PUT, DELETE, etc.
        mode: 'cors', // no-cors, cors, *same-origin
        redirect: 'follow', // manual, *follow, error
        referrer: 'no-referrer', // *client, no-referrer
      })
      .then(response => response.json()) // parses response to JSON
    }


  render() {
    const test_content = ["first", "second", "third"];

    const initial_data = {
      'id': 1,
      'model-name': 'Joke'
    };

    postData('/start-jokes/', initial_data)
      .then(data => console.log(data)
       ) // JSON from `response.json()` call
      .catch(error => console.error(error));


    const jokes_div = test_content.map((item, i) => (
      <div key={i} className="card col-md-7">
        <div className="card-body">
            {item}
        </div>
      </div>
    ));
    return <div className="container" id="jokes">{jokes_div}</div>;
  }
}
// ========================================

ReactDOM.render(
  <App />,
  document.getElementById('root')
);

This works ok and the console logs this response.

Object { status: "ok", jokes: Array[10], ref-id: 11 }

The jokes array has an id and text in an Object, the text would be used same as test_content to populate the items with it's own unique key id shown here

enter image description here

any pointers on how to now populate from there will be much appreciated.

Upvotes: 0

Views: 934

Answers (2)

Subhanshu
Subhanshu

Reputation: 2146

Never call the api in render. If you want the data to be loaded when the page renders call the function in the componentDidMount ; else if you want to load on some other events or some input change call it in onChange event and as said no need to return the results you can setState the response.

class App extends React.Component {
    constructor(props) {
       super(props);
       this.state = { 
           data : [],
        }
     }
    componentDidMount(){
     this.postdata()
    }

    postdata(){
        var self = this;
            fetch(url, {
            body: JSON.stringify(data),
            cache: 'no-cache', 
            credentials: 'same-origin', 
            headers: {
            'user-agent': 'Mozilla/4.0 MDN Example',
            'content-type': 'application/json'
            },
            method: 'POST',
            mode: 'cors', 
            redirect: 'follow',
            referrer: 'no-referrer',
            })
            .then(response => response.json()).then((json) => {
              self.setState({ data : json.data }) // which ever the key hold the data 
            })
    }

    render(){
       return( 
            <div>
            {this.state.data.length == 0 && 
               <div> No options available.</div>
            }
            {this.state.data.length > 0 && 
              <div className="container" id="jokes">
                   {this.state.data.map(function(item,i){
                          return(
                                <div key={i} className="card col-md-7">
                                <div className="card-body">
                                {item}   // here you are getting object in item. Get the key from the object like item.name
                                </div>
                                </div>
                      )
                   })}
               </div>
            }
          </div>
         )
    }
}

Upvotes: 1

Sebastian Rothbucher
Sebastian Rothbucher

Reputation: 1483

As you're asynchronous, you'll need to take the lifecycle into account:

  1. call postData in componentDidMount
  2. instead of .then(response => response.json()) set the result into the state, e.g. .then(response => this.setState({jokes: response.json()}))
  3. in render, instead of test_content, use (this.state.jokes || [])

In larger applications, I'd consider separating rendering and data management (i.e. do two components), but I hope you get one step further with the points above...

Upvotes: 0

Related Questions