Jae
Jae

Reputation: 1157

ReactJS not rendering my API call results

In React, I have a state called views_res which is a list. I make an API call in viewsList(), which is supposed to map the results of the API call to this state variable. However, when I debug using console.log(), I see the "start" and "WHAT UP DOE," but the views is empty :(

I know that the API end point is correct, as Postman shows me the correct JSON response. However, my state variable is simply not receiving the data. I'm not sure where I am going wrong with this!

For privacy, I redacted the exact API end point.

componentDidMount() {
    this.ViewsList();
  }

  // Gets views from Wistia API
   ViewsList() {
    console.log("start", this.state.views);
// API call
$.getJSON(
  "url"
)
  // JSON format
  .then(response => {
    response.json();
  })
  .then(data => {
    // Map over data
    let views_res = data.response.map(item => (
      <div>
        console.log("play_count", {item.play_count})
        <h1>{item.play_count}</h1> */}
      </div>
    ));
    // Set the state
    this.setState({ views: views_res });
  });
console.log("WHAT UP DOE", this.state.views);
  }

Upvotes: 1

Views: 1135

Answers (1)

Sagiv b.g
Sagiv b.g

Reputation: 31024

I'm not sure what kind of library you're using for $.getJson (is it jQuery?) but note that setState is an asynchronous operation. Meaning, you want "see" the changes if you console.log after you called setState.
There is a second argument though for setState which is a callback function that will get triggered after the actual update of the state.

this.setState({ views: views_res }, () => {
    // this is a callback function for setState.
  // this coode will run just after the state actually updated
  console.log("WHAT UP DOE", this.state.views)
})

From the DOCS:

setState() does not always immediately update the component. It may batch or defer the update until later. This makes reading this.state right after calling setState() a potential pitfall. Instead, use componentDidUpdate or a setState callback (setState(updater, callback)), either of which are guaranteed to fire after the update has been applied

Edit
Note that this part:

<div>
  console.log("play_count", {item.play_count})
  <h1>{item.play_count}</h1> */}
</div>

Will not log anything, as

console.log("play_count", {item.play_count})

Is just a string inside a JSX block. If you want to write JavaScript expressions inside a JSX block, you should wrap it with curly braces ({}):

See a running example:

function App() {
  return (
    <div>
     <div>
        console.log("i am just a string")
        {console.log('I will show in the console')}
      </div>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<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">

Upvotes: 2

Related Questions