How to update properties in React "setState"

Asked

Viewed 938 times

1

I’m trying to add objects to 2 properties of the Fecthapis component. I make the call to both Api’s, and I get the request with the expected objects. However, when I try to include these objects in both properties, with "setState", I get the following error for the second property (feedGitHub): uncaught (in Promise) Typeerror: Cannot read Property 'setState' of null

the code is as follows::

import React, { Component } from 'react';
import axios from 'axios';


class App extends React.Component {

  render() {
    return (
      <div className="App">
        <FetchApis />
      </div>
    )
  }
}

class FetchApis extends React.Component {
  constructor(){
    super();
    this.state ={
      feedReddit: [],
      feedGitHub: []
    }
  }

  componentDidMount(){
    axios.all([
      axios.get('https://www.reddit.com/r/redditdev/top.json?limit=2'),
      axios.get('https://api.github.com/search/repositories?q=react+language:javascript&sort=stars&order=desc')
    ])
      .then(axios.spread(function (reddit, github) {
        var feed1 = reddit.data.data.children.map(obj => obj.data);
        var feed2 = github.data.items.map(obj => obj)
        console.log(feed1);
        console.log(feed2);
        this.setState({
          feedReddit: {feed1},
          feedGitHub: {feed2}
        })
      }));
  }

  render(){
    return(
      <div>
        <h1>teste</h1>
        <ul>
          {this.state.feedReddit.map(bananareddit =>
          <li key={bananareddit.id}>{bananareddit.title}</li>
          )}
        </ul>


        <ul>
          {this.state.feedGitHub.map(bananagithub =>
          <li key={bananagithub.id}>{bananagithub.name}</li>
          )}
        </ul>
      </div>

    )
  }

}

export default App;

Thank you so much for your attention.

1 answer

0


The problem is that the this inside the callback of the axios is no longer your component. You have two alternatives:

  • use Arrow functions
  • use an alias

With Arrow Function:

mute

.then(axios.spread(function (reddit, github) {

for

.then(axios.spread((reddit, github) => {

Alias:

componentDidMount(){
    const self = this;
    axios.all([
      axios.get('https://www.reddit.com/r/redditdev/top.json?limit=2'),
      axios.get('https://api.github.com/search/repositories?q=react+language:javascript&sort=stars&order=desc')
    ])
      .then(axios.spread(function (reddit, github) {
        var feed1 = reddit.data.data.children.map(obj => obj.data);
        var feed2 = github.data.items.map(obj => obj)
        console.log(feed1);
        console.log(feed2);
        self.setState({
          feedReddit: {feed1},
          feedGitHub: {feed2}
        });
      }));
}

Note: I don’t understand the idea of var feed2 = github.data.items.map(obj => obj). Is there anything missing? or do you want to make a copy? in that case you can use slice, but unnecessary as the array was created two lines above.

  • Thank you so much for your return, Sergio. Truth, I could pick up the date that returns from the call. For those who see this post, even to help, after fixing with your suggestion, will appear another error. I will post below the resolution.

  • @Alinevianna you do not need to post the solution if you used the ideas of my answer. What is the other error that appears?

  • Typeerror: this.state.feedReddit.map is not a Function

  • @Alinevianna ok, why are you creating an object here? feedReddit: {feed1}, should just be feedReddit: feed1,

  • @Exact Alinevianna!

  • 1

    that =) I got confused.. in the documentation it said I had to pass expressions by keys. Thanks again, @Sergio !

  • @Alinevianna of nothing!

Show 2 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.