【问题标题】:How to update an array using useState Hook如何使用 useState Hook 更新数组
【发布时间】:2021-02-06 15:36:41
【问题描述】:

我尝试从 URL 获取数据并以 JSON 格式获取结果,然后不将对象结果存储在我的状态中。但它总是返回一个空数组。

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();
  }, []);

代码如下: 我看不出问题出在哪里。 ps:我删除了导入,这样代码更易读

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;

非常感谢

【问题讨论】:

标签: javascript arrays reactjs react-hooks


【解决方案1】:

我认为如果你改变它应该可以工作

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

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

【讨论】:

  • 你能把文件的其余部分贴出来吗?可能还有另一个问题在起作用
  • 我刚刚编辑了代码。非常感谢您的宝贵时间。
  • 我刚刚查看了您的代码,并且该日志中的流派将为空,因为 setGenres 函数尚未完成。如果将该日志移到 useEffect 之外,您将看到在下一次渲染中填充了流派
  • 有效!!!非常感谢您的参与。这是我下次会注意的。
【解决方案2】:

你确定

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

还不够吗? :)

向上。如果你开始了,你可以使用async-await 语法直到最后。它看起来更整洁。

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

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

【讨论】:

  • 你也可以在存储前修改数据setGenres(data.genres.map(/* ... */));
  • 两个都试过了
  • 如果你把debuger放在setGenres(data.genres);之前你会在data.genres得到什么?
  • 一个字符串数组,其中数组的每个元素都是引用类别的名称
  • 等等!您想在线获取console.log(genres); // genres always empty 后立即获取流派吗?当然,你会在这个地方得到[]。 =)
【解决方案3】:

你应该把genresState作为你的依赖

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]);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-22
    • 1970-01-01
    • 1970-01-01
    • 2021-07-25
    • 1970-01-01
    相关资源
    最近更新 更多