微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么状态在 foreach 中更新时不会将所有处于 Array 状态的数据保留在钩子中?

如何解决为什么状态在 foreach 中更新时不会将所有处于 Array 状态的数据保留在钩子中?

我想通过 foreach 在钩子中更新我的数组状态,但它只保留最后一个。我还使用了 useEffect 的空数组,通过更新状态来停止每次重新渲染。

import './App.css';
import Card from "./Card"
import Books from "./Books"
import { useEffect,useState } from 'react';
import axios from "axios"
import BooksInfo from './Books';
function App() {
  const [bookInfo,setBookInfo] = useState([])
  useEffect( ()=>{
    let bname = ""
    let bauthor = ""
    let bcover = 0
    async function getInfo(){
        let results = Promise.all(BooksInfo.map(book=>{
          let result = axios.get(`https://openlibrary.org/search.json?q=${book}`)
          return result
        }))
        ;(await results).forEach(result=>{
          console.log(result)
            bname= result.data.docs[0].title_suggest
            bauthor= result.data.docs[0].author_name[0]
            bcover= result.data.docs[0].cover_i
            setBookInfo([...bookInfo,{ name:bname,author:bauthor,cover:bcover }]);
            console.log(bookInfo)
        })
    }

    getInfo()
  },[])  

这是其中一条注释的附加代码:此代码帮助我了解 state 和 useEffect 的工作原理。

function App(){
  console.log("App Rendered!");

  const [counter,setCounter] = useState(0);
  const [test,setTest] = useState(0)
  const [run,setRun] = useState(0)
  useEffect(()=>{
    console.log("inside useEffect")
    setCounter(counter => counter + 1);
    setTest(test => test +counter)

  },[run])
  const count= ()=>{
    console.log("test")
    setRun(run => run + 2)
  }
  return (
    <div>
      <h1>Counter: {counter}</h1>
      <button
        onClick={count}
      >
        Increment
      </button>
    </div>
  );
}
export default App;

解决方法

试试这个,setBookInfo 是一个异步调用,当你在循环中使用它时,它不会为下一次迭代取最新值。相反,它采用最后一个值(初始值)。这就是它显示最后一个值的原因。

import "./App.css";
import Card from "./Card";
import Books from "./Books";
import { useEffect,useState } from "react";
import axios from "axios";
import BooksInfo from "./Books";
function App() {
  const [bookInfo,setBookInfo] = useState([]);
  useEffect(() => {
    async function getInfo() {
      let results = await Promise.all(
        BooksInfo.map((book) => {
          let result = axios.get(
            `https://openlibrary.org/search.json?q=${book}`
          );
          return result;
        })
      );

      const finalResult = results.map((result) => {
        let bname = "";
        let bauthor = "";
        let bcover = 0;
        console.log(result);
        bname = result.data.docs[0].title_suggest;
        bauthor = result.data.docs[0].author_name[0];
        bcover = result.data.docs[0].cover_i;
        return { name: bname,author: bauthor,cover: bcover };
      });
      setBookInfo([...bookInfo,...finalResult]);
    }
    getInfo();
  },[]);
}
,

setBookInfo 函数是异步的,因此无法保证每次迭代后,bookInfo 的数据都会更新为新插入的数据。 map 函数更适合你的情况

const newBookInfor = (await results).map((result) => {
    let bname = "";
    let bauthor = "";
    let bcover = 0;
    bname = result.data.docs[0].title_suggest;
    bauthor = result.data.docs[0].author_name[0];
    bcover = result.data.docs[0].cover_i;
    return { name: bname,cover: bcover };
});
setBookInfo(newBookInfor);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。