Ashwin van Dijk Ashwin van Dijk - 3 months ago 172
React JSX Question

Migrating redux-form to v6, onBlur and onChange functions

I'm migrating redux-form to the newest version, 6.0.0rc3. In this version the 'fields' array is gone, and is replaced by a Field component (see http://redux-form.com/6.0.0-rc.3/docs/MigrationGuide.md/). I used to extend the default onBlur function in v5 like this:

const { user_zipcode } = this.props.fields;
onChange={
val => user_zipcode.onChange(this._handleZipcodeChange(val))
}


However, in the new version this can't be done anymore, because
this.props.fields
doesn't exist.

From what I found in the docs, the new way should be to create a component for every form field that has a distinct function, and extend the onBlur function there:

_onBlur() {
// my custom blur-function
}

render() {
const { input, touched, error } = this.props;
return (
<input
className={styles.input}
{...input}
onBlur={() => {
// 2 functions need to be called here
this._onBlur();
input.onBlur();
}}
/>
);
}


This is fine, except that I need to create a new element for each field that needs to do something different when the blur event occurs. In some fields I have to make a call to an API, which I do by dispatching an action. For example, I have to do this to get an address. In these components I have to connect my store, so it gets connected many times.

I tried to pass my custom function from the parent to the Field component, like this:

<Field
type="text"
name="user_zipcode"
component={Zipcode}
onBlurFunction={this._myBlurFunction}
/>


and getting both functions in my component from the props:

...
onBlur={() => {
input.onBlurFunction();
input.onBlur();
}}
...


This didn't work correctly because of the new React warning.

Is there a better way to do this?

Answer

I ended up with creating a custom component for every form-field that has a onChange or onBlur function. In that way you can run both functions, so all the default redux-form actions are called.

// Licenceplate-component

export default class Licenceplate extends Component {

    _handleBlur = ({ currentTarget: { value } }) => {
        // my blur function
    }

    render() {
        const {
          input,
          meta: { touched, error }
        } = this.props;

        return (
          <div className={styles.wrapper}>
            <input
              {...input}
              type="text"
              onBlur={
                e => input.onBlur(this._handleBlur(e))
              }
            />

         </div>
       );
   }
}


// In my form-component
<Field
    component={Licenceplate}
    name="car_licenceplate"
    type="text"
/>
Comments