2.0.0-alpha.3 • Published 5 years ago

react-formed v2.0.0-alpha.3

Weekly downloads
247
License
ISC
Repository
github
Last release
5 years ago

React Formed

This is a project which aims to create a really easy way to build complex forms, both using component state with events or using redux

Coverage Status Build Status Maintainability Commitizen friendly code style: airbnb npm Known Vulnerabilities Wallaby.js

Install

npm install react-formed

Creating a form

The root element of a for is the Form element. Inside this the form elements are placed. Currently only one element comes pre-packed, which is Input, but more is on the way. Input acts almost exacly as a input element would with the same API, with the one exception that a name attribute is required, and will be the key in the resulting object

import { Form, Input } from 'react-formed';

export default () => (
  <Form onFormChange={values => console.log(values)}>
    <Input name="field1" />
    <Input name="field2" />
  </Form>
)

The above example will log an object to the console, each time a value is changed. The value will have the form of { field1: ..., field2: ... }

Setting initial values

import { Form, Input } from 'react-formed';

export default () => (
  <Form initValues={{ field1: 'test1', field2: 'test2' }}>
    <Input name="field1" />
    <Input name="field2" />
  </Form>
)

Be aware that initValues will override any previous set form values on mount. Setting init value to {} will clear the form on remount (obs: This behaviour is subject to change in a later version)

Creating groups

Values can also be grouped, which will cause them to create a namespace inside the form values, for instance

import { Form, Input, Group } from 'react-formed';

export default () => (
  <Form onFormChange={values => console.log(values)}>
    <Group name="group1">
      <Input name="field1" />
      <Input name="field2" />
    </Group>
    <Input name="field3" />
  </Form>
)

would result in an object { group1: { field1: ..., field2: ... }, field3 }

Creating lists

import { Form, Input, List } from 'react-formed';

export default () => (
  <Form onFormChange={values => console.log(values)}>
    <List 
      name="list1"
      render={({ remove }) => (
        <div>
          <Input name="field1" />
          <button onClick={remove}>Remove</button>
        <div>
      )}
    >
      {({ add, children }) => (
        <div>
          {children}
          <button onClick={add}>
            Add
          </button>
        </div>
      )}
    </List>
    <Input name="field3" />
  </Form>
)

would result in an object { list1: [{ field1: ... }, ..., ], field3 }

Using composition names

If working with complex objects composition names can be used. for instance <Input name={['testA', 1, 'testB']}>. Be aware that compositions will create any non existing composition part, so the above exampe will generate a state as {testA: [undefined, { testB: $value }]}. Number keys will create arrays while string keys will create objects. This is usable with Lists and Groups as long as the types matches, and composition names inside Group and List will be scoped to their Group or List.

Using with Redux

When using with redux, a ReduxForm element should be added after redux's Provider, which should have a getState function, which tells where in the store the formReducer can be found. Also when using Redux form elements should have a name attribute, which should be unique for each form

import { formReducer, Form, ReduxForm } from 'react-formed';
import { combineReducers, createStore, Provider } from 'redux';

const store = createStore(
  combineReducers({
    form: formReducer,
  }),
);

export default () => (
  <Provider store={store}>
    <ReduxForm getState={state => state.form}>
      <Form>
        ...
      </Form>
    </ReduxForm>
  </Provider>
)

Selectors

You can use the createSelector method to create a selector for easier working with forms in redux.

import { createSelector } from 'react-formed';

const { getForm } = createSelector(state => state.form);

const mapStateToProps = state => ({
  myForm: getForm(state, 'myForm'),
});

Actions

You can use build in actions for common tasks in redux

import { actions } from 'react-formed';

dispatch(actions.clear('myForm')); // Clear all fields in a form

dispatch(actions.setForm('myForm', { // Replaces all values in the form with the provided values
  fieldA: 'valueA',
  fieldB: 'valueB',
  fieldC: [{
    title: 1,
  }, {
    title: 2,
  }],
}));

dispatch(actions.setValue('myForm', 'fieldB', 'valueC')); // Replaces a specific value with the provided value
dispatch(actions.setValue('myForm', ['fieldC', 1, 'title'], 'valueD'));

Creating custom elements

It is easy to create custom elements, using the withForm decorator, which supplies the function with a value object and a setValue function

This is for instance how Input works

import { withForm } from 'react-formed';
const Input = ({ setValue, value, ...props }) => (
  <input
    {...props}
    value={value || ''}
    onChange={({ target }) => setValue(target.value)}
  />
);

export default withForm(Input);

Loose bindings

If you do not wish to bind the component using the withForm HOC, a render-prop version is also provided

import { WithForm } from 'react-formed';
const Input = (props) => (
  <WithForm>
    {(value, setValue) => (
      <input
        {...props}
        value={value || ''}
        onChange={({ target }) => setValue(target.value)}
      />
    )}
  </WithForm>
);

export default Input;
2.0.0-alpha.3

5 years ago

2.0.0-alpha.2

5 years ago

2.0.0-alpha.1

5 years ago

1.0.8

5 years ago

1.0.7

5 years ago

1.0.6

5 years ago

1.0.5

6 years ago

1.0.4

6 years ago

1.0.3

6 years ago

1.0.2

6 years ago

1.0.1

6 years ago

1.0.0

6 years ago