ReactNative - 键盘由于重新渲染而关闭 - 由于数组更新的重新渲染而无法更新或键入值

问题描述 投票:0回答:1

有人可以检查一下这段代码吗?我在更新文本框中的值时遇到问题。当 NEW_ITEM_CNT 中已存在值时,我无法键入或更新它。即使对于其他项目,它一次也只更新一个字符,并且键盘会消失,因为每个字符输入都会重新渲染。我已经为此苦苦挣扎了几乎一天。有人可以就我可能做错的事情提供指导吗?

我探索了各种选项,包括模糊、去抖和 onEndEditing,但它们似乎都不能解决问题。

import {
  View,
  Text,
  Colors,
  TouchableOpacity,
  Avatar,
} from 'react-native-ui-lib';
import React from 'react';
import {debounce} from 'lodash';
import {useDispatch} from 'react-redux';
import {useCallback} from 'react';
import FA5 from 'react-native-vector-icons/FontAwesome5';
import {Dimensions, TextInput} from 'react-native';

import {StyleSheet} from 'react-native';
import {theme} from 'galio-framework';
import {useState} from 'react';
import { useEffect } from 'react';

const {width, height} = Dimensions.get('window');

const TestingComp = props => {
  //const {params} = props.route.params;
  const dispatch = useDispatch();
  const [FinalList, setFinalList] = useState([]);

  useEffect(() => {

    setFinalList([{"DESCR": "Bed", "ITEM_TYPE_CD": "1-BED"}, {"CM_PREM_ID": "9297720000", "CM_SP_ID": "1ee4cc77-1ff5-3bcc-ee60-28bad4d6f762", "DESCR": "Pool/Fountain/Water", "FA_ID": "1371577927", "FO_ID": "1372274798", "ID": 157, "ITEM_CNT": "0", "ITEM_TYPE_CD": "1-GALLNS", "NEW_ITEM_CNT": "8686", "PREM_ID": "9297720000", "SP_ID": "1ee4cc77-1ff5-3bcc-ee60-28bad4d6f762", "USER_GENERATED": 0}, {"DESCR": "Student", "ITEM_TYPE_CD": "1-STDNT"}, {"DESCR": "Unit", "ITEM_TYPE_CD": "1-UNIT"}, {"DESCR": "Mopsink", "ITEM_TYPE_CD": "2-MOPSNK"}, {"DESCR": "Showers/Tubs", "ITEM_TYPE_CD": "2-SHWTUB"}, {"DESCR": "Sinks", "ITEM_TYPE_CD": "2-SINKS"}, {"DESCR": "Toilets", "ITEM_TYPE_CD": "2-TOILT"}, {"DESCR": "Urinals", "ITEM_TYPE_CD": "2-URINL"}, {"DESCR": "Clothes Washer", "ITEM_TYPE_CD": "3-CLSWSH"}, {"DESCR": "Dishwasher", "ITEM_TYPE_CD": "3-DSHWSH"}, {"DESCR": "Glasswasher", "ITEM_TYPE_CD": "3-GLSWSH"}, {"DESCR": "Hosebib", "ITEM_TYPE_CD": "3-HOSEBB"}, {"DESCR": "Pre-Rinse Spray", "ITEM_TYPE_CD": "4-PRSPRY"}, {"DESCR": "Dipperwell", "ITEM_TYPE_CD": "5-DPPRWL"}, {"DESCR": "Hood Washer", "ITEM_TYPE_CD": "5-HDWSHR"}, {"DESCR": "Pot Filler", "ITEM_TYPE_CD": "5-POTFLR"}, {"DESCR": "Pot Washer", "ITEM_TYPE_CD": "5-POTWSH"}, {"DESCR": "Rinse Table", "ITEM_TYPE_CD": "5-RNSTBL"}, {"DESCR": "Steam Table", "ITEM_TYPE_CD": "5-STMTBL"}, {"DESCR": "Wok Hood Wash", "ITEM_TYPE_CD": "5-WOKHOD"}, {"DESCR": "Wok Sink", "ITEM_TYPE_CD": "5-WOKSNK"}, {"DESCR": "Pedicure Sink", "ITEM_TYPE_CD": "6-PEDSNK"}, {"DESCR": "Cooling Towers", "ITEM_TYPE_CD": "7-COLTWR"}]);

  }, []);

  const handleIncrement = useCallback(
    index => {
      const updatedList = [...FinalList];
      const item = {...updatedList[index]};
      let count = parseInt(item.NEW_ITEM_CNT || 0);

      //5 character length - no specific reason but limited to 5 for now
      if (count < 100000) {
        item.NEW_ITEM_CNT = count + 1;
        updatedList[index] = item;
        setFinalList(updatedList);
      }
    },
    [FinalList],
  );

  const handleDecrement = useCallback(
    index => {
      const updatedList = [...FinalList];
      const item = {...updatedList[index]};
      let count = parseInt(item.NEW_ITEM_CNT || 0);

      if (count > 0) {
        item.NEW_ITEM_CNT = parseInt(count) - 1;
        updatedList[index] = item;
        setFinalList(updatedList);
      }
    },
    [FinalList],
  );

  //   const handleEndEditing = (index, value) => {
  //     //   setFinalList(prevItemList => {
  //     //     const updatedItemList = [...prevItemList];
  //     //     updatedItemList[index].NEW_ITEM_CNT = parseInt(value) || 0;
  //     //     return updatedItemList;
  //     //   });
  //   };
  //   const handleInputChange =
  //     (index, value) => {
  //       const updatedList = [...FinalList];

  //       const item = {...updatedList[index]};

  //       const numericValue = parseInt(value); // Convert input to an integer
  //       item.NEW_ITEM_CNT = isNaN(numericValue) ? 0 : numericValue;
  //       updatedList[index] = item;

  //       console.log('<---->', index, value, numericValue, item);
  //       setFinalList(updatedList);

  //       // console.log('Updating input at index', index, 'with value', value);
  //     };

  //   const debouncedInputChange = useCallback(
  //     debounce((index, value) => {
  //       console.log('DEBOUNCED: ', index);
  //       const updatedList = [...FinalList];
  //       const item = {...updatedList[index]};
  //       const numericValue = parseInt(value);
  //       item.NEW_ITEM_CNT = isNaN(numericValue) ? 0 : numericValue;
  //       updatedList[index] = item;
  //       setFinalList(updatedList);
  //     }, 300), // Adjust the debounce delay as needed
  //     [],
  //   );

  const onHandleChange = useCallback(
    debounce((value, index) => {
      // // Make a shallow copy of the current `data`.
      const updatedList = [...FinalList];
      // // Update the changed item.
      const item = {...updatedList[index]};
      //const newValue = parseInt(e.nativeEvent.text);
      const newValue = parseInt(value);
      item.NEW_ITEM_CNT = isNaN(newValue) ? 0 : newValue;
      updatedList[index] = item;
      console.log(newValue);
      setFinalList(updatedList);
    }, 1000),
    [FinalList],
  );

  const renderFixtures = useCallback(() => {
    return (
      <View flex margin-20 backgroundColor={Colors.white} borderRadius={10}>
        {FinalList &&
          FinalList?.map((item, index) => (
            <RenderFixtureItem
              key={index}
              item={item}
              index={index}
              onIncrement={handleIncrement}
              onDecrement={handleDecrement}
              onTextChange={onHandleChange}
              //onDebouncedInputChange={debouncedInputChange}
              //onInputChange={handleInputChange}
              //onEndEditing={handleEndEditing}
            />
          ))}
      </View>
    );
  }, [FinalList]);

  const RenderFixtureItem = useCallback(p => {
    // console.log('Rendering Fixture Item', item.ITEM_TYPE_CD);
    return (
      <View
        backgroundColor={Colors.white}
        borderBottomWidth={1}
        borderColor={Colors.grey60}
        borderRadius={0}>
        <View flex row spread padding-5 margin-5>
          <View flex marginB-3>
            <Text text80 grey10 numberOfLines={1}>
              {p.item?.ITEM_TYPE_CD}
            </Text>
            <Text text90 grey20>
              {p.item?.DESCR}
            </Text>
          </View>
          <View
            flex
            marginB-3
            row
            style={{
              flexDirection: 'row',
              justifyContent: 'space-evenly',
              flexWrap: 'wrap',
            }}>
            <View
              flex
              center
              style={{
                borderColor: Colors.green50,
                // borderRadius: 10,
                //  borderWidth: 1,
              }}>
              <Text grey20 text60>
                {p.item?.ITEM_CNT != null ? p.item.ITEM_CNT || '    ' : '  '}
              </Text>
            </View>

            <View row center marginT-10 marginR-10>
              <TouchableOpacity
                //disabled={parseInt(Count, 10) < 1}
                onPress={() => {
                  p.onDecrement(p.index);
                }}>
                <Avatar size={theme.SIZES.CARD_AVATAR_HEIGHT}>
                  <FA5
                    name="minus-circle"
                    size={theme.SIZES.CARD_AVATAR_HEIGHT / 2}
                  />
                </Avatar>
              </TouchableOpacity>

              <TextInput
                keyboardType="numeric"
                maxLength={5}
                // onEndEditing={e => {
                //   //onEndEditing(index, e.nativeEvent.text);
                // }}
                onChangeText={val => p.onTextChange(val, p.index)}
                //    onBlur={val => {
                //        onInputChange(index, val);
                //      }}
                // onChange={e => {
                //   onTextChange(e, index);
                // }}
                style={styles.fixtureTextField}
                value={p.item?.NEW_ITEM_CNT?.toString()}
                //value={FinalList[index]?.NEW_ITEM_CNT?.toString() || ''} // Ensure it's not undefined

                // value={item?.NEW_ITEM_CNT != null ? item?.NEW_ITEM_CNT.toString() : ''}
              />

              <TouchableOpacity
                onPress={() => {
                  p.onIncrement(p.index);
                }}>
                <Avatar size={theme.SIZES.CARD_AVATAR_HEIGHT}>
                  <FA5
                    name="plus-circle"
                    size={theme.SIZES.CARD_AVATAR_HEIGHT / 2}
                    backgroundColor={Colors.blue10}
                  />
                </Avatar>
              </TouchableOpacity>
            </View>
          </View>
        </View>
      </View>
    );
  });

  return <View flex>{renderFixtures()}</View>;
};

const styles = StyleSheet.create({
  container: {flex: 1, backgroundColor: Colors.grey70},

  slider: {
    backgroundColor: Colors.white,
    borderTopLeftRadius: 25,
    borderTopRightRadius: 25,
  },
  sliderContainer: {
    textAlign: 'left',
    padding: 10,
    margin: 10,
  },
  sliderTitle: {
    fontFamily: 'Lato-Bold',
    color: Colors.blue1,
    textAlign: 'left',
  },
  sliderText: {
    fontFamily: 'Lato-Bold',
    fontWeight: 'bold',
    textAlign: 'left',
    marginTop: 50,
    marginBottom: 50,
  },
  textField: {
    color: 'white',
    borderBottomWidth: 1,
    borderColor: Colors.white,
    paddingBottom: 4,
  },
  fixtureTextField: {
    //marginLeft: 20,
    color: Colors.blue10,
    textAlign: 'center',
    minWidth: 100,
    fontWeight: 'bold',
    fontSize: 22,
    borderWidth: 1,
    borderColor: Colors.grey60,
    borderRadius: 10,
    padding: 0,
    //paddingBottom: 4,
  },
});

export default TestingComp;

  
reactjs react-native rendering
1个回答
0
投票

如果有人正在寻找答案。尝试了不同的可能组合。有些确实解决了问题,但最终还是将 Formik 库与 FieldArray 一起使用。更容易且非常简单。

© www.soinside.com 2019 - 2024. All rights reserved.