React JS 在 for 循环中更新 setState

React JS updating setState in a for loop

我希望能够将数组值添加到 React JS 中的 setState。基本上我正在为城市做一个搜索栏。每次用户键入时,它都会更新 setState 以包含更多过滤搜索。基本上,如果用户想要搜索 'Los Angeles, California',他们会先输入 'L'。然后程序搜索所有以 'L' 开头的城市并将它们添加到 setState。然后用户继续 'Lo',然后程序搜索所有以 'Lo' 开头的城市,并仅使用以 'Lo' 开头的城市更新 setState 等等第四。

出于某种原因,它总是重复同一个城市 100 次。因此,如果此人输入 'L',它将第一个城市添加 100 次到 setState,而不是前 100 个不同的城市。下面是我的代码。我在 for 循环中使用它。

cities已经是美国所有城市和州的州。 thisCitythisState 已经声明。

for (var i = 0; i < cities.length; i++){
      if(cities[i].city.toUpperCase().startsWith(e.target.value.toUpperCase())){
        thisCity = cities[i].city;
        thisState = cities[i].state;

        setSuggest((suggest) => [...suggest, {id: Math.random() * 1000,
        city: thisCity,
        state: thisState}])
      }
}

这里有一些问题。

首先,将var i = 0替换为let i = 0var 全局范围,其中 let 范围到块。

其次,您还没有声明变量thisCitythisState,所以它们也是全局设置的。使用 const 声明它们,因为它们不会改变。

无论何时调用 setSuggest 中的回调函数,它都会将最后一个值设置为 thisCity 和 thisState,而不是该块范围内的值。这是因为回调函数是稍后执行的。如果在 setSuggest 中放置一个 console.log,在 for 循环的末尾放置另一个,您会看到 for 循环的日志出现在 setSuggest 的日志之前。

最后,您应该先弄清楚城市列表,然后再设置您的州。这将显着提高性能。总的来说,我建议替换你的 for 循环以支持使用数组方法 .filter:

const compareTo = e.target.value.toUpperCase();
const suggestions = cities.filter(city => (
  city.toUpperCase().startsWith(compareTo)
));
setSuggest(suggestions);

我发现这篇文章可以帮助您更好地理解变量范围:https://dmitripavlutin.com/javascript-scope-gotchas/