Search code examples
typescriptreact-nativereduxredux-form

formValueSelector always returns undefined


I have a HOC and a presentation component (one with redux-form), I'm trying to get the input value within the HOC using formValueSelector but it always gives me undefined

presentation component:

interface Props {
  onCreatePayoutPress: () => void
}

const submit = (values: any) => {
  console.tron.log('submitting form', values)
}

class PayoutView extends React.PureComponent<InjectedFormProps<{}, Props> & Props> {
  private renderPayoutInput = (field: any) => (
    <TextInput style={{fontSize: 17}} autoFocus={true} keyboardType={'number-pad'} onEndEditing={this.calculatePayout}/>
  )

  public render() {
    return (
      ...
      <Field name="payoutInput" type="text" component={this.renderPayoutInput}/>
      <Button style={{height:42, marginHorizontal: 15}}
        onPress={this.props.onCreatePayoutPress}>
          {'Pay out now'}
      </Button>
    )
  }
}

export default reduxForm<{}, Props>({
  form: 'PayoutForm'
})(PayoutView)

Even with onPress={handleSubmit(submit)} reactotron logs indicate the values are empty object {}

HOC:

interface Props {
  createPayout: (identityID: string, payoutAmount: number) => void
  payoutAmount: number
}

const identityID = '...'

export default class PayoutScreen extends React.PureComponent<Props> {
public render() {
    return (
      <PayoutView
        onCreatePayoutPress={this._createPayout}
      />
    )
  }

  _createPayout = () => {
    const payoutAmount = this.props.payoutAmount;
    console.tron.log(this.props.payoutAmount)
    // payoutAmount here is always undefined
    this.props.createPayout(identityID, payoutAmount);
  };
}

const mapStateToProps = (state: ReduxState) => {
  const selector = formValueSelector('PayoutForm')
  const payoutAmount = selector(state, 'payoutInput')

  return {
    payoutAmount: selector(state, 'payoutInput')
  }
}

const mapDispatchToProps = (dispatch: ReduxDispatch) => ({
  createPayout: (identityID: string, payoutAmount: number) => dispatch(createPayout(identityID, payoutAmount)),
})

export const PayoutScreen = connect(
  mapStateToProps,
  mapDispatchToProps,
)(PayoutScreen)

reducer:

const rootReducer = combineReducers({
  ....
  form: formReducer
})

Where is wrong?


Solution

  • You are not forwarding the field.input prop to the underlying <TextInput>.

    See for example here how the renderField has <input {...input}.

    In that way you can 'connect' your text input with the actual Field