How to use Redux-Form with React-Bootstrap?

Dr.YSG picture Dr.YSG · May 11, 2017 · Viewed 7.6k times · Source

I am trying to use "redux-form": "^6.7.0" with "react-bootstrap": "^0.31.0"

My Component renders nicely, but when I press Submit, what I see is an empty object.

note: I have tried wrapping the Config with connect first, and as show below, first wraping it with redux-form and then with the from react-redux connect()

Configuration.js

class Config extends Component {
    render() {
        const { ServerPort, UserID, PortNumber, WWWUrl, SourcePath, FMEPath, pickFile, pickFolder, handleSubmit } = this.props;
        return (
            <Form horizontal onSubmit={handleSubmit}>
                <FormGroup controlId="serverPortBox">
                    <Col componentClass={ControlLabel} sm={2}>Watson Port:</Col>
                    <Col sm={10}>
                        <OverlayTrigger placement="left" overlay={(<Tooltip id="tt1">TCP port for Watson to use</Tooltip>)}>
                            <Field name="WatsonPort" component={FormControl}
                                type="number" min="1024" max="65535" placeholder={ServerPort} />
                        </OverlayTrigger>
                    </Col>
                </FormGroup>

 ......

const CForm = reduxForm({
    form: 'configuration' // a unique name for this form
})(Config);

const Configuration = connect(mapStateToProps, mapDispatchToProps)(CForm)

export default Configuration

reducers.js

import { combineReducers } from 'redux'
import { reducer as formReducer } from 'redux-form

......

const reducerList = {
    GLVersion,
    ServerConfig,
    ServerStats,
    form: formReducer
}

export default combineReducers(reducerList)

Main Package Dashboard.js

what i see in the debugger is that config is an empty object

    <Panel className='configPanel'
      collapsible header="Configuration"
      eventKey="1"
      defaultExpanded={true}>
      <Configuration onSubmit={(config) => writeConfig(config)} />
    </Panel>

Answer

Dr.YSG picture Dr.YSG · May 14, 2017

See: https://github.com/erikras/redux-form/issues/2917

Oh, this was a great mystery. I followed the advice in https://github.com/react-bootstrap/react-bootstrap/issues/2210 and both the warning about additional props and the empty submit stopped.

It seems you have to wrap the Bootstrap in your custom component (why?, I don't know). Also make sure you custom component is a stateless funcitonal component, or after the first key press, you field will blur and lose focus.

There are some warnings in the documentation of redux-form about this.

my custom field component FieldInput

  const FieldInput = ({ input, meta, type, placeholder, min, max }) => {
        return (
            <FormControl
                type={type}
                placeholder={placeholder}
                min={min}
                max={max}
                value={input.value}
                onChange={input.onChange} />
        )
    }

and I invoke it like this:

<Field name="ServerPort"
   type='number' 
   component={FieldInput} 
   placeholder={ServerPort} 
   min="1024" max="65535" 
/>

see also: https://github.com/erikras/redux-form/issues/1750

So now, the definition of FieldInput and Config look like this:

import React, { Component } from 'react'
import { Field, reduxForm } from 'redux-form'
import { connect } from 'react-redux'
import { Form, FormControl, FormGroup, ControlLabel, Col, Button, Tooltip, OverlayTrigger } from 'react-bootstrap'
import * as Act from '../dash/actions.js'
import FaFolderOpen from 'react-icons/lib/fa/folder-open'
import FaFileCodeO from 'react-icons/lib/fa/file-code-o'

const FieldInput = ({ input, meta, type, placeholder, min, max }) => {
    return (
        <FormControl
            type={type}
            placeholder={placeholder}
            min={min}
            max={max}
            value={input.value}
            onChange={input.onChange} />
    )
}

const Config = ({ ServerPort, UserID, PortNumber, WWWUrl, SourcePath, FMEPath, pickFile, pickFolder, handleSubmit }) => {
    return (
        <Form horizontal onSubmit={handleSubmit}>
            <FormGroup controlId="serverPortBox">
                <Col componentClass={ControlLabel} sm={2}>Watson Port:</Col>
                <Col sm={10}>
                    <OverlayTrigger placement="left" overlay={(<Tooltip id="tt1">TCP port for Watson to use</Tooltip>)}>
                        <Field name="ServerPort" type='number' min="1024" max="65535" component={FieldInput} placeholder={ServerPort}  />
                    </OverlayTrigger>
                </Col>
            </FormGroup>