简体   繁体   中英

Can't set state in react

So, I'm simply trying to set state in my react app. Simply get data from Axios, and then set state. But no matter what I do, the state will not set. I've tried putting it in a callback since it's async and putting it my component did mount and component did update alas nothing. any pointers?

class App extends Component {
  componentDidUpdate() {}

  constructor(props) {
    super(props);
    this.state = {
      Catogories: [
        "Business",
        "Entertainment",
        "General",
        "Health",
        "Science",
        "Sports",
        "Technology"
      ],
      CatPics: [],
      TopStories: [],
      Selection: [],
      Sources: [],
      selected: false
    };
  }
  GeneratePic = () => {
    this.state.Catogories.forEach(Catogory => {
      axios
        .get(
          "https://api.pexels.com/v1/search?query=" +
            Catogory +
            "&per_page=15&page=1",
          {
            Authorization:
              "563492ad6f91700001000001d33b5d31a9a145b78ee67e35c8e6c321"
          }
        )
        .then(res => {
          var object = { Catogory: res.photos[0].src.large2x };
          this.state.CatPics.push(object);
        });
    });
  };
  dump = x => {
    this.setState({ TopStories: x }, console.log(this.state.TopStories));
  };
  TopStories = () => {
    console.log("working");
    axios
      .get(
        "https://newsapi.org/v2/top-headlines?country=us&apiKey=91bec895cf8d45eaa46124fb19f6ad81"
      )
      .then(res => {
        console.log(res);
        const data = res.data.articles;
        console.log(data);
        this.dump(data);
      });
  };

You are doing two things wrong.

  1. Don't mutate the state
  2. Don't do async actions inside loop and then use same loop variable inside async callback because at that point in time, loop variable will have some other value and not the respective iteration category.
  GeneratePic = async () => {
    const promises = this.state.Catogories.map(Catogory => {
      return axios
        .get(
          "https://api.pexels.com/v1/search?query=" +
            Catogory +
            "&per_page=15&page=1",
          {
            Authorization:
              "563492ad6f91700001000001d33b5d31a9a145b78ee67e35c8e6c321"
          }
        )
        .then(res => {
          return res.photos[0].src.large2x;
        });
    });

    let photos = await Promise.all(promises);
    photos = this.state.Catogories.map((cat, index) => ({ [cat]: photos[index] }));
    this.setState({ CatPics: photos });
  };

 getPics = cat => { return axios .get( "https://api.pexels.com/v1/search?query=" + cat + "&per_page=15&page=1", { Authorization: "563492ad6f91700001000001d33b5d31a9a145b78ee67e35c8e6c321" } ) .then(res => { return { [cat]: res.photos[0].src.large2x }; }); } GeneratePic = async () => { const promises = this.state.Catogories.map(Catogory => { this.getPics(Catogory); }); let photos = await Promise.all(promises); this.setState({ CatPics: photos }); };

This should work.

Dont Mutate the state.

 GeneratePic = () => {
        this.state.Catogories.forEach(async Catogory => {
            await axios
                .get(
                    "https://api.pexels.com/v1/search?query=" +
                    Catogory +
                    "&per_page=15&page=1", {
                        Authorization: "563492ad6f91700001000001d33b5d31a9a145b78ee67e35c8e6c321"
                    }
                )
                .then(res => {
                    var object = { Catogory: res.data.photos[0].src.large2x };
                    const cPics = [...this.state.CatPics];
                    cPics.push(object);
                    this.setState({
                        CatPics: cPics
                    })
                });
        });
    };

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM