iPhone
reactjs
reactnative
redux
redux-form

React Native と Redux Formの組み合わせでキーボード入力中にsubmitしても入力内容が反映されていない問題

React NativeとRedux Formを組み合わせて(もちろんReduxは使用)利用した時にちょっとした問題に遭遇したので投稿します。
ちなみにiPhoneでしか確認していないので、Androidで同様かは不明です。

問題

ログインフォームなどでTextInputに入力する時、フォームにfocusされたままでログインボタンを押した場合、入力中の文字はdispatchされない。
次のスクリーンショットのような状況です。

Simulator Screen Shot - iPhone 6 - 2018-01-22 at 22.59.33.png

この状況だとログインボタンを押してもパスワードが入力されていない扱いになり、バリデーションエラーが表示されてしまいます。

解決方法

Redux FormのFieldのinput propsにonChange()があるので、TextInputonChangeText propに渡せば解決します。
Redux Form -Field

次のようにTextInputFormの部品を作ります。関係ない部分は削っています。

TextInputFormを利用した全体のコードは次の通りです。@decorator使ってます。

const TextInputForm = (props) => {
  const { input, style, label, ...inputProps } = props
  return (
    <View>
      <Text>{label}</Text>
      <TextInput
        {...inputProps}
        style={style}
        onChangeText={text => input.onChange(text)} //これを追加
      />
    </View>
  );
}

import React, { Component } from 'react'
import { reduxForm, Field } from 'redux-form'
import { Text, TextInput, View, TouchableOpacity } from 'react-native'

@reduxForm({
  form: 'login',
  validate: values => {
    const errors = {}
    if (!values.id) errors.id = 'IDを入力してください'
    if (!values.password) errors.password = ' パスワードを入力してください'
    return errors
  }
})
export default class Login extends Component {
  login = values => {
    // 何か処理
  }

  render() {
    const { handleSubmit, error } = this.props
    return (
      <View style={styles.root}>
        <View>
          <Field
            name='id'
            label='ID'
            style={styles.input}
            component={TextInputForm}
          />
        </View>
        <View>
          <Field
            name='password'
            label='パスワード'
            style={styles.input}
            component={TextInputForm}
            secureTextEntry
          />
        </View>
        <TouchableOpacity onPress={handleSubmit(this.login)} style={styles.button}>
          <Text style={{color: '#fff', fontSize: 20}}>ログイン</Text>
        </TouchableOpacity>
      </View>
    )
  }
}

これで解決するにはするのですが、onChangeTextが呼ばれる度にdispatchされているため、もしかするとパフォーマンスに影響がある可能性があります。