ReactNative动态表单TextInput失去焦点

时间:2020-08-25 19:17:44

标签: react-native

我看过其他有关如何应用动态textInputs的示例,我对问题的根源有所了解,但我仍未找到解决方案...我知道每次键入时都会发生重新渲染,因为它会调用钩子和也许是因为我在同一个调用中用输入构建了一个由多行和多个单元组成的数组,所以它们都被重新渲染了……但是我找不到使它工作的正确方法。

//CustomTableView.tsx
import React, {useState} from 'react';
import {View, StyleSheet, Text} from 'react-native';
import TextInputColumn from './TextInputColumn';
import UniqueId from '@rpearce/simple-uniqueid';

function multipleOf(value: number) {
  var multiples = [];
  for (var i = 0; i < value; i++) {
    if (i % 4 === 0) {
      // divide by the number
      multiples.push(i); // add the current multiple found to the multiples array
    }
  }

  if (multiples[multiples.length - 1] !== value) {
    multiples.push(value);
  }

  return multiples;
}

const CustomTableView = () => {
  const [inputData, setInputData] = useState<string[]>([]);

  const handleInputChange = (text: string, index: number) => {
    let data: string[] = [...inputData];
    console.log('text:' + text);
    data[index] = '';

    if (/^\d+$/.test(text)) {
      data[index] = text;
    }
    console.log(text + index);
    setInputData(data);
  };

  const renderRows = (total_codes: number) => {
    const rows = [];
    const multiplesOfTotal = multipleOf(total_codes);
    for (let i = 0; i < multiplesOfTotal.length; i++) {
      const fromPosition = multiplesOfTotal[i];
      const toPosition = multiplesOfTotal[i + 1];
      rows.push(
        <View key={UniqueId()} style={styles.viewRow}>
          {renderCells(fromPosition, toPosition)}
        </View>,
      );
    }
    return rows;
  };

  const renderCells = (fromPosition: number, toPosition: number) => {
    const cells = [];
    const total_cells = 4;
    let currentCellCount = 0;

    for (let i = fromPosition; i < toPosition; i++) {
      cells.push(
        <TextInputColumn
          key={UniqueId()}
          labelText={String(i + 1)}
          handleInputChange={handleInputChange}
        />,
      );
      currentCellCount += 1;
    }

    if (currentCellCount < total_cells) {
      for (let i = currentCellCount; i < total_cells; i++) {
        cells.push(<View key={UniqueId()} style={styles.viewColumn} />);
      }
    }

    return cells;
  };

  return (
    <View style={styles.container}>
      <Text key={UniqueId()}>CustomTableView</Text>
      {renderRows(34)}
    </View>
  );
};

export default CustomTableView;

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#FFF',
  },
  viewColumn: {
    flex: 1,
    flexDirection: 'column',
    paddingHorizontal: 5,
    paddingVertical: 5,
  },
  viewRow: {
    flexDirection: 'row',
  },
  textInput: {
    width: 70,
    height: 40,
    borderColor: 'darkblue',
    borderWidth: 1,
  },
});

//TextInputColumn.tsx
import React from 'react';
import {StyleSheet, View, TextInput, Text} from 'react-native';

interface Props {
  labelText: string;
  handleInputChange(text: string, index: number): any;
}

const TextInputColumn = ({labelText, handleInputChange}: Props) => {
  return (
    <View style={styles.viewColumn}>
      <Text style={styles.label}>{labelText}</Text>
      <TextInput
        style={styles.textInput}
        placeholder={labelText}
        maxLength={4}
        keyboardType="numeric"
        onChangeText={(text) => handleInputChange(text, Number(labelText))}
      />
    </View>
  );
};

export default TextInputColumn;

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#FFF',
    alignItems: 'flex-start',
    justifyContent: 'flex-start',
  },
  viewColumn: {
    flex: 1,
    flexDirection: 'column',
    paddingHorizontal: 5,
    paddingVertical: 5,
  },
  viewRow: {
    flexDirection: 'row',
  },
  textInput: {
    width: 60,
    height: 40,
    borderColor: 'darkblue',
    borderWidth: 1,
    marginLeft: 15,
    paddingHorizontal: 'auto',
  },
  label: {
    top: '40%',
    alignContent: 'center',
    textAlign: 'left',
    alignSelf: 'flex-start',
    marginRight: 'auto',
    position: 'absolute',
  },
});

0 个答案:

没有答案