2
votes

I've been trying to get redux-form working with react-native, but I can't get the simplest form working.

I have 2 problems:

  1. If I bind props.input to the TextInput component, every keypress gets eaten. You see the typed character for a brief moment and it disappears. By trial and error, I found that if you don't bind props.input.value, it will allow the field to show the characters you type.

  2. My submit function is always passed an empty values argument.

// @flow
import React, { PropTypes } from 'react'
import {
  StyleSheet,
  Text,
  TextInput,
  TouchableHighlight,
  View,
} from 'react-native'
import { reduxForm, Field } from 'redux-form'

const styles = StyleSheet.create({
  form: {
    flex: 1,
    flexDirection: 'column',
    paddingLeft: 16,
    paddingRight: 16,
  },
  submitbutton: {
    height: 48,
    marginTop: 32,
  },
  textfield: {
    height: 28,
  },
});

class TextInputField extends React.Component {

  render() {
    const { input, placeholder, style, input: { onChange } } = this.props
    console.log(this.props)
    return (
      <TextInput
        onChange={onChange}
        placeholder={placeholder}
        style={style}
      />
    )
  }
}

class SigninScene extends React.Component {

  render() {
    const { handleSubmit, submitting } = this.props
    return (
      <View style={styles.form}>
        <Field name="email" component={TextInputField} placeholder="email" style={styles.textfield}/>
        <Field name="password" component={TextInputField} placeholder="password" style={styles.textfield}/>
        <TouchableHighlight
          onPress={handleSubmit((values, dispatch, props) => {
            console.log("handling submit")
            console.log(values)
          })}
        >
          <Text style={styles.submitbutton}>Signin</Text>
        </TouchableHighlight>
      </View>
    )
  }
}

export default reduxForm({ form: 'signin' })(SigninScene)
4
Are you using Immutable.js? I saw this behavior when I accidentally imported Field from redux-form instead of from redux-form/immutablesfridman
Holy shit! That's it! I forgot I had added it to package.json. As soon as I changed the import, it works perfectly. Thank-you!Julian Paas
👍 Those treacherous hidden assumptions -_-sfridman
Hi @JulianPaas am having the same issue and have been trying to figure this out for a few hours now. Anyway you could share your working code? Would really appreciate itprgrmr

4 Answers

1
votes

Well, for one, you can't do destructuring assignments like this:

const { input, placeholder, style, input: { onChange } } = this.props

As I understand it, the first input eats the contents of input so that onChange won't equal anything. Try

const { input, placeholder, style } = this.props

and then

<TextInput
    onChange={input.onChange} // <-----
    placeholder={placeholder}
    style={style}
0
votes

Based on this issue in the redux-form Github repo, I've updated the code a bit, but still can't get it working.

https://github.com/erikras/redux-form/issues/1668

// @flow
import React, { PropTypes } from 'react'
import {
  StyleSheet,
  Text,
  TextInput,
  TouchableHighlight,
  View,
} from 'react-native'
import { reduxForm, Field, formValueSelector } from 'redux-form'
import { connect } from 'react-redux'

const styles = StyleSheet.create({
  form: {
    flex: 1,
    flexDirection: 'column',
    paddingLeft: 16,
    paddingRight: 16,
  },
  submitbutton: {
    height: 48,
    marginTop: 32,
  },
  textfield: {
    height: 28,  // have to do it on iOS
    marginTop: 32,
  },
});

class TextInputField extends React.Component {

  render() {
    const { input: { onChange, value }, ...otherProps } = this.props
    console.log(this.props)
    return (
      <TextInput
        onChangeText={(value) => onChange(value)}
        value={value}
        {...otherProps}
      />
    )
  }
}

class SigninScene extends React.Component {

  render() {
    console.log(this.props)
    const { handleSubmit, submitting } = this.props
    return (
      <View style={styles.form}>
        <Field name="email" component={TextInputField} placeholder="email" style={styles.textfield}/>
        <Field name="password" component={TextInputField} placeholder="password" style={styles.textfield}/>
        <TouchableHighlight
          onPress={handleSubmit((values, dispatch, props) => {
            console.log("handling submit")
            console.log(values)
          })}
        >
          <Text style={styles.submitbutton}>Signin</Text>
        </TouchableHighlight>
      </View>
    )
  }
}

SigninScene = reduxForm({
    form: 'signin'
})(SigninScene)

const selector = formValueSelector('signin');

function mapStateToProps(state){
    return {
        email: selector(state, 'email'),
        password: selector(state, 'password'),
    }
}

SigninScene = connect(mapStateToProps)(SigninScene)

export default SigninScene
0
votes

Instead of mapping field values to state, try this.

const mapStateToprops = (state: State) => ({
});

export default reduxForm({
  form: 'signin'
})(
  connect(mapStateToprops)(SigninScene)
);
0
votes

I have open sourced react native starter app with redux form, if you still got questions don't hesitate to ask me

https://github.com/DimitriMikadze/firebase-react-native-redux-starter