【问题标题】:How to remove repeatable API results when using react-infinite-scroll and react hooks使用 react-infinite-scroll 和 react 钩子时如何删除可重复的 API 结果
【发布时间】:2020-10-04 09:35:01
【问题描述】:

我正在使用 react-infinite-scroll-component 库和 randomuser.me api。我可以获取数据并且无限滚动工作得很好,但我遇到的问题是,由于组件在每次滚动时都会发出请求,所以我得到了可重复的结果。

我找到了一种解决方法,可以删除相同的数组,但它不能与无限滚动包一起正常工作。

这是我的代码:

function App() {
  const [people, setPeople] = useState([]);

  const fetchPeopleImages = () => {
    axios.get(`https://randomuser.me/api/?results=30&nat=br`).then((res) => {
      const result = res.data.results;
      setPeople([...people, ...result]);
    });
    // if (people.length > 30) {
    //   const removedDuplicatedPeople = people.filter(
    //     (ele, ind) =>
    //       ind ===
    //       people.findIndex(
    //         (elem) => elem.picture.medium === ele.picture.medium,
    //       ),
    //   );
    //   setPeople([...people, removedDuplicatedPeople]);
    // }
  };

  useEffect(() => {
    fetchPeopleImages();
    // commented below because ESLINT was asking me to use useCallback 
    // inside fetchPeopleImage func. idk why
    // eslint-disable-next-line
  }, []);

  return (
    <div className="App">
      <InfiniteScroll
        dataLength={people.length}
        next={() => fetchPeopleImages()}
        hasMore={true}
        loader={<h4>Carregando...</h4>}
        endMessage={
          <p style={{ textAlign: 'center' }}>
            <b>Yay! You have seen it all</b>
          </p>
        }
      >
        {people.length > 1 &&
          people.map((people, i) => (
            <div>
              <img src={people.picture.medium} alt="Imagem de uma pessoa" />
            </div>
          ))}
      </InfiniteScroll>
    </div>
  );
}

export default App;

评论的是我发现删除具有相同图像链接的数组的解决方法。 密码沙盒:https://codesandbox.io/s/gracious-wildflower-opjx5?file=/src/App.js

【问题讨论】:

    标签: javascript reactjs react-infinite-scroll-component


    【解决方案1】:

    理想情况下,不要专门针对频繁提取(如滚动)进行过滤。最好保持一个状态,比如 page 并将其传递给您的 api 并且 api 应该返回数据。

    您所面临的不一致问题是由于 randomuser.me api 的限制。该 api 仅提供有限的图像,因此它将混合名称、年龄、图像等,并尽力提供独特的记录。因此,您经常会看到重复的图像。您可以通过将名称与图像一起渲染来检查,您会看到 2 个相同的图像具有不同的名称。

    解决问题的一些建议: - 为results 查询参数提供一个低值,比如 10 - 对 api 使用 seed 选项 - 在每次滚动时增加 page 并将其传递给 api 查询参数

    updated demo here - 它在某种程度上有效

    注意 - 您仍然无法保证看到呈现的独特图像。但是,您可以使用更新后的代码,并且在您使用真正的 api 时它会起作用。

    更新代码 sn-p

    function App() {
      const [people, setPeople] = useState([]);
      const [page, setPage] = useState(0);
    
      const fetchPeopleImages = () => {
        axios
          .get(`https://randomuser.me/api/?results=10&nat=br&page=${page}&seed=abc`)
          .then(res => {
            const result = res.data.results;
            setPeople([...people, ...result]);
            setPage(prev => prev + 1);
          });
        console.log("page", page);
    
      };
    
      useEffect(() => {
        fetchPeopleImages();
        // commented below because ESLINT was asking me to use useCallback inside
        // fetchPeopleImage func. idk why
        // eslint-disable-next-line
      }, []);
    
      return (
        <div className="App">
          <InfiniteScroll
            dataLength={people.length}
            next={() => fetchPeopleImages()}
            hasMore={true}
            loader={<h4>Loading.....</h4>}
            endMessage={
              <p style={{ textAlign: "center" }}>
                <b>Yay! You have seen it all</b>
              </p>
            }
          >
            {people.length > 1 &&
              people.map((people, i) => (
                <div key={i}>
                  <img src={people.picture.medium} alt="Person" />
                  <p>{people.name.first}</p>
                </div>
              ))}
          </InfiniteScroll>
        </div>
      );
    }
    

    【讨论】:

    • 你说得对,ramdomuser api 让它很难工作。感谢您的宝贵时间。
    猜你喜欢
    • 2020-08-06
    • 2020-11-14
    • 1970-01-01
    • 1970-01-01
    • 2022-11-07
    • 1970-01-01
    • 2020-11-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多