简体   繁体   English

如何使用 reactjs 从多个 API 获取搜索结果

[英]How do I fetch search results from multiple API using reactjs

I am new to ReactJS and I am trying to create a search feature with react by fetching data from multiple API.我是 ReactJS 的新手,我正在尝试通过从多个 API 获取数据来创建一个搜索功能。 Below is the Search.js file.下面是Search.js文件。 I tried so many times to make it functions and make the results appear live while typing.我尝试了很多次以使其发挥作用并在打字时使结果实时显示。 I however keep on getting this error message TypeError: values.map is not a function .但是,我不断收到此错误消息TypeError: values.map is not a function Where am I going wrong and how do I fix it?我哪里出错了,我该如何解决?

 function Search() { const [input, setInput] = useState(""); const [results, setResults] = useState([]); const urls = [ 'https://jsonplaceholder.typicode.com/posts/1/comments', 'https://jsonplaceholder.typicode.com/comments?postId=1' ] Promise.all(urls.map(url => fetch(url).then((values) => Promise.all(values.map(value => value.json()))).then((response) => response.json()).then((data) => setResults(data)).catch(error => console.log('There was a problem,', error)) ). []) const handleChange = (e) => { e;preventDefault(). setInput(e.target;value). } if (input.length > 0) { results.filter((i) => { return i.name.toLowerCase();match(input). }) } return ( < div className = "search" htmlFor = "search-input" > < input type = "text" name = "query" value = { input } id = "search" placeholder = "Search" onChange = { handleChange } /> { results,map((result. index) => { return ( < div className = "results" key = { index } > < h2 > { result.name } < /h2> < p > { result.body } < /p> { result } < /div> ) }) } </div> ) }
 .search { position: relative; left: 12.78%; right: 26.67%; top: 3%; bottom: 92.97%; }.search input { /* position: absolute; */ width: 40%; height: 43px; right: 384px; margin-top: 50px; top: 1.56%; bottom: 92.97%; background: rgba(0, 31, 51, 0.02); border: 1px solid black; border-radius: 50px; float: left; outline: none; font-family: 'Montserrat', sans-serif; font-style: normal; font-weight: normal; font-size: 16px; line-height: 20px; /* identical to box height */ display: flex; align-items: center; /* Dark */ color: #001F33; } /* Search Icon */ input#search { background-repeat: no-repeat; text-indent: 50px; background-size: 18px; background-position: 30px 15px; } input#search:focus { background-image: none; text-indent: 0px }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

Issue问题

  1. The response you get from fetch(url) is just the one single response, so there's nothing to map.您从fetch(url)获得的响应只是一个响应,因此 map 没有任何内容。
  2. The data fetching occurs in the function body of the component, so when working this causes render looping since each render cycle fetches data and updates state.数据获取发生在组件的 function 主体中,因此在工作时会导致渲染循环,因为每个渲染周期都会获取数据并更新 state。
  3. The input.length > 0 filtering before the return does nothing since the returned filtered array isn't saved, and it also incorrectly searches for sub-strings.在返回之前input.length > 0过滤什么都不做,因为返回的过滤数组没有被保存,并且它也错误地搜索子字符串。
  4. Attempt to render result object in the render function, objects are invalid JSX尝试在渲染 function 中渲染result object,对象无效 JSX

Solution解决方案

  1. Skip the .then((values) => Promise.all(values.map((value) => value.json()))) step and just move on to accessing the JSON data.跳过.then((values) => Promise.all(values.map((value) => value.json())))步骤,然后继续访问 JSON 数据。
  2. Move the data fetching into a mounting useEffect hook so it's run only once.将数据获取移动到挂载的useEffect挂钩中,使其仅运行一次。
  3. Move the filter function inline in the render function and use string.prototype.includes to search.将过滤器 function 移动到渲染 function 中并使用 string.prototype.includes 进行搜索。
  4. Based on other properties rendered and what is left on the result object I'll assume you probably wanted to render the email property.基于呈现的其他属性以及result object 上剩下的内容,我假设您可能想要呈现email属性。

Code:代码:

function Search() {
  const [input, setInput] = useState("");
  const [results, setResults] = useState([]);

  useEffect(() => {
    const urls = [
      "https://jsonplaceholder.typicode.com/posts/1/comments",
      "https://jsonplaceholder.typicode.com/comments?postId=1"
    ];

    Promise.all(
      urls.map((url) =>
        fetch(url)
          .then((response) => response.json())
          .then((data) => setResults(data))
          .catch((error) => console.log("There was a problem!", error))
      ),
      []
    );
  }, []);

  const handleChange = (e) => {
    e.preventDefault();
    setInput(e.target.value.toLowerCase());
  };

  return (
    <div className="search" htmlFor="search-input">
      <input
        type="text"
        name="query"
        value={input}
        id="search"
        placeholder="Search"
        onChange={handleChange}
      />
      {results
        .filter((i) => i.name.toLowerCase().includes(input))
        .map((result, index) => {
          return (
            <div className="results" key={index}>
              <h2>{result.name}</h2>
              <p>{result.body}</p>
              {result.email}
            </div>
          );
        })}
    </div>
  );
}

编辑 how-do-i-fetch-search-results-from-multiple-api-using-reactjs

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM