简体   繁体   English

React setState不立即更新组件视图

[英]React setState not immediately updating component view

I have a input field that is filtering the elements on of an array. 我有一个输入字段正在过滤数组中的元素。

The search results are always one keystroke behind, I assume because setState doesn't instantly update the view? 我猜搜索结果总是落后一键,因为setState不会立即更新视图吗? What's the best way to work around that? 解决此问题的最佳方法是什么?

class App extends Component {
  constructor() {
    super();
    this.state = {
      images:[],
      searchfield: '',
      filteredImages:[],
      suggestedKeywords:[],
      inputValue: ''
    }
  }

  onSearchChange = (event) => {
    this.setState({searchfield: event.target.value});
    this.setState({inputValue: event.target.value});
    let filteredImages = this.state.images.filter(image => {
      return image.labels.includes(this.state.searchfield.toLowerCase());
    });
    console.log(event.target.value);
    this.setState({filteredImages});
  }
}

const SearchBox = ({searchfield, searchChange, inputValue}) => {
  return (
    <div>
      <input 
      type="search"
      value={inputValue}
      onChange={searchChange}
      placeholder="Search images..."
      />
    </div>
  );
}

The search results are always one keystroke behind, I assume because setState doesn't instantly update the view? 我猜搜索结果总是落后一键,因为setState不会立即更新视图吗? What's the best way to work around that? 解决此问题的最佳方法是什么?

That isn't the problem. 那不是问题。

Your problem is that you are assuming updates to setState occur instantly. 您的问题是您假设对setState的更新会立即发生。

this.setState({searchfield: event.target.value}); //You update searchfield here
return image.labels.includes(this.state.searchfield.toLowerCase()); 
//but this.state.searchfield doesn't reflect the update yet!

So instead, simply work off of the updated value rather than the one from the store. 因此,只需处理更新后的值,而不是商店中的值即可。

return image.labels.includes(event.target.value.toLowerCase()); 

setState is asynchronous, so you will be filtering by the old searchfield when you do this.state.searchfield.toLowerCase() . setState是异步的,因此执行this.state.searchfield.toLowerCase()时, this.state.searchfield.toLowerCase()旧的搜索searchfield进行过滤。 With this in mind you could do something like this instead: 考虑到这一点,您可以改为执行以下操作:

onSearchChange = (event) => {
  const { value } = event.target;
  const newState = {
    searchField: value,
    inputValue: value
  };

  newState.filteredImages = this.state.images.filter(image => {
    return image.labels.includes(value.toLowerCase());
  });

  this.setState(newState);
}

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

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