首页 > 解决方案 > 如何防止 react-native onTextChange 事件中的重复请求?

问题描述

/* eslint-disable react-native/no-inline-styles */
import React from 'react';
import {
  View,
  Text,
  Image,
  TouchableOpacity,
  FlatList,
  TextInput,
  StyleSheet,
  Dimensions,
} from 'react-native';
import Toast from 'react-native-root-toast';
import _ from 'lodash';
import api from '../utils/api';
const {width, height} = Dimensions.get('window');

const toast = str => {
  Toast.show(str);
};

export default class InputSearch extends React.Component {
  state = {
    keyword: '',
    listData: [],
    currentPage: 1,
    refreshing: false,
  };

  componentDidMount = () => {
    // this.fetchSearchData = _.debounce(this.fetchSearchData, 500);
  };

  handleOnChangeText = async text => {
    this.setState(
      {
        keyword: text,
        listData: [], // I cleared listData
      },
      this.fetchSearchData,
    );
  };

  fetchSearchData = async () => {
    const {keyword} = this.state;
    try {
      const data = await api('/upload/video', {query: {keyword}});
      const {listData} = data;

      console.log('listData should be [] but is not', this.state.listData);

      this.setState({
        listData: this.state.listData.concat(listData),
        currentPage: this.state.currentPage + 1,
      });
    } catch (err) {
      console.log('saul fetchSearchDataError', err);
    }
  };

  render() {
    return (
      <View
        style={{
          height,
          backgroundColor: '#eee',
        }}>
        <TextInput
          style={{width: 375, padding: 20, backgroundColor: '#FFF'}}
          autoFocus={true}
          selectionColor={'#333'}
          onChangeText={text => {
            this.handleOnChangeText(text);
          }}
          value={this.state.keyword}
        />
        <FlatList
          keyboardShouldPersistTaps={'handled'}
          onEndReachedThreshold={0.1}
          keyExtractor={(item, index) => index.toString()}
          ListHeaderComponent={() => {
            return null;
          }}
          ListFooterComponent={() => {
            return null;
          }}
          horizontal={false}
          data={this.state.listData}
          renderItem={this.renderItem}
          refreshing={this.state.refreshing}
          onEndReached={() => {}}
          onRefresh={() => {}}
        />
      </View>
    );
  }
  renderItem = ({item, index, separators}) => {
    return (
      <TouchableOpacity activeOpacity={0.7} onPress={() => {}}>
        <Text>{item.title}</Text>
        <Image
          style={{width: 375 / 2, height: 100}}
          source={{uri: item.imageUrl}}
        />
      </TouchableOpacity>
    );
  };
}

const styles = StyleSheet.create({});

当我将 listData 设置为空白时,每次我更改 TxtInput 中的 Text 并从服务器获取数据时,我的状态 listData 应该为空。对吗?

但我在我的 UI 中得到了重复的视图。为什么 ?

我想当我在 TextInput 中更改我的文本时,多个请求同时发送到服务器,这使得状态随机更新,并且当我调用 this.setState() 时无法确定 listData 是否为空。如果我是对的,如何防止这种情况发生?

标签: javascriptreactjsreact-native

解决方案


推荐阅读