react-formed v2.0.0-alpha.3
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
Install
npm install react-formedCreating 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;6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
7 years ago
7 years ago
7 years ago
8 years ago
8 years ago
8 years ago