Javascript 如何在状态具有特定值时运行API调用

Javascript 如何在状态具有特定值时运行API调用,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我在自学React,其中一个练习是使用axios从API获取国家列表 const fetchCountries = () => { axios.get("https://restcountries.eu/rest/v2/all").then(response => { setCountries(response.data); }); }; React.useEffect(fetchCountries, []); 然后,当用户输入时,国家列表将被

我在自学React,其中一个练习是使用axios从API获取国家列表

const fetchCountries = () => {
    axios.get("https://restcountries.eu/rest/v2/all").then(response => {
      setCountries(response.data);
    });
  };

  React.useEffect(fetchCountries, []);
然后,当用户输入时,国家列表将被过滤

  const handleInputChange = event => {

    const filter = event.target.value; // current input value
    let matchingCountries = query !== ''
        ? countries.filter(country => country.name.toLowerCase().indexOf(query.toLowerCase()) !== -1)
        : countries;
    setQuery(filter);
    setMatches(matchingCountries)
    console.log('matches', matches)
    console.log('query', query)
  };
我的目标是,当一个国家匹配时,会触发一个新的API请求来获取天气,但这不是我的问题,而是时间。当匹配单个国家时,我将呈现一些关于该国家的数据,然后获取并呈现单个国家首都的天气细节

我遇到的一个问题是,当我设置状态时,值似乎总是落后一步。例如,在这种情况下,当你进入FRA时,你应该得到法国。然而,我必须进入弗兰才能获得比赛。当我不使用状态变量进行匹配时,就不会发生这种情况。这成为一个问题,因为我需要在匹配数=1时运行下一个API调用,但匹配状态的长度总是错误的


所以我想知道1。如何获得匹配国家的正确状态。二,。当我应该运行第二个API调用而不进入无限循环时

唯一的问题是您在handleInputChange中使用了旧的查询值

记住,即不会立即生效

以下是更新版本:

const handleInputChange = event => {

  const filter = event.target.value; // current input value
  let matchingCountries = filter ? <code here>
  // ...
  setQuery(filter);
};
使用关注点分离的useEffect解决方案 1函数应该做1件事

handleInputChange更新状态 useEffect更新状态 但它们并不耦合。 稍后,您可能会有一个名为handleDropdownChange的新函数,用于更新状态 在这种情况下,您不需要修改useEffect

归根结底,我们开发人员不喜欢重写东西


还有一种解决方案不推荐直接使用@Joseph D提供的event.target.value。

1问题的原因如下:

let matchingCountries = filter !== ''
        ? countries.filter(country => country.name.toLowerCase().indexOf(query.toLowerCase()) !== -1)
        : countries;
如果使用query而不是filter变量,则处理程序函数应如下所示:

const handleInputChange = event => {

    const filter = event.target.value; // current input value
    let matchingCountries = filter !== ''
        ? countries.filter(country => country.name.toLowerCase().indexOf(filter.toLowerCase()) !== -1)
        : countries;

    setQuery(filter);
    setMatches(matchingCountries)
  };
2在何处运行下一个API调用:
出于研究目的,我不建议您使用一些应用程序状态管理库,比如redux。只需在setFilter和setQuery之后调用它即可。它将按预期运行。因为调用API也是异步的,所以它将在setQuery和setFilter之后执行。同步函数console.log不会发生这种情况。

Yes!好的,这就实现了匹配。我想我现在只知道一次国家队比赛,但下一次我想知道一次国家队比赛的天气情况。我什么时候开一辆新的,明白吗?昨天,我在一个无限循环中快速浏览了天气api。哎哟。@helgatheviking更新了答案,添加了另一个效果来检查匹配情况。Length如果我简化输入,这确实会让天气API调用激发,而不是像以前那样无限激发。这给我留下了一些关于其他事情的问题,但我认为这解决了问题。谢谢约瑟夫!当setWeather改变天气状态时,组件会重新渲染吗?@helgatheviking是,因为它是一种状态。i、 e.const[weather,setWeather]=React.useState{}。很高兴能帮上忙!谢谢你,梅德特!将setMatches分离成另一个效果与将其与handleInputChange组合相比有什么好处?@helgatheviking其关注点的分离,1个函数应该做1件事,handleInputChange更新状态,useEffect更新状态,但它们不耦合。稍后,您可能会有一个名为handleDropdownChange的新函数,该函数将更新状态,在这种情况下,您不需要修改UseEffect是有意义的。谢谢你的解释!
let matchingCountries = filter !== ''
        ? countries.filter(country => country.name.toLowerCase().indexOf(query.toLowerCase()) !== -1)
        : countries;
const handleInputChange = event => {

    const filter = event.target.value; // current input value
    let matchingCountries = filter !== ''
        ? countries.filter(country => country.name.toLowerCase().indexOf(filter.toLowerCase()) !== -1)
        : countries;

    setQuery(filter);
    setMatches(matchingCountries)
  };