使用 Promises 等待 useState 挂钩增量计数器
Waiting for useState hook increment counter using Promises
我有一个计数器需要在我的 DOM 呈现之前更新。
const [count, setCount] = useState(1);
我需要在用户滚动时更新它,并调用 fetchMoreData 函数。
所以我将它添加到 Promise 中并等待它被更新
const fetchMoreData = async () => {
await new Promise((resolve, reject) => {
setCount(count+1);
resolve();
});
updateNews();
};
但这似乎不起作用,计数没有立即增加。
我该如何解决?
编辑: 在聊天中,A.mola 帮助我解决了问题,所以他给我的答案是根据我的代码,我发布了相同的这里。
import React, { useEffect, useState } from "react";
import NewsItem from "./NewsItem";
import Spinner from "./Spinner";
import PropTypes from "prop-types";
import InfiniteScroll from "react-infinite-scroll-component";
const News = (props) => {
const [articles, setArticles] = useState([]);
const [loading, setLoading] = useState(true);
const [page, setPage] = useState(1);
const [totalResults, setTotalResults] = useState(0);
const capitalizeFirstLetter = (string) => {
return string.charAt(0).toUpperCase() + string.slice(1);
};
const updateNews = async () => {
props.setProgress(10);
let goToPage = page;
const url = `newsapi.org/v2/…${props.country}&category=${props.category}&apiKey=${props.apiKey}&page=${goToPage}&pageSize=${props.pageSize}`;
props.setProgress(30);
let data = await fetch(url);
props.setProgress(50);
let parsedData = await data.json();
props.setProgress(70);
if (parsedData) {
setArticles(articles.concat(parsedData.articles));
setLoading(false);
setPage(page);
setTotalResults(parsedData.totalResults);
}
props.setProgress(100);
};
useEffect(() => {
updateNews();
// eslint-disable-next-line
}, []);
const fetchMoreData = async () => {
setPage((page) => {
console.log(page);
return page + 1;
});
console.log(page);
updateNews();
};
return (
<>
<h3 className="text-center" style={{ marginTop: "4%" }}>
NewsMonkey - Top {`${capitalizeFirstLetter(props.category)}`} Headlines
</h3>
{loading && <Spinner />}
<InfiniteScroll
dataLength={articles.length}
next={fetchMoreData}
hasMore={articles.length < totalResults}
loader={<Spinner />}
>
<div className="container">
<div className="row">
{articles.map((element) => {
return (
<div className="col-md-4" key={element.url}>
<NewsItem
title={
element && element.title ? element.title.slice(0, 45) : ""
}
description={
element && element.description
? element.description.slice(0, 50)
: ""
}
imageUrl={element.urlToImage}
newsUrl={element.url}
author={element.author}
date={element.publishedAt}
source={element.source.name}
/>
</div>
);
})}
</div>
</div>
</InfiniteScroll>
</>
);
};
感谢a.mola的全面回答,我正在更新你在聊天中给我的答案。
我们正在使用 useEffect
挂钩来使用数组依赖项呈现我们的组件。
import React, { useEffect, useState } from "react";
import NewsItem from "./NewsItem";
import Spinner from "./Spinner";
import PropTypes from "prop-types";
import InfiniteScroll from "react-infinite-scroll-component";
const News = ({ country, category, apiKey, pageSize, setProgress }) => {
const [articles, setArticles] = useState([]);
const [loading, setLoading] = useState(true);
const [page, setPage] = useState(1);
const [totalResults, setTotalResults] = useState(0);
const capitalizeFirstLetter = (string) => {
return string.charAt(0).toUpperCase() + string.slice(1);
};
useEffect(() => {
const updateNews = async () => {
setProgress(10);
let goToPage = page;
const url = `newsapi.org/v2/…${country}&category=${category}&apiKey=${apiKey}&page=${goToPage}&pageSize=${pageSize}`;
setProgress(30);
let data = await fetch(url);
setProgress(50);
let parsedData = await data.json();
setProgress(70);
if (parsedData) {
setArticles(articles.concat(parsedData.articles));
setLoading(false);
setTotalResults(parsedData.totalResults);
}
setProgress(100);
};
updateNews();
}, [page, articles, pageSize, setProgress, apiKey, category, country]);
const fetchMoreData = () => setPage(page + 1);
return (
<>
<h3 className="text-center" style={{ marginTop: "4%" }}>
NewsMonkey - Top {`${capitalizeFirstLetter(category)}`} Headlines
</h3>
{loading && <Spinner />}
<InfiniteScroll dataLength={articles.length} next={fetchMoreData} hasMore={articles.length < totalResults} loader={<Spinner />}>
<div className="container">
<div className="row">
{articles.map((element) => {
return (
<div className="col-md-4" key={element.url}>
<NewsItem title={element && element.title ? element.title.slice(0, 45) : ""} description={element && element.description ? element.description.slice(0, 50) : ""} imageUrl={element.urlToImage} newsUrl={element.url} author={element.author} date={element.publishedAt} source={element.source.name} />
</div>
);
})}
</div>
</div>
</InfiniteScroll>
</>
);
};
这是代码框 link : https://codesandbox.io/s/proud-shape-58yig?file=/Infinite.tsx:0-2597
我有一个计数器需要在我的 DOM 呈现之前更新。
const [count, setCount] = useState(1);
我需要在用户滚动时更新它,并调用 fetchMoreData 函数。
所以我将它添加到 Promise 中并等待它被更新
const fetchMoreData = async () => {
await new Promise((resolve, reject) => {
setCount(count+1);
resolve();
});
updateNews();
};
但这似乎不起作用,计数没有立即增加。
我该如何解决?
编辑: 在聊天中,A.mola 帮助我解决了问题,所以他给我的答案是根据我的代码,我发布了相同的这里。
import React, { useEffect, useState } from "react";
import NewsItem from "./NewsItem";
import Spinner from "./Spinner";
import PropTypes from "prop-types";
import InfiniteScroll from "react-infinite-scroll-component";
const News = (props) => {
const [articles, setArticles] = useState([]);
const [loading, setLoading] = useState(true);
const [page, setPage] = useState(1);
const [totalResults, setTotalResults] = useState(0);
const capitalizeFirstLetter = (string) => {
return string.charAt(0).toUpperCase() + string.slice(1);
};
const updateNews = async () => {
props.setProgress(10);
let goToPage = page;
const url = `newsapi.org/v2/…${props.country}&category=${props.category}&apiKey=${props.apiKey}&page=${goToPage}&pageSize=${props.pageSize}`;
props.setProgress(30);
let data = await fetch(url);
props.setProgress(50);
let parsedData = await data.json();
props.setProgress(70);
if (parsedData) {
setArticles(articles.concat(parsedData.articles));
setLoading(false);
setPage(page);
setTotalResults(parsedData.totalResults);
}
props.setProgress(100);
};
useEffect(() => {
updateNews();
// eslint-disable-next-line
}, []);
const fetchMoreData = async () => {
setPage((page) => {
console.log(page);
return page + 1;
});
console.log(page);
updateNews();
};
return (
<>
<h3 className="text-center" style={{ marginTop: "4%" }}>
NewsMonkey - Top {`${capitalizeFirstLetter(props.category)}`} Headlines
</h3>
{loading && <Spinner />}
<InfiniteScroll
dataLength={articles.length}
next={fetchMoreData}
hasMore={articles.length < totalResults}
loader={<Spinner />}
>
<div className="container">
<div className="row">
{articles.map((element) => {
return (
<div className="col-md-4" key={element.url}>
<NewsItem
title={
element && element.title ? element.title.slice(0, 45) : ""
}
description={
element && element.description
? element.description.slice(0, 50)
: ""
}
imageUrl={element.urlToImage}
newsUrl={element.url}
author={element.author}
date={element.publishedAt}
source={element.source.name}
/>
</div>
);
})}
</div>
</div>
</InfiniteScroll>
</>
);
};
感谢a.mola的全面回答,我正在更新你在聊天中给我的答案。
我们正在使用 useEffect
挂钩来使用数组依赖项呈现我们的组件。
import React, { useEffect, useState } from "react";
import NewsItem from "./NewsItem";
import Spinner from "./Spinner";
import PropTypes from "prop-types";
import InfiniteScroll from "react-infinite-scroll-component";
const News = ({ country, category, apiKey, pageSize, setProgress }) => {
const [articles, setArticles] = useState([]);
const [loading, setLoading] = useState(true);
const [page, setPage] = useState(1);
const [totalResults, setTotalResults] = useState(0);
const capitalizeFirstLetter = (string) => {
return string.charAt(0).toUpperCase() + string.slice(1);
};
useEffect(() => {
const updateNews = async () => {
setProgress(10);
let goToPage = page;
const url = `newsapi.org/v2/…${country}&category=${category}&apiKey=${apiKey}&page=${goToPage}&pageSize=${pageSize}`;
setProgress(30);
let data = await fetch(url);
setProgress(50);
let parsedData = await data.json();
setProgress(70);
if (parsedData) {
setArticles(articles.concat(parsedData.articles));
setLoading(false);
setTotalResults(parsedData.totalResults);
}
setProgress(100);
};
updateNews();
}, [page, articles, pageSize, setProgress, apiKey, category, country]);
const fetchMoreData = () => setPage(page + 1);
return (
<>
<h3 className="text-center" style={{ marginTop: "4%" }}>
NewsMonkey - Top {`${capitalizeFirstLetter(category)}`} Headlines
</h3>
{loading && <Spinner />}
<InfiniteScroll dataLength={articles.length} next={fetchMoreData} hasMore={articles.length < totalResults} loader={<Spinner />}>
<div className="container">
<div className="row">
{articles.map((element) => {
return (
<div className="col-md-4" key={element.url}>
<NewsItem title={element && element.title ? element.title.slice(0, 45) : ""} description={element && element.description ? element.description.slice(0, 50) : ""} imageUrl={element.urlToImage} newsUrl={element.url} author={element.author} date={element.publishedAt} source={element.source.name} />
</div>
);
})}
</div>
</div>
</InfiniteScroll>
</>
);
};
这是代码框 link : https://codesandbox.io/s/proud-shape-58yig?file=/Infinite.tsx:0-2597