使用查询在api调用上触发useEffect

时间:2019-12-15 19:55:56

标签: reactjs redux react-hooks

我正在尝试使用React Hooks构建Search组件,而最主要的功能是当我在输入中放入一个Word时,我用该单词进行API调用,并返回与之匹配的单词

现在组件看起来像这样

import React, { useState, useEffect } from 'react';
import axios from 'axios';
import './SearchBar.css';

export function SearchBar() {
  const [query, setQuery] = useState('');
  const [searchResults, setSearchResults] = useState([]);
  const handleChange = event => {
    setQuery(event.target.value);
    console.log(event);
  };

  useEffect(() => {
    const fetchCities = query => {
      const uri = 'http://0.0.0.0:8000/v1/autocomplete/';
      axios
        .get(uri, {
          params: {
            q: query
          }
        })
        .then(response => {
          const data = response.data.filter(name =>
            name.toLowercase().includes(query)
          );
          setSearchResults(data);
          console.log('searchResults' + searchResults);
        })
        .catch(err => {
          console.log(err); //I know this is nothign but im running out of time tbh
        });
    };

    fetchCities();
  }, [query]);

  const handleSubmit = evt => {
    /*  evt.preventDefault();
    alert(apiCall());
    reset(); */
  };
  return (
    <form onSubmit={handleChange} className='display'>
      <input
        type='text'
        placeholder='Search'
        onChange={event => setQuery(event.target.value)}
      />
      <input type='submit' value='Submit' className='resize' />
      <ul>
        {searchResults.map(item => (
          <li>{item}</li>
        ))}
      </ul>
      <div></div>
    </form>
  );
}

现在在页面加载时出现此错误

xhr.js:166 GET http://0.0.0.0:8000/v1/autocomplete/ 400 (Bad Request)
dispatchXhrRequest @ xhr.js:166
xhrAdapter @ xhr.js:16
dispatchRequest @ dispatchRequest.js:49
Promise.then (async)

当我只希望在提交表单时进行API调用。有帮助吗?

2 个答案:

答案 0 :(得分:0)

我对您的代码示例做了一些更新:

在我看来,主要问题是获取网址未运行

import ReactDOM from "react-dom";
import React, { useState, useEffect } from "react";
import axios from "axios";

function App() {
  const [query, setQuery] = useState("");
  const [searchResults, setSearchResults] = useState([]);
  const handleChange = event => {
    setQuery(event.target.value);
  };

  useEffect(() => {
    const fetchCities = qry => {
      const uri = "https://www.mocky.io/v2/5df693273400002900e5a5f3";

      axios
        .get(uri, {
          params: {
            q: qry
          }
        })
        .then(response => {
          const data = response.data.tags.filter(name =>
            name.toLowerCase().includes(qry)
          );
          setSearchResults(data);
        })
        .catch(err => {
          console.log("error", err); //I know this is nothign but im running out of time tbh
        });
    };

    fetchCities(query);
  }, [query]);

  const handleSubmit = evt => {
    evt.preventDefault();
  };
  return (
    <form method="POST" onSubmit={handleChange} className="display">
      <input
        type="text"
        placeholder="Search"
        onChange={event => setQuery(event.target.value)}
      />
      <input
        type="submit"
        onClick={handleSubmit}
        value="Submit"
        className="resize"
      />
      <ul>
        {searchResults.map(item => (
          <li>{item}</li>
        ))}
      </ul>
      <div />
    </form>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

答案 1 :(得分:0)

var $ = function (id) {return document.getElementById(id);} "use strict"; var scoreArray = []; var dispArray = []; var displayScores = function () { var totalScore = 0; var numberOfScores = 0; var averageScore = 0; numberOfScores = scoreArray.length; //loop to find the total score for (var i=0;i<numberOfScores;i++) { totalScore = totalScore + scoreArray[i]; } //find the average averageScore = totalScore/numberOfScores; var st=""; //put the string in the display array for(var i=0; i<numberOfScores;i++) { st += (dispArray[i]+"\n"); } //display the average score $("#average_score").val(averageScore.toString()); $("#scores").val(st); }; $("#add_button").click(function(){ var scoreNumber = parseInt( $("#score").val()); var scoreString = $("#last_name").val() + ", " + $("first_name").val() + ": " + $("#score").val(); scoreArray.push(scoreNumber); dispArray.push(scoreString); displayScores(); //reset the values $("#first_name").val(""); $("#last_name").val(""); $("#score").val(""); $("#first_name").focus(); }); //function to clear the contents of the form $("#clear_button").click(function(){ //empty the arrays scoreArray=[]; dispArray=[]; //reset the values in the form $("#scores").val(""); $("#first_name").val(""); $("#last_name").val(""); $("average_score").val(""); $("#score").val(""); }); //function to sort the scores based on the last name that was entered $("#sort_button").click(function(){ var mylen = scoreArray.length; //sorting for(var kk=0;kk<mylen;kk++) { for(var aa = 1; aa<(mylen-kk);aa++) { var xp1 = dispArray[aa-1].split(" "); var lname1 = xp1[0]; lname1 = lname1.slice(0, -1); var xp2 = dispArray[aa].split(" "); var lname2 = xp2[0]; lname2 = lname2.slice(0, -1); if (lname1 > lname2){ var tp1 = scoreArray[aa]; scoreArray[aa]=scoreArray[aa-1]; scoreArray[aa-1] = tp1; var tp2 = dispArray[aa]; dispArray[aa]=dispArray[aa-1]; dispArray[aa-1] = tp2; } } } //display the scores $("#scores").val(""); var st=" "; for(var i=0;i<dispArray.length;i++) { st += (dispArray[i]+"\n"); } //display the sorted scores $("scores").val(st); }); $("#first_name").focus(); 将在您的组件首次安装时触发,因此您需要在其中包含useEffect语句来决定是否要进行API调用:

if

但是,如果您只想在提交表单时触发API调用,那么我将简化您的代码:

useEffect(() => {
  if (query === "") return

  const fetchCities = query => {
    // ...
  }
  fetchCities()
}, [query])

这样,您不必在每次在function SearchBar() { const [query, setQuery] = useState('') // ... const handleSubmit = (event) => { event.preventDefault() const uri = '...' axios.get(uri, { params: { q: query } }) .then(response => { // ... setSearchResults(data) }) .catch(err => { ... }) } const handleQueryChange = (event) => { setQuery(event.target.value) } return ( <form onSubmit={handleSubmit}> <input type="text" placeholder="Search" onChange={handleQueryChange} /> <input type="submit" value="Submit" /> {...} </form> ) 字段中输入新字符时都调用API端点。单击search只会调用一次。

有关示例,请参见以下submit链接: