React/JS中使用Fetch()将返回数组赋值给可用变量的问题
问题描述
在完成FCC课程项目时,尝试通过fetch获取包含数组的JSON并赋值给React组件的state(不想手动编写数组),但遇到了问题:能成功获取JSON并在控制台打印quotes数组,但把它赋值给变量时得到的是Promise对象。推测是对异步函数的理解不到位,于是做了一个非React环境的CodePen测试:
const testFetch = fetch('https://gist.githubusercontent.com/camperbot/5a022b72e96c4c9585c32bf6a75f62d9/raw/e3c6895ce42069f0ee7e991229064f167fe8ccdc/quotes.json') .then(response => response.json()) .then((quote) => { return quote.quotes; }) // 这里能正常打印出第一个quote的内容 const testVar = async () => { const quoteArr = await testFetch; console.log("The quote is ", quoteArr[0].quote); return quoteArr[0].quote; }; let myQuote = testVar(); // 这里打印的是 "Is my quote variable working? + [Promise pending]" console.log("Is my quote variable working? + ", myQuote)
测试里async函数内部能正常打印第一个quote,但把函数返回值赋值给myQuote时,得到的是Pending状态的Promise,想知道问题出在哪,该怎么修正。
问题分析与解决
核心问题很明确:async函数的返回值永远是Promise对象——不管你return的是原始值还是其他内容,都会被自动包装成Promise。所以直接把testVar()赋值给myQuote,拿到的必然是还未完成的Promise,而非最终的quote字符串。
1. 非React测试场景的修正方法
如果你只是想拿到最终的quote值并使用,有两种简单方式:
- 方式一:在async函数内部直接处理结果(比如打印、赋值给DOM元素等)
const testVar = async () => { const quoteArr = await testFetch; const myQuote = quoteArr[0].quote; console.log("Is my quote variable working? + ", myQuote); // 这里能拿到正确值 return myQuote; }; testVar(); - 方式二:用
.then()链式调用获取Promise的最终结果let myQuote; testVar().then(quote => { myQuote = quote; console.log("Is my quote variable working? + ", myQuote); // 正确拿到值 }); - 更简洁的写法:直接对
testFetch用.then()处理,不用额外封装async函数testFetch.then(quoteArr => { const myQuote = quoteArr[0].quote; console.log("Is my quote variable working? + ", myQuote); });
2. React组件场景的正确做法
回到你实际的FCC项目,要把fetch到的数组赋值给组件state,得在组件的异步生命周期里处理:
- 函数组件(用useEffect)
import { useState, useEffect } from 'react'; function QuoteComponent() { const [quotes, setQuotes] = useState([]); useEffect(() => { fetch('https://gist.githubusercontent.com/camperbot/5a022b72e96c4c9585c32bf6a75f62d9/raw/e3c6895ce42069f0ee7e991229064f167fe8ccdc/quotes.json') .then(res => res.json()) .then(data => setQuotes(data.quotes)) .catch(err => console.error('获取数据失败:', err)); }, []); // 空依赖数组确保只执行一次 return ( <div> {quotes.length > 0 && <p>{quotes[0].quote}</p>} </div> ); } - 类组件(用componentDidMount)
class QuoteComponent extends React.Component { state = { quotes: [] }; componentDidMount() { fetch('https://gist.githubusercontent.com/camperbot/5a022b72e96c4c9585c32bf6a75f62d9/raw/e3c6895ce42069f0ee7e991229064f167fe8ccdc/quotes.json') .then(res => res.json()) .then(data => this.setState({ quotes: data.quotes })) .catch(err => console.error('获取数据失败:', err)); } render() { const { quotes } = this.state; return ( <div> {quotes.length > 0 && <p>{quotes[0].quote}</p>} </div> ); } }
内容的提问来源于stack exchange,提问作者Jobeyobey
相关产品推荐
相关产品推荐

