GithubHelp home page GithubHelp logo

j0nas / light-form Goto Github PK

View Code? Open in Web Editor NEW
37.0 3.0 4.0 167 KB

Lightweight library for lightweight React/Redux forms

Home Page: http://light-form.surge.sh

JavaScript 100.00%
react redux form state state-management abstraction redux-form

light-form's Introduction

Light-form

Lightweight library for boilerplate-free React/Redux forms

CircleCI Coverage Status

light-form is a lightweight library that lets you create boilerplate-free React/Redux.

Check out the live demo and the examples.

Installation

npm install --save light-form  

Example

// CustomerForm.jsx
import React from 'react';
import {Input} from 'light-form';

const CustomerForm = () =>
  <div>
    <Input name="customer.firstname" />
    <Input name="customer.lastname" />
  </div>;
    
export default CustomerForm;

Import Reducer and pass it the name which you alias the reducer to. This should be the same as the first part of the dot-delimited name property for the fields in your form. Then add the reducer to your store setup (eg. using combineReducers).

// rootReducer.js
import {combineReducers} from 'redux';
import {Reducer} from 'light-form';

const rootReducer = combineReducers({
  customer: Reducer('customer'),
  // .. other reducers
});

export default rootReducer;

Quick start

light-form only requires four simple steps to get started:

  • in your view, import {Input, Select, TextArea} from "light-form";
  • pass the components a name prop in the form of [formName].[fieldName]
    • (eg. <Input name="myForm.myField" />)
  • in your root reducer, import {Reducer} from "light-form";
  • pass it [formName] and add it to your store under the same name
    • (eg. combineReducers({ myForm: Reducer('myForm'), ... }))

And that's it, your form is ready!

How it works

light-form exports <Input />, <Select /> and <TextArea /> components. These components come with value and onChange props attached under the hood. Those props are wired up to the reducer with the matching name, eg. customer in the example above. So entering 'Jonas' and 'Jensen' into the example form above would give us this state tree:

{
  customer: {
    firstname: 'Jonas',
    lastname: 'Jensen'
  }
}

The components' value prop is handled in the reducer and should never be explicitly set. The onChange prop is intercepted by the components' container, if defined. See 'Defining custom onChange handlers' below.

Why it's useful

light-form aims to combine ease of use with flexibility. The following are its strong points.

Reduced boilerplate

Mapping and attaching value and onChange props is done the same way in most use cases, so light-form abstracts that away. The same applies for the reducer which handles those props. Rather than typing out repetitive code, we can focus on the domain aspects which makes our forms unique. To demonstrate this, compare the example above to the equivalent form in "vanilla" React/Redux. This grows more beneficial with increased complexity, such as with multi-part forms. See Nested demo/example.

No abstraction trade-off

You can opt to have complete control of the form's events. The onChange prop and the reducer action handler have hooks which you can use to intercept the changes and perform mutations. This allows for have fine-tuned control where necessary, just like with vanilla React/Redux. See InterceptOnChange and OnStateChange demo/examples.

No ad-hoc magic

You can treat the provided components almost as standard uncontrolled React components, except they're in sync with the Redux store by default. Any props you pass them are applied. Eg., the provided <Input /> is just a wrapper for a standard <input />, and will accept any props that would be valid for <input />. value and onChange are the exceptions, see "Defining custom event handlers".

Defining custom event handlers

The exported components and reducer have hooks which you can pass functions to. This allows for fine-grained control of the events passed to the components and the resulting state on reducer changes.

Custom onChange handlers for fields

If the onChange prop of a field is defined, the passed function will be invoked, and the return of that function will be passed to the internal onChange function. This allows for complete control of the onChange handling and outcome. The function passed to the prop will receive the event object as a parameter which you are free to copy and mutate as you please. Return this event object (or a copy) as a part of the custom onChange function, or a falsy value if you want to abort handling the event. See Intercept OnChange example.

Custom onStateChange handler for reducer

In addition to an optional defaultState second parameter, the Reducer accepts an onStateChange function as an optional third parameter. If present, the passed function will be invoked after a state update has occurred, and the function will receive the updated state as a parameter. The function is free to mutate this state as needed. The function is expected to return an object, which will be applied as the new state for the reducer. See OnStateChange example.

Custom reducer actions

The Reducer accepts an optional actionHandlers object as the fourth parameter. This is expected to be an object with Redux action names as keys and state migration functions (like in conventional reducers) as values. The functions will receive state and action parameters, being the reducer's state and the dispatched action respectively. The value returned from the function will be the new state. See Custom reducer actions example.

light-form's People

Contributors

j0nas avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

reglendo ankcorn

light-form's Issues

Fail to replicate CustomReducerAction example

Using exact same code, apart from importing Reducer from light-form, I can not replicate the example. Action is fired fine (when inspected in redux-dev-tools), but has no effect on state.

As I said, the only thing that is different is from where the Reducer is imported, so my best guess is that it has to do with that

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.