An open API service indexing awesome lists of open source software.

https://github.com/capaj/react-bound

a HOC for binding an input or group off inputs to a model-it can be a POJO or a mobx observable
https://github.com/capaj/react-bound

databinding mobx mobx-react observable reactjs

Last synced: 4 months ago
JSON representation

a HOC for binding an input or group off inputs to a model-it can be a POJO or a mobx observable

Awesome Lists containing this project

README

          

# react-bound

a react utility component for binding inputs to a model. Model can be a POJO or a mobx observable.
It does the same thing as https://facebook.github.io/react/docs/two-way-binding-helpers.html. Links the value from your model to your inputs so that you don't have to wire up every single input manually.
With react-bound you can forget what property of an `event.target` carries the actual value. No matter if it's a checkbox, radio or a file input. All of the DOM api quirks are hardcoded in react-bound and you get the actual values laid out into your model.

![showcase login form](https://raw.githubusercontent.com/capaj/react-bound/master/img/showcase-login-form.gif)

## supported html tags

```
input
textarea
select
```

### supported input element types

```
text
url
search
checkbox
radio
password
color
email
date
time
file
datetime-local
number
```

## form extra API

Currently you get an object available for your children callback with these props:

- `dirty` boolean flag indicating if any of the bound inputs had any change event
- `reset` this function reverts your state object to the state it was in when `` rendered first
- `set` this function sets a property on your state to the supplied value and changes dirty from false to true

Also inspired by angular form controller I want to add support for validation to be able to indicate `valid` and `invalid` on the whole state object.

## Motivation

Main motivation is to avoid handling raw events for each input. Having a `` saves quite a bit of code. This approach violates the often touted one-way data flow-the great react.js strength, but I don't really care. It works well enough for all the forms I've created with it so far.

## Showcase

To run a showcase, use: `npm run showcase`

## Usage

You can bound a single input:

```javascript

```

Or a whole form:

```javascript
const state = observable({
first: '',
second: '',
})
// in render



First
{
console.log('onchange still works as always', ev)
}}
/>


Second


```

All you have to do is match the name of input to the property in your state. The React element tree is recursively traversed, so even if you hide the input 20 layers deep, it will still hook it up.

You can bind multiple forms inside a single `Bound` element, but I'd advise you to at least namespace your inputs, so that your model remains somewhat tidy.
For example:

```javascript
const state = observable({
formA: {
unicornInput: ''
},
formB: {
unicornInput: ''
}

})


```

## With inputs wrapped in custom elements

So a lot of inputs you use are wrapped in a react component. For example [react-select](https://github.com/JedWatson/react-select). To bind these, you can utilize a `bound` prop on any element which accepts a `value` and `onChange` handler. Example:

```javascript

```

## Children as function

By using function a direct child, you can get `dirty`, `reset` and `set` form utils. These utils are backed by a Weakmap-so if you have multiple elements where `to` is the same, `dirty` will be changed to true if any of the two forms is touched.

```javascript

{({dirty, reset, set, setClean}) => {
return




has been touched: {dirty}
{
reset()
}}>
reset form

{
const savedState = await someApiCall()
setClean(savedState) //set the clean state to a new value-when you've saved your form on backend for example
}}>
save form

{
set('a', 1) // sets a value to model programatically-same as doin a = 1 but "dirty" gets switched
}}>
reset form


}}

```

## Props

### to

a reference to s state object

### onChange

is called for any change in the state object. Callback is called with 3 params: state, statePropPath, castedValue

### TBD

Sometimes you'd get a react warning when you do this-if you do the wrapped element is forwarding the bound prop to the child. If you can't make sure that the prop `bound` is not passed, you'll want to use `` like this to avoid getting the error:

```javascript



```

## With mobx

Make sure you initialize your fields, otherwise an error is thrown if your state is mobx observable.

```javascript
const state = observable({
unicornInput: ''
})
// in render

```

## formsExtraState

In raw cases you might need to be able to get the state for `dirty` and `reset` imperatively. In those cases, just `import {formsExtraState} from 'react-bound'` and you should be able to get any form state from it

## Browser compatibility

Any browser with a Weakmap will do.