【问题标题】:onChange triggers only after 2 text inputsonChange 仅在 2 个文本输入后触发
【发布时间】:2017-10-02 12:28:24
【问题描述】:

我的“TextInput”有一个奇怪的行为。我正在尝试根据 TextInput 条目过滤 ListView:

export default class SearchTabScreen1 extends Component {
  constructor(props) {
    super(props);
    this.state = {
      searchText:'',
      data:[]
    };
}

setSearchText(event) {
    var reset = realm.objects('User');
    if (this.state.data !== reset){
    this.setState({
      data:realm.objects('User')
    });

    const searchText = event.nativeEvent.text;
    this.setState({searchText:searchText});
    console.log(this.state.searchText);

    var searchString = this.state.searchText;
    if(searchString != ""){
      let searchResult = realm.objects('User').filtered('name BEGINSWITH[c] $0', searchString);
      var filteredData = searchResult;

      this.setState({
        data : filteredData
      });
      console.log("FILTERED", filteredData);
    }
  }
}

render() {
      return (
        <View style={{flex: 1, padding: 20}}>
          <TextInput
            ref="recherche"
            placeholder="Search"
            autoCorrect={true}
            returnKeyLabel="search"
            underlineColorAndroid="black"
            value = {this.state.searchText}
            onChange={this.setSearchText.bind(this)}
          />
          <ListViewDico
            navigator={this.props.navigator}
            dataFromParent={this.state.data}
          />
        </View>

问题是当我键入“L”时,例如,在 TextInput 中,日志:console.log(this.state.searchText); 什么也不显示。

只有在我输入第二个字符(不管它是什么)等之后,日志才会显示这个“L”。

我总是在“t+1 条目”得到响应。

我将不胜感激,谢谢。

【问题讨论】:

    标签: javascript listview reactjs react-native textinput


    【解决方案1】:

    发生这种情况的原因是setState 不会立即改变状态,而是需要时间,并且由于Javascript 是异步的,所以您的console.log() 在状态改变之前被执行,因此您不会得到更新值,仅在下次看到旧值时执行。解决办法是调用setState callback中的console.log()

     this.setState({searchText:searchText}, () => {
         console.log(this.state.searchText);
     });
    

    代码:

    setSearchText(event) {
        var reset = realm.objects('User');
        if (this.state.data !== reset){
        this.setState({
          data:realm.objects('User')
        });
    
        const searchText = event.nativeEvent.text;
        this.setState({searchText:searchText}, function() {
             console.log(this.state.searchText);
        });
    
    
        var searchString = searchText;
        if(searchString != ""){
          let searchResult = realm.objects('User').filtered('name BEGINSWITH[c] $0', searchString);
          var filteredData = searchResult;
    
          this.setState({
            data : filteredData
          }, function() {
              console.log("FILTERED", filteredData);
          });
    
        }
      }
    }
    

    【讨论】:

    • 是的,我忘记了 setState !但这也影响了我的 UI:当我输入“L”时,我的 ListView 不会更新,但是在我输入“Lx”(或其他 2 个字符)之后,我在 ListView 中得到了所有以“L”开头的项目。有可能解决这个问题吗?
    • 是的,这是因为在更新状态后应该再次使用搜索字符串,否则使用来自event.native.text的值
    • 好的!我直接使用了event.native.text,它现在运行良好。我通过 searchText 变量在 if 语句中使用它。我的过滤器现在工作正常 :) 非常感谢您的帮助!
    猜你喜欢
    • 2017-06-03
    • 2017-07-10
    • 2020-03-28
    • 1970-01-01
    • 1970-01-01
    • 2019-12-09
    • 1970-01-01
    • 2020-10-05
    • 2011-10-01
    相关资源
    最近更新 更多