Search code examples
reactjsreduxredux-form

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?


Solution

  • 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"
    />