简体   繁体   English

React JS 在 for 循环中更新 setState

[英]React JS updating setState in a for loop

I want to be able to add array values to a setState in React JS.我希望能够将数组值添加到 React JS 中的setState Basically I'm doing a search bar for cities.基本上我正在为城市做一个搜索栏。 Every time the user types, it will update the setState to include a more filtered search.每次用户键入时,它都会更新setState以包含更过滤的搜索。 Basically, if the user wants to search for 'Los Angeles, California', they'll type in 'L' first.基本上,如果用户想要搜索“加利福尼亚州洛杉矶”,他们会首先输入“L”。 So then the program searches for all the cities that start with 'L' and add them to the setState .因此,程序会搜索所有以“L”开头的城市并将它们添加到setState中。 Then the user proceeds 'Lo', then the program searches for all the cities that start with 'Lo' and updates the setState with only cities that start with 'Lo' and so on and so forth.然后用户继续“Lo”,然后程序搜索所有以“Lo”开头的城市,并仅使用以“Lo”开头的城市更新setState ,依此类推。

For some reason, it always repeats the same city 100 times.出于某种原因,它总是重复同一个城市 100 次。 So if the person types in 'L' it adds the first city 100 times to setState instead of the first 100 different cities.因此,如果该人键入“L”,它会将第一个城市添加到setState 100 次,而不是前 100 个不同的城市。 Below is my code.下面是我的代码。 I'm using it in a for loop.我在 for 循环中使用它。

cities is already a state with every city and state in the US. cities已经是每个城市的 state 和美国的 state。 thisCity and thisState is already declared. 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}])
      }
}

There are a few issues here.这里有几个问题。

First, replace var i = 0 with let i = 0 .首先,将var i = 0替换为let i = 0 var scopes globally, where as let scopes to the block. var作用域是全局的,而let作用域是块。

Secondly, you have not declared the variables thisCity and thisState , so they are also being set globally.其次,您没有声明变量thisCitythisState ,因此它们也是全局设置的。 Declare them using const , since they won't be changing.使用const声明它们,因为它们不会改变。

Whenever your callback function inside setSuggest is called, it's getting the very last value set to thisCity and thisState, instead of the value scoped to that block.每当调用 setSuggest 中的回调 function 时,它会获取设置为 thisCity 和 thisState 的最后一个值,而不是该块范围内的值。 This is because the callback function is executed later.这是因为回调 function 稍后执行。 If you put a console.log inside setSuggest, and another one at the end of your for loop, you'd see the log for the for loop occur before the one for the setSuggest.如果您将一个console.log 放在setSuggest 中,另一个放在for 循环的末尾,您会看到for 循环的日志出现在setSuggest 的日志之前。

Lastly, you should figure out the list of cities first, and then set your state.最后,你应该先弄清楚城市列表,然后设置你的 state。 This will be significantly more performant.这将显着提高性能。 Overall, I'd recommend replacing your for-loop in favor of using the array method .filter :总的来说,我建议更换你的 for 循环,以支持使用数组方法.filter

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

I found this article that may help you understand variable scope a little better: https://dmitripavlutin.com/javascript-scope-gotchas/我发现这篇文章可以帮助您更好地理解变量 scope: https://dmitripavlutin.com/javascript-scope-gotchas/

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

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