Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 831
Ashwin van Dijk Avatar asked Jul 21 '16 13:07

Ashwin van Dijk


1 Answers

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"
/>
like image 174
Ashwin van Dijk Avatar answered Nov 15 '22 07:11

Ashwin van Dijk