使useState挂钩的set方法等待变量更新
making set method of useState hook to wait for the variable update
我有一个用例,我使用 useState 挂钩来增加变量的值。一旦变量的值递增,那么我只需要调用一个更新函数。
const [page, setPage] = useState(1);
const fetchMoreData = () => {
setPage(page+1);
updateNews();
};
所以本质上我希望它像 await setPage(page+1);
那样。因此,一旦页面更新,我只能从更新 URL 页面获取新闻。
由于这个原因,我目前得到
index.js:1 Warning: Encountered two children with the same key, `https://english.jagran.com/trending/did-mars-ever-look-like-earth-heres-what-top-nasa-scientist-has-to-say-10033695`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.
at div
at div
at div
at div
at InfiniteScroll (http://localhost:3000/static/js/vendors~main.chunk.js:32922:24)
at News (http://localhost:3000/static/js/main.chunk.js:775:89)
at Route (http://localhost:3000/static/js/vendors~main.chunk.js:34951:29)
at Switch (http://localhost:3000/static/js/vendors~main.chunk.js:35153:29)
at div
at Router (http://localhost:3000/static/js/vendors~main.chunk.js:34582:30)
at BrowserRouter (http://localhost:3000/static/js/vendors~main.chunk.js:34203:35)
at App
这是我目前的组件News.js
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 = `https://newsapi.org/v2/top-headlines?country=${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 = () => {
setPage(page+1);
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>
</>
)
}
export default News
我尝试在更新函数中打印 goToPage
的值,我看到它每次都是 1。
有什么方法可以解决错误还是等待setPage。
注意:我尝试了这个问题的解决方案,作为对这个问题的建议,但这对我不起作用。
- 如果你想增加
page
属性,你可能应该使用 setPage
和回调函数,像这样:
setPage(page => page + 1);
- 您可以通过在依赖数组中使用
useEffect
和 page
来达到预期的效果:
useEffect(() => {
updateNews();
}, [page])
我有一个用例,我使用 useState 挂钩来增加变量的值。一旦变量的值递增,那么我只需要调用一个更新函数。
const [page, setPage] = useState(1);
const fetchMoreData = () => {
setPage(page+1);
updateNews();
};
所以本质上我希望它像 await setPage(page+1);
那样。因此,一旦页面更新,我只能从更新 URL 页面获取新闻。
由于这个原因,我目前得到
index.js:1 Warning: Encountered two children with the same key, `https://english.jagran.com/trending/did-mars-ever-look-like-earth-heres-what-top-nasa-scientist-has-to-say-10033695`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.
at div
at div
at div
at div
at InfiniteScroll (http://localhost:3000/static/js/vendors~main.chunk.js:32922:24)
at News (http://localhost:3000/static/js/main.chunk.js:775:89)
at Route (http://localhost:3000/static/js/vendors~main.chunk.js:34951:29)
at Switch (http://localhost:3000/static/js/vendors~main.chunk.js:35153:29)
at div
at Router (http://localhost:3000/static/js/vendors~main.chunk.js:34582:30)
at BrowserRouter (http://localhost:3000/static/js/vendors~main.chunk.js:34203:35)
at App
这是我目前的组件News.js
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 = `https://newsapi.org/v2/top-headlines?country=${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 = () => {
setPage(page+1);
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>
</>
)
}
export default News
我尝试在更新函数中打印 goToPage
的值,我看到它每次都是 1。
有什么方法可以解决错误还是等待setPage。
注意:我尝试了这个问题的解决方案,作为对这个问题的建议,但这对我不起作用。
- 如果你想增加
page
属性,你可能应该使用setPage
和回调函数,像这样:
setPage(page => page + 1);
- 您可以通过在依赖数组中使用
useEffect
和page
来达到预期的效果:
useEffect(() => {
updateNews();
}, [page])