Tino
Tino

Reputation: 65

understanding promises and callbacks in ReactJS

How do i access the value of titles within render? I haven't quite got my head round promises and callbacks.

callback = (err, feed)=> {
    let titles =[]
    feed.items.forEach((entry)=> {
        titles.push(entry.title + ':' + entry.link);
    })
    return titles
}

render() {        
    this.state.parser.parseURL(this.state.proxy + 
        'http://feeds.bbci.co.uk/news/rss.xml?edition=uk', this.callback)
}

Upvotes: 0

Views: 1919

Answers (2)

adsy
adsy

Reputation: 11382

Theres 2 issues here:

  1. The render() method must return valid JSX. Instead of making the call to your external service in render(), you should make it in a lifecycle method like componentDidMount. Otherwise, your app will make lots of requests every time react runs render (which, by default, is every time the input props to the component or the local state change)
  2. If you want to access something like that in your render method, you need to put it in the state. So in your callback function, instead of returning title you will do this.setState({titles: titles}). In your render method, you'll be able to access this through this.state.titles.

I guess the key to understanding your problem is that if you want to access some data in render and have it update every time that data changes, it has to come from the component state or the props

Upvotes: 1

Daniel
Daniel

Reputation: 15413

When you delve into callbacks and Promises in JavaScript we are now talking about its asynchronous nature.

The result of an asynchronous operation is a callback.

A Promise is an object that wraps around an operation and notifies us when that operation is done. It seems similar to callbacks but instead of providing a callback, a promise has its own methods which you call to tell the promise what will happen when it is successful or when it fails.

Understanding that an asynchronous operation may not provide us with a result before we need to move on with another operation, what happens if that we have to code a second asynchronous operation, but the result of that one, is dependent on the result of the first asynchronous operation?

We would have a create a callback inside a callback like this:

request('http://www.example.com', function (firstError, firstResponse, firstBody) {
    if(firstError){
        // Handle error.
    }
    else {
        request(`http://www.example.com/${firstBody.someValue}`, function (secondError, secondResponse, secondBody) {
            if(secondError){
                // Handle error.
            }
            else {
                // Use secondBody for something
            }
        });
    }
});

The above example can get really hairy and nasty real fast with a growing application and it will lead to what is termed as callback hell.

Promises can serve to mitigate callback hell. So instead of nesting callbacks inside callbacks inside callbacks, you chain .then() calls together making it more readable and easier to follow. Every .then() should either return a new Promise or just a value or object which will be passed to the next .then() in the chain.

So taking the messy example above, and adding an axios library for handling http requests, the code, with Promise would look like this:

const axios = require(‘axios’);
axios.get(‘http://www.somepage.com')
.then(function (response) { // Reponse being the result of the first request
    // Returns another promise to the next .then(..) in the chain
    return axios.get(`http://www.somepage.com/${response.someValue}`);
})
.then(function response { // Reponse being the result of the second request
    // Handle response
})
.catch(function (error) {
    // Handle error.
});

Upvotes: 2

Related Questions