UNPKG

react-redux-formal

Version:

Form state management and building library for react and redux

158 lines (120 loc) 3.91 kB
# react-redux-formal Long name, I know. But the name is supposed to convey that it's build on top of both react and redux. Formal came into life after I experimented with [redux-form][redux-form] but found it a bit too "heavy" for most usecases I required. It came with slightly too much out of the box so I decided to make a more lightweight alternative. [redux-form]: https://github.com/erikras/redux-form ## Installation As you'd expect, `react-redux-formal` is available on npm. ```bash $ npm install --save react-redux-formal ``` As the name would suggest, `react-redux-formal` depends on `redux` as well as `react-redux`, so you might need to issue ```bash $ npm install --save redux react-redux ``` ## Setup After you've installed the package, you'll need to add the `formReducer` to your store and expose the store to your app through `react-redux`'s `Provider`. *Note:* `react-redux-formal` requires the formReducer to be mounted at `state.form`. ```jsx import { Provider } from 'react-redux'; import { formReducer } from 'react-redux-formal'; import { render } from 'react-dom'; import { combineReducers, createStore } from 'redux'; const store = createStore(combineReducers({ form: formReducer, })); render(( <Provider store={store}> <App /> </Provider> ), document.getElementById('app-container')): ``` ## Usage With the reducer in place you can use the `connectForm` function to hook your app up and have fields injected. For example, a simple login form component might look something like this: ```jsx import PropTypes from 'prop-types'; import React from 'react'; import { connectForm, validators } from 'react-redux-formal'; export class Signup extends React.Component { static propTypes = { fields: PropTypes.object.isRequired, formValidate: PropTypes.func.isRequired, getValues: PropTypes.func.isRequired, } constructor() { super(); this.onSubmit = this.onSubmit.bind(this); } onSubmit(ev) { ev.preventDefault(); this.props.formValidate() .then(values => { /* do stuff with values */ }) .catch(() => {}); } render() { const { fields } = this.props; return ( <form onSubmit={this.onSubmit}> <fields.username /> <fields.email /> <fields.password /> <button type="submit">Sign up</button> </form> ); } } export default connectForm(() => { name: 'signup', fields: { username: { type: 'text', label: 'Username', validators: [ validators.required('Username is required'), ], }, email: { type: 'text', label: 'E-mail', validators: [ validators.required('E-mail is required'), ], }, password: { type: 'text', label: 'Password', validators: [ validators.required('Password is required'), ], }, }, })(Signup); ``` ## API ### `connectForm(mapStateToOptions)(component)` Generate fields that are injected into the wrapped component. Does not modify the component passed to it. Instead it returns a new component which wraps the original component which should be used instead. - `mapStateToOptions` *(Function)*: A function which should return an object with options for your form. This gets passed the same arguments as redux `connect`'s `mapStateToProps`. The return `options` object can have the following keys: - `name` *(String)*: Name of the form, this is used to store the form in redux under its own namespace. Ensure this is unique for each form. - `fields` *(Object)*: Object containing field specifications. The key will be reused when injecting fields into your component. - [`values`] *(Object)*: Initial values to populate the fields with. - [`inputTypes`] *(Object)*: Custom input types. This can be used to specify your own input types if you don't want to use the ones provided. - `component` *(Component)*: The component to wrap. ## License MIT © [Chiel Kunkels](http://kunkels.me/)