A simpler two-way binding helper for React

I’ve built this small utility to help me with two-way binding for a long time.

In 22 lines of code:

import invariant from 'invariant';

const valueGetters = {
  text: e => e.target.value,
  checkbox: e => e.target.checked,
};

export default (self, key) => {
  invariant(key, 'key is required');
  invariant(self, 'self is required');

  return {
    onChange: (event) => {
      self.setState({
        [key]: valueGetters[event.target.type](event),
      });

      event.stopPropagation();
    },
    value: self.state[key],
  };
};

What this allows me to do is:

<TextField label={‘E-mail’} {…linkState(this, ‘email’)} />

And I get this.state.email populated very easily.

If you see the official react documents, it uses a valueLink and a checkedLink to cater to the weird checkbox behaviour of returning event.target.checked as value. But since we have configurable valueGetters:

<Checkbox label={‘Remember me’} {…linkState(this, ‘remember’)} />

If you have custom controls? No problem. Define the custom type in event.target.type and configure a new valueGetter key by that type.

Note: I’m making use of the spread operator to write this.

Written on June 7, 2016