Search code examples
reactjsreduxreact-reduxmaterial-uiredux-form

How to grab Textfield input values with Redux-form using MaterialUI


Goal: Get the input values from a material UI component and pass them to an action creator in a handleSubmit function.

                 <Field name='email'
                  component={email =>
                   <TextField
                    fullWidth
                     autoComplete='off'
                      className={classes.textField}
                      id='email-text-field'
                      label='Email'
                      value={email} />
                    } />

                 <Field name='password'
                  component={password =>
                    <TextField
                      type='password'
                      fullWidth
                      autoComplete='off'
                      className={classes.textField}
                      id='password-text-field'
                      label='Password'
                      value={password} />
                    } />

This is how it is being connected to Redux:

@reduxForm({form: 'loginForm', fields: ['email', 'password']})

The warnings I'm getting in my chrome dev tools console is: Failed prop type: Invalid prop value supplied to TextField. Warning: Failed prop type: Invalid prop value supplied to Input.`

Additionally, the email field in my login form shows [Object, object} My guess is that this is happening due to the fact that props are being passed from the

Any ideas on where I've gone wrong?


Solution

  • When you want to use a custom field for Redux-Form, Redux-form gives you access to both props like onChange etc, but also other meta-data (like if the form has been touched or not). These different kinds of props are grouped depending on type.

    The interesting part for you is that all the attributes associated with a normal input element (like onChange, value, type) are grouped in props.input. So the argument you call password is actually the whole props object that is sent down to the component. It looks something like this {input:{ value: 'someValue', onChange: somFunction.. etc. etc}, meta: { touched: false, etc. etc.}}.

    That means that if you want to use the TextField like you do now, you need to do something like:

    <Field name='email'
        component={({input}) =>
          <TextField
             value={input.value}
             onChange={input.onChange}
             fullWidth
             autoComplete='off'
             className={classes.textField}
             id='email-text-field'
             label='Email'
            />
         } />
    

    This can get pretty messy, especially if you want to use the meta props, so it's often worth it to break the custom component logic out into its own function, like they do in the example in the docs: https://redux-form.com/7.0.4/examples/material-ui/

    You may also be interested to know that for material-ui components, there actually already exists a library that has done most of that manual work for you: redux-form-material-ui.