Проблема с плоским списком при изменении состояния [React Native]

#javascript #reactjs #react-native

#javascript #reactjs #react-native

Вопрос:

Я работаю над приложением для ввода данных, которое будет обрабатывать много данных. В настоящее время я использую flatlist для отображения введенных пользователем данных. Но когда пользователь непрерывно вводит данные, производительность приложений резко падает. Ранее у меня была такая же проблема, но я использовал встроенную таблицу данных react-native-paper. Итак, для устранения этой проблемы я использовал flatlist, но здесь все еще существует та же проблема. Когда состояние постоянно обновляется, вся производительность падает. Я видел много проблем, связанных с проблемой производительности в reactnative flatlist. Есть ли какой-либо способ преодолеть эту проблему.

это код, который я использовал

 const Item = ({ count,digit,countsum }) => (
  <View style={styles.itemcontainer}>
      <View style={styles.item}>
          <Text style={styles.title}>{digit}</Text>
      </View>
      <View style={styles.item}>
          <Text style={styles.title}>{count}</Text>
      </View>
      <View style={styles.item}>
          <Text style={styles.title}>{countsum}</Text>
      </View>
  </View>
);

const renderItem = ({ item }) => ( console.log(item),
  <Item count={item.count} digit={item.digit} countsum={item.countsum} />
);

const Componentinput = React.memo(({data,setListData,scrollref}) => {
  const countRef = React.useRef();
  const digitRef = React.useRef();
  const values = React.useRef({ digit: '', count: '' });

  const onSubmitPress = async () => {
    const { digit, count } = values.current;
    const digitError = numberValidator(digit)
    const countError = numberValidator(count)
    const usertoken = await AsyncStorage.getItem("@userToken")
    if (digitError || countError) {
      alert('error occured')
      return
    }else if(digit.length < 3 || digit.length > 3){
      alert('enter 3 digit')
      return
    }
    let date = moment().format('YYYY-MM-DD HH:mm:ss');
    setListData([...data, {digit, count, countsum:'', created_at:date}])
    axios
    .post(
      constants.BASE_URL 'savedata',
      { 
        digit: digit,
        count:count,
        created_at:date,
        token: usertoken
      },
      {
        headers: {
          "Content-Type": "application/json"
        }
      }
    )
    .then(scrollref.current.scrollToEnd({animated: true}))
    .then(countRef.current.clear())
    .then(digitRef.current.clear())
    .then(values.current = {digit: '', count: ''},digitRef.current.focus())
    .then(response => { console.log('success');
    })
    .catch(error => {
      // setLoading(false)
      showMessage({
        message: "Error Occured",
        description: "Oops!! Please try again",
        type: "danger",
        color: "#fff",
        icon: "danger",
        floating: true,
      });
    });

  }
  
  return (
    <View style={styles.fixedform}>
      <View style={styles.textinputViewleft}>
          <NumberInput
            style={styles.textinput}
            ref={digitRef}
            label="Digit"
              autoCorrect={false}
              autoCompleteType="off"
              defaultValue=""
              clearTextOnFocus={true}
               onChangeText={(text) => {
              values.current.digit = text;
              if (text.length === 3) {
                countRef.current.focus();
              }
            }}
            keyboardType="numeric"
            maxLength={3}
            minLength={3}
          />
        </View>
        <View style={styles.textinputView}>
          <NumberInput
            style={styles.textinput}
            ref={countRef}
            onChangeText={(text) => {
              values.current.count = text;
            }}
            label="Count"
            keyboardType="numeric"
            maxLength={3}
          />
        </View>
      <View style={styles.textinputView}>
          <Button style={styles.buttonView} mode="contained" onPress={onSubmitPress} >Submit</Button>
      </View>
    </View>
  )
});

const Dashboard = ({ navigation }) => {
  const [listdata, setListData] = useState([])
  const scrollViewRef = useRef();
  const ITEM_HEIGHT = 200;
  const getItemLayout = useCallback(
    (data, index)=>({
      length: ITEM_HEIGHT,
      offset: ITEM_HEIGHT * index,
      index,
    }),
  );
  

  return (
    <Background>
      <Header style={styles.headermargin}></Header>
      <View style={styles.datatable}>
      <ScrollView
              ref={scrollViewRef}
              style={{ marginBottom: 70 }}
              refreshControl={
                <RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
              }>
        <SafeAreaView style={styles.container}>
            <FlatList
                data={listdata}
                renderItem={renderItem}
                keyExtractor={item => item.created_at}
                maxToRenderPerBatch={2}
                getItemLayout={getItemLayout}
            />
        </SafeAreaView>
      </ScrollView>
      </View>
      <Componentinput 
        data={listdata} 
        setListData={setListData} 
        scrollref={scrollViewRef} 
      />
    </Background>
  )
}

export default React.memo(Dashboard)
 

Комментарии:

1. Я думаю Flatlist , что внутри Scrollview — это большой нет-нет, вам действительно нужно поместить его внутрь?

2. @Konstantin Мне нужно фиксированное поле ввода, поэтому я сделал так