开发者问题收集

当查询为空时,如何处理 API 返回数据?

2022-10-25
1084

我正在从 API 中获取数据并将其显示在我的网站前端

{/*fetching the the data from an API*/}
  function searchArtistes() {
    const options = {
      method: "GET",
      headers: {
        "X-RapidAPI-Key": "86f453f970msh48154777add2da0p1e185cjsn969596f1a317",
        "X-RapidAPI-Host": "spotify81.p.rapidapi.com",
      },
    };

    fetch(
      `https://spotify81.p.rapidapi.com/search?q=${searchInput}&type=multi&offset=0&limit=10&numberOfTopResults=5`,
      options
    )
      .then((response) => response.json())
      .then((response) =>
        setArtisteData(
          response.artists.items.map((artist) => artist.data.profile.name)
        )
      )
      .catch((err) => console.error(err));
  }
{/* function fetching the data is called by an onChange event listener in the input */}
          <form className="search-input flex justify-between  md:items-center">
            <div className="flex md:flex-row-reverse">
              <input
                placeholder="search artists"
                onChange={() => {
                  handleChange(event);
                  searchArtistes();
                }}
                className="search ml-6 "
              />
              <img
                src={search}
                className="search-icon md:ml-12 lg:ml-14 2xl:ml-18"
              />
            </div>
          </form>


{/*Displaying it on the interface*/}
        <div>
          <ul className="flex flex-col items-center text-white">
            {artisteData.map((name) => (
              <li className="cursor-pointer pt-1">{name}</li>
            ))}
          </ul>
        </div>

但问题是,即使查询为空,API 仍然会返回数据,如下图所示:

在此处输入图片描述

我该怎么办?

2个回答

这是因为对于查询参数而言,空字符串仍然是字符串。据我所知,在所有情况下,搜索文本 "" 只会返回未过滤的结果,而不会阻止您的代码发送 API 调用本身。您需要跟踪搜索输入值的状态,并在其为空时避免发送 API 查询。

但是,您的代码还有更严重的问题需要担心。首先,每次搜索输入发生变化时,您都会发送 API 调用,这严重浪费资源。请在本地跟踪搜索文本的变化,并仅在用户提交搜索查询时发送 API 查询。

或者,如果您希望结果在用户输入查询时动态更新,请获取未过滤的结果,将其存储在本地,并在查询文本在 UI 中发生变化时在本地过滤它们。

Karthik Sivasubramaniam
2022-10-25

如果这是一个功能组件,请使用 useState() 钩子将初始 artisteData 的状态设置为 null,如下所示:

const [artisteData, setArtisteData] = useState(null);

这个想法是,只有当数据有数据时才将状态设置为数据。

在 .map 之前添加“?”运算符。这会在运行数据集之前检查数组是否为空

试试这个:

<div>
    <ul className="flex flex-col items-center text-white">
        {artisteData?.map((name) => (
            <li className="cursor-pointer pt-1">{name}</li>
         ))}
    </ul>
</div>

编辑:

我还需要提到,在更改时调用该函数会浪费资源。改用按钮调用此 onSubmit()。

如果这仍然是您想要采用的方法(我不建议这样做),您可以随时按如下方式实现它:

<div>
    <ul className="flex flex-col items-center text-white">
        {artisteData?.map((name) => (
            if(name !== null and name !== "")
            <li className="cursor-pointer pt-1">{name}</li>
         ))}
    </ul>
</div>

这会在 DOM 中创建元素之前检查 Artist 名称是否为空。

Dirk Odendaal
2022-10-25