0

React Native Elements から入力コンポーネントを動的に追加するビューがあります。最終的に、Input に入力されたテキストを検証する必要があるため、今のところ、 onChangeText で errorMessage prop を false から true に変更しようとします。残念ながら、状態コンポーネントが true に変更されても、errorMessage を変更しようとするものは何もありません。Snackがあり、便宜上、私のコードは次のとおりです。

import * as React from 'react'
import { ScrollView, StyleSheet, View } from 'react-native'
import { Button, Icon, Input, Text } from 'react-native-elements'
import * as Shortid from 'shortid'

export default class App extends React.Component {
  constructor (props) {
    super(props)

    this.state = {
      timeInputs: [],
      validities: []
    }

    this.addTimeInput = this.addTimeInput.bind(this)
    this.removeTimeInput = this.removeTimeInput.bind(this)
    this.mutateValidities = this.mutateValidities.bind(this)
  }

  componentDidMount () {
    this.addTimeInput()
  }

  addTimeInput () {
    const identifier = Shortid.generate()
    const timeInputs = this.state.timeInputs
    const validities = this.state.validities

    let isTimeValid = false
    let time = ''

    new Promise(
      (resolve, reject) => {
        resolve(
          validities.push(
            { id: identifier, value: isTimeValid }
          ),
          timeInputs.push(
            <View key = { identifier }>
              <View style = { styles.row }>
                <Input
                  errorMessage = {
                    this.state.validities.filter(
                      validity => validity.id !== identifier
                    ).value == true
                      ? 'Valid'
                      : 'Invalid'
                  }
                  errorStyle = { styles.error }
                  onChangeText = {
                    value => {
                      time = value
                      this.mutateValidities(identifier, true)
                      console.log('TIME ' + identifier + ': ' + time)
                    }
                  }
                  placeholder = 'HH:MM AM/PM'
                  ref = { React.createRef() }
                />
                <Icon
                  color = { colors.dark }
                  name = 'add-circle'
                  onPress = { () => this.addTimeInput() }
                  type = 'material'
                />
                <Icon
                  color = { colors.dark }
                  name = 'remove-circle'
                  onPress = {
                    () => {
                      if (this.state.timeInputs.length > 1) {
                        this.removeTimeInput(identifier)
                      } else {
                        console.log('LENGTH: ' + this.state.timeInputs.length)
                      }
                    }
                  }
                  type = 'material'
                />
              </View>
            </View>
          )
        )
      }
    )
      .then(
        this.setState(
          {
            timeInputs: timeInputs,
            validities: validities
          }
        )
      )
      .catch(
        (reason) => {
          console.log(
            'Failed to create time-input because of the following: ' + reason
          )
        }
      )
  }

  mutateValidities (key, value) {
    this.setState(
      {
        validities: this.state.validities.map(
          validity => validity.id === key
            ? {...validity, value: value}
            : validity
        )
      }
    )
  }

  removeTimeInput (key) {
    this.setState(
      {
        timeInputs: this.state.timeInputs.filter(
          timeInput => timeInput.key !== key
        ),
        validities: this.state.validities.filter(
          validity => validity.id !== key
        )
      }
    )
  }

  render () {
    return (
      <ScrollView contentContainerStyle = { styles.container }>
        <Text h4 style = { styles.title }>Time Inputs</Text>
        {
          this.state.timeInputs.map(
            (value) => { return value }
          )
        }
        <Button
          buttonStyle = { styles.button }
          onPress = {
            () => this.state.validities.map(
              validity => console.log(validity.id + validity.value)
            )
          }
          title = 'Log Validities'
        />
      </ScrollView>
    )
  }
}

const colors = {
  dark: 'steelblue',
  light: 'aliceblue',
  medium: 'lightsteelblue',
  error: 'firebrick'
}

const styles = StyleSheet.create(
  {
    button: {
      backgroundColor: colors.dark,
      margin: 5
    },
    container: {
      alignItems: 'center',
      backgroundColor: colors.light,
      flex: 1,
      justifyContent: 'center'
    },
    error: {
      color: colors.error,
      fontSize: 12,
      margin: 5
    },
    row: {
      alignItems: 'center',
      flexDirection: 'row',
      margin: 5,
      width: '80%'
    },
    title: {
      margin: 5
    }
  }
)

私をここまで導いてくれたMcGregor (2017) のおかげですが、私はまだ立ち往生しています。

参照:

McGregor, L. (2017 年 10 月 2 日) ReactJS で配列内のオブジェクトを更新する最良の方法は何ですか? [スタック オーバーフローの回答]。https://stackoverflow.com/a/46518653/6084947から取得

4

1 に答える 1