英文:
Load more only works once when fetching from API in react
问题
I am currently trying to implement the load more functionality into this website, and I have a function I call when pressing the button, it adds 5 to the count, then this count is fetched, but the button only seems to add 5 the first time
我目前正在尝试将“加载更多”功能添加到这个网站中,当按下按钮时,我调用一个函数,它将数字增加5,然后获取该数字,但按钮似乎只在第一次添加5。
I don't really know what should be done, maybe using the useEffect, but I think is something really simple I can't see
我不太清楚应该做什么,也许可以使用 useEffect,但我认为这是一些非常简单的东西,我无法看到
import React, { useEffect, useState } from "react";
import "./BeerList.css";
const BeerList = () => {
const [beerList, setBeerList] = useState(null);
let count = 10;
const loadBeers = async () => {
const response = await fetch(
`https://api.punkapi.com/v2/beers?per_page=${count}`
);
const results = await response.json();
const randomBeerList = results.map((beersObj) => ({
name: beersObj.name,
tagline: beersObj.tagline,
url: beersObj.image_url,
}));
setBeerList(randomBeerList);
};
useEffect(() => {
loadBeers();
}, []);
const increment = () => {
count += 5;
loadBeers();
console.log(count);
}
if (beerList === null) {
return <div>Loading...</div>;
}
return (
<div className="beer-list-parent">
<div className="beer-list">
{beerList.map(({ name, tagline, url }, key) => (
<div key={key} className="beer">
<div className="beer-img">
<img src={url} className="url" />
</div>
<div className="beer-text">
<div className="name">{name}</div>
<div className="tagline">"{tagline}"</div>
</div>
</div>
))}
</div>
<div id="loadmore" className="more-parent">
<button className="more" type="button" onClick={increment}>Load more</button>
</div>
</div>
);
};
export default BeerList;
I tried using a counter and incrementing but only is added once, I console.log
and the value was repeating every time.
我尝试使用一个计数器并递增,但只添加了一次,我使用 console.log
发现值每次都重复。
英文:
I am currently trying to implement the load more functionality into this website, and I have a function I call when pressing the button, it adds 5 to the count, then this count is fetched, but the button only seems to add 5 the first time
I don't really know what should be done, maybe using the useeffect, but I think is something really simple I can't see
import React, { useEffect, useState } from "react";
import "./BeerList.css";
const BeerList = () => {
const [beerList, setBeerList] = useState(null);
let count = 10;
const loadBeers = async () => {
const response = await fetch(
`https://api.punkapi.com/v2/beers?per_page=${count}`
);
const results = await response.json();
const randomBeerList = results.map((beersObj) => ({
name: beersObj.name,
tagline: beersObj.tagline,
url: beersObj.image_url,
}));
setBeerList(randomBeerList);
};
useEffect(() => {
loadBeers();
}, []);
const increment = () => {
count += 5;
loadBeers();
console.log(count);
}
if (beerList === null) {
return <div>Loading...</div>;
}
return (
<div className="beer-list-parent">
<div className="beer-list">
{beerList.map(({ name, tagline, url }, key) => (
<div key={key} className="beer">
<div className="beer-img">
<img src={url} className="url" />
</div>
<div className="beer-text">
<div className="name">{name}</div>
<div className="tagline">"{tagline}"</div>
</div>
</div>
))}
</div>
<div id="loadmore" className="more-parent">
<button className="more" type="button" onClick={increment}>Load more</button>
</div>
</div>
);
};
export default BeerList;
I tried using a counter and incrementing but only is added once, I console.log
and the value was repeating every time.
答案1
得分: 0
你每次组件渲染时(即每次状态更新时),都将count
重置为0。为了避免这种情况,你应该将其存储在状态中。
此外,你还应该:(i) 在useEffect
中获取数据,而不是在事件处理程序中获取数据,以避免竞争条件;(ii) 将count
添加为useEffect
的依赖项,因为它是一个依赖项,依赖项应始终位于依赖项数组中,这将允许useEffect
在count
更新时重新运行。
import React, { useEffect, useState } from "react";
import "./BeerList.css";
const BeerList = () => {
const [beerList, setBeerList] = useState(null);
const [count, setCount] = useState(10); // <= 在这里进行更改
const loadBeers = async () => {
const response = await fetch(
`https://api.punkapi.com/v2/beers?per_page=${count}`
);
const results = await response.json();
const randomBeerList = results.map((beersObj) => ({
name: beersObj.name,
tagline: beersObj.tagline,
url: beersObj.image_url,
}));
setBeerList(randomBeerList);
};
useEffect(() => {
loadBeers();
}, [count]); // <= 在这里进行添加
const increment = () => {
setCount(count + 5); // <= 在这里进行更改和移除
console.log(count);
}
if (beerList === null) {
return <div>Loading...</div>;
}
return (
<div className="beer-list-parent">
<div className="beer-list">
{beerList.map(({ name, tagline, url }, key) => (
<div key={key} className="beer">
<div className="beer-img">
<img src={url} className="url" />
</div>
<div className="beer-text">
<div className="name">{name}</div>
<div className="tagline">"{tagline}"</div>
</div>
</div>
))}
</div>
<div id="loadmore" className="more-parent">
<button className="more" type="button" onClick={increment}>Load more</button>
</div>
</div>
);
};
export default BeerList;
英文:
You're resetting count
to 0 every time the component renders (which is every time the state updates). To avoid this you should store it in state.
Besides this, you should also: (i) fetch the data inside a useEffect and not in event handler to avoid race conditions; and (ii) add count
as a dependency of your useEffect, because it is a dependency and dependencies should always be in the dependency array, and because this will allow for the useEffect to rerun every time count
is updated.
import React, { useEffect, useState } from "react";
import "./BeerList.css";
const BeerList = () => {
const [beerList, setBeerList] = useState(null);
const [count, setCount] = useState(10); // <= Change here
const loadBeers = async () => {
const response = await fetch(
`https://api.punkapi.com/v2/beers?per_page=${count}`
);
const results = await response.json();
const randomBeerList = results.map((beersObj) => ({
name: beersObj.name,
tagline: beersObj.tagline,
url: beersObj.image_url,
}));
setBeerList(randomBeerList);
};
useEffect(() => {
loadBeers();
}, [count]); // <= Add here
const increment = () => {
setCount(count + 5); // <= Change and remove here
console.log(count);
}
if (beerList === null) {
return <div>Loading...</div>;
}
return (
<div className="beer-list-parent">
<div className="beer-list">
{beerList.map(({ name, tagline, url }, key) => (
<div key={key} className="beer">
<div className="beer-img">
<img src={url} className="url" />
</div>
<div className="beer-text">
<div className="name">{name}</div>
<div className="tagline">"{tagline}"</div>
</div>
</div>
))}
</div>
<div id="loadmore" className="more-parent">
<button className="more" type="button" onClick={increment}>Load more</button>
</div>
</div>
);
};
export default BeerList;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论