【问题标题】:API results are not consistentAPI 结果不一致
【发布时间】:2021-05-18 02:27:12
【问题描述】:

我正在尝试在我的小型 React 应用程序中使用 Open Library API。根据我的搜索查询,我向 API 发出请求并获取结果,然后将其呈现为列表。但是,有时,最终列表与 API 请求的原始结果完全不同。网络选项卡上的一切似乎都很好;获取 URL 是正确的,没有额外的请求来呈现不同的结果。

例如:我输入“apple”,所以我提出了 5 个请求。 (最终请求:网络选项卡上的https://openlibrary.org/search.json?title=apple)。第五个请求的控制台日志是正确的,但它以某种方式呈现一个(可能更多)时间并获得另一个与搜索查询完全无关的列表。 Network选项卡上仍然只有5个请求(当然我只计算XHR)

我认为还有其他问题与此 API 调用问题有关。例如,如果我不限制(获取数组的第一个 X 元素)API 调用的结果,我可以看到约 400 个请求。我可能做错了什么。

我使用 Context API 来管理几乎所有内容。

这里是沙盒:https://codesandbox.io/s/hungry-merkle-dnz17

请注意:为了您的方便,我添加了一个 console.log 来查看实际的 API 结果。您可能需要搜索几次。

我认为问题出在上下文或搜索组件中。

上下文:

import { useState, useEffect, createContext } from "react";

const Context = createContext();

const ContextProvider = ({ children }) => {
  const [books, setBooks] = useState([]);
  const [query, setQuery] = useState("");

  let URL = `https://openlibrary.org/search.json?title=${query}`;


  useEffect(() => {
    fetch(URL)
      .then((res) => res.json())
      .then((data) => setBooks(data.docs.slice(0, 8)))
      .catch((err) => console.error(err));
  }, [URL]);

  console.log('Click to link to see actual API result: ', URL)

  const handleSearch = (e) => {
    e.preventDefault();
    let value = e.target.value;
    setQuery(value);
  };

  const handleFilter = (value) => {
    const filteredBooks = [...books];
    if (books.length > 0) {
      switch (value) {
        case "alphabetical":
          filteredBooks.sort((a, b) => a.title - b.title);
          setBooks(filteredBooks);
          break;
        case "publishdate":
          filteredBooks.sort(
            (a, b) => b.first_publish_year - a.first_publish_year
          );
          setBooks(filteredBooks);
          break;
        default:
          console.log("reached");
      }
    }
  };

  return (
    <Context.Provider value={{ books, query, handleSearch, handleFilter }}>
      {children}
    </Context.Provider>
  );
};

export { ContextProvider, Context };

搜索:

import Filter from "./Filter";
import { useContext } from "react";
import { Context } from "../context/Context";

function Search() {
  const { query, handleSearch } = useContext(Context);

  return (
    <>
      <div className="search-container">
        <div className="search-input-wrapper">
          <input
            type="text"
            placeholder="Search by title or author"
            value={query}
            onChange={handleSearch}
          />
        </div>
      </div>
      <Filter />
    </>
  );
}

export default Search;

【问题讨论】:

  • 请在您的问题中包含相关的Minimal, Complete, and Reproducible Code Example,这样我们就不会猜测要在您的沙盒中查看什么。
  • 我不知道应该在此处添加代码的哪些部分。这就是我制作沙盒的原因。反正。如果您想查看更多组件/代码,请告诉我。

标签: reactjs


【解决方案1】:

问题

据我所知,您正在向query 发送每个状态更新的 GET 请求,并且它们以不确定的顺序解决。似乎较短的查询实际上比较长的查询需要更长的时间来解决,即"title=a" 似乎比"title=apple" 需要更长的时间。

解决方案

看起来你在尝试去抖动某物方面走在了正确的轨道上。你应该去抖动你的 GET 请求。使用useMemo钩子来记忆去抖函数。

const debouncedFetch = useMemo(
  () =>
    debounce((url) => {
      fetch(url)
        .then((res) => res.json())
        .then((data) => setBooks(data.docs.slice(0, 8)))
        .catch((err) => console.error(err));
    }, 500),
  []
);

useEffect(() => {
  const URL = `https://openlibrary.org/search.json?title=${query}`;

  query && debouncedFetch(URL);
}, [query]);

【讨论】:

  • 对于一般用途,我应该去抖动 GET 请求或输入(在搜索等输入中)?我的意思是,如果有一个通用的答案。
  • @TToprak1 你不想让你的 React 状态/UI 更新去抖动,所以我建议你去抖动高延迟的网络请求(或其他计算量大的回调)。不受控制的输入的onChange 回调可以被去抖动/节流。
猜你喜欢
  • 2012-11-13
  • 2021-04-18
  • 2014-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多