依赖异步数据获取异常:fetchStats需点击两次才生效
解决异步请求依赖状态的执行问题
问题核心:fetchStats依赖openseaCollection状态,但setOpenseaCollection是异步更新的——点击按钮时fetchOpenSeaData刚触发状态更新,fetchStats就立刻执行,此时openseaCollection还是旧值,导致第一次点击不生效;第二次点击时状态已完成更新,才能正常执行。
方案一:直接传递数据,跳过状态异步等待
修改fetchOpenSeaData让它返回获取到的数据,在按钮点击时先等待该函数执行完成,再把结果直接传给fetchStats,不再依赖组件状态的更新:
const fetchOpenSeaData = async () => { if (!collection.length) return null; const requestOptions = { method: "GET" }; const fetchURL = `https://api.opensea.io/api/v1/asset_contract/${collection}`; const response = await fetch(fetchURL, requestOptions); const nfts = await response.json(); if (nfts) { console.log("Collection Info", nfts); setOpenseaCollection(nfts); } return nfts; // 返回获取到的原始数据 }; const fetchStats = async (collectionData) => { // 直接使用传入的参数,不再依赖组件状态 if (!collectionData) return; const requestOptions = { method: "GET" }; const fetchURL = `https://api.opensea.io/api/v1/collection/${collectionData?.collection?.slug}/stats`; const response = await fetch(fetchURL, requestOptions); const nfts = await response.json(); if (nfts) { console.log("Collection Stats", nfts); setStats(nfts); } }; // 更新按钮点击逻辑 <button onClick={async () => { if (fetchForCollection) { fetchNFTsForCollection(); const collectionData = await fetchOpenSeaData(); await fetchStats(collectionData); } else { fetchNFTs(); } }} > Go! </button>
方案二:用useEffect监听状态变化
如果必须依赖状态触发请求,可以通过useEffect监听openseaCollection的变化,当状态更新完成后自动调用fetchStats:
import { useEffect } from 'react'; // 新增监听逻辑 useEffect(() => { // 初始状态是空数组,所以用长度判断避免无效请求 if (openseaCollection.length > 0) { fetchStats(); } }, [openseaCollection]); // 仅当openseaCollection变化时执行 // 简化按钮点击逻辑 <button onClick={() => { if (fetchForCollection) { fetchNFTsForCollection(); fetchOpenSeaData(); // 不再直接调用fetchStats,交给useEffect处理 } else { fetchNFTs(); } }} > Go! </button>
优化提示:如果想让状态判断更严谨,可以把openseaCollection的初始状态从空数组改为null:
const [openseaCollection, setOpenseaCollection] = useState(null);
此时useEffect里的判断条件可以简化为if (openseaCollection)。
内容的提问来源于stack exchange,提问作者plastik
相关产品推荐
相关产品推荐

