英文:
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;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论