简体   繁体   中英

How to update an array using useState Hook

I've tried to fetch data from a URL and get the result as JSON format, then store not of the object result in my state. but it always returns an empty array.

const [genres, setGenres] = useState([]);
  useEffect(() => {
    const getGenres = async () => {
      fetch("https://quote-garden.herokuapp.com/api/v2/genres")
        .then((response) => response.json())
        .then((data) => {
           for (const g of data.genres) {
             setGenres((oldGenres) => [...oldGenres, g]);
           }          
        });
    };
    getGenres();
  }, []);

Here is the code: I don't see where the problem can be. ps: I deleted the import so the code is more readable

import React, { useEffect, useState } from "react";
function App() {
  const [quoteOfTheDay, setQuoteOfTheDay] = useState("");
  const [authorOfQod, setAuthorOfQod] = useState("");
  useEffect(() => {
    const getQuoteOfTheDay = async () => {
      fetch("https://quotes.rest/qod?language=en")
        .then((response) => response.json())
        .then((data) => {
          const qod = data.contents.quotes[0].quote;
          const author = data.contents.quotes[0].author;
          setQuoteOfTheDay(qod);
          setAuthorOfQod(author);
        });
    };
    getQuoteOfTheDay();
  }, []);
  const [genres, setGenres] = useState([]);
  useEffect(() => {
    const getGenres = async () => {
      fetch("https://quote-garden.herokuapp.com/api/v2/genres")
        .then((response) => response.json())
        .then((data) => {
          for (const g of data.genres) {
             setGenres((oldGenres) => [...oldGenres, g]);
           } 
        });
      console.log(genres); // genres always empty
    };
    getGenres();
  }, []);
  return (
    <div className="app">
      <Head quoteOfTheDay={quoteOfTheDay} author={authorOfQod} />
      <div className="app__category">
        <QuoteCategory genre="sport" />
      </div>
    </div>
  );
}

export default App;

Thank you so much

I think it should work if you change

for (const g of data.genres) {
    setGenres((oldGenres) => [...oldGenres, g]);
}

to

setGenres((oldGenres) => [...oldGenres, ...data.genres]);

Are you sure that

useEffect(() => {
  const getGenres = async () => {
    fetch("https://quote-garden.herokuapp.com/api/v2/genres")
      .then((response) => response.json())
      .then((data) => {
         setGenres(data.genres);
      });
  };
  getGenres();
}, []);

is not enough? :)

Up. If you began you can use async-await syntax till the end. It looks more neatly.

useEffect(() => {
  const getGenres = async () => {
    const response = await fetch("https://quote-garden.herokuapp.com/api/v2/genres");
    const { genres } = await response.json();

    setGenres(genres);
  };
  
  getGenres();
}, []);

you should put genresState as your dependency

const [genresState, setGenres] = useState([])



useEffect(() => {
  const getGenres = async () => {
    const response = await fetch("https://quote-garden.herokuapp.com/api/v2/genres");
    const { genres } = await response.json();

    setGenres(genres);
  };
  
  getGenres();
}, [genresState]);

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