JSPM

  • Created
  • Published
  • Downloads 795
  • Score
    100M100P100Q85242F
  • License MIT

React valueLink implementation with links to objects, validation, and purely functional state updates.

Package Exports

  • valuelink

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (valuelink) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Advanced React links for purely functional two-way data binding.

React 15.x will remove valueLink support. This package is complete dependency-free implementation of valueLinks with powerful API extensions.

  • Implements standard React 0.14 links API
  • API extensions:
    • Purely functional updates of enclosed objects and arrays.
    • Declarative binding to event handlers.
    • Simple form validation.
    • Offhand boolean link creation for checkbox and radio groups.
  • Reference implementation for 'linked' tags (you'll need it with React 15.x):
    • Standard tags: <Input /> (with validation), <Select />, <TextArea />
    • Custom tags: <Radio />, <Checkbox />
var linkToArray = Link.state( this, 'phonebook' );

var list = linkToArray.map( ( itemLink, i ) => (
    <div key={ i }>
        <Input valueLink={ itemLink.at( 'name' ) } />            
    </div>
));

This technology is one of the key components of NestedReact architecture, helping you to build large-scale React applications with a powerful and fast NestedTypes classical OO models.

Breaking API changes in version 1.1

  • link.update is now performs immediate purely functional link update, shallow copying enclosed plain objects and arrays.
  • link.action behaves as link.update in 1.x. Rename.
  • link.toggle is removed. Use link.update( x => !x ) instead.

Installation

npm install valuelink

CommonJS module, MIT License. No side dependencies.

// Links
import Link from 'valuelink'

// You'll need this components with React 15.x instead of standard ones.
import { Input, TextArea, Select, Radio, Checkbox } from 'valuelink/tags.jsx'

API

  • Create custom link: new Link( value, requestChange )

    var customLink = new Link( this.value, x => this.value = x );
  • Create link to react component's state attribute:

    var nameLink = Link.state( this, 'name' );
  • Set link value: link.set( x ) or link.requestChange( x )

    <button onClick={ () => boolLink.set( !boolLink.value ) } />
  • Purely functional link value: link.update( prevValue => newValue ). Plain objects and arrays are shallow copied by update and action functions, thus it's safe just to update the value in place.

    <button onClick={ () => boolLink.update( x => !x ) } />
        <button onClick={ () => objLink.update( obj => {
                                    obj.a = 1;
                                    return obj;
                                }) } />
    
  • Create action to handle UI event: link.action( ( prevValue, Event ) => newValue )

    <button onClick={ boolLink.action( x => !x ) } />
    ...
    const setValue = ( x, e ) => e.target.value;
    ...
    <input  value={ link.value }
            onChange={ link.action( setValue ) } />

Links has link.check( condition, error = 'Invalid value' ) method which can be used to check the sequence of conditions. Checks can be chained.

condition is predicate function linkValue => isValid taking link value as an argument. Whenever condition returns falsy value, link.error will take the value of corresponding error. link.error field may be analyzed by custom <Input /> control to indicate an error.

This mechanics can be used to add ad-hoc validation in render.

  • Simple asserts:

    var numLink = List.state( this, 'num' )
                    .check( x => x >= 0 && x <=5 );
                    
    console.log( numLink.error );                    
  • Validation asserts with custom error objects

    var numLink = List.state( this, 'num' )
                    .check( x => x >= 0 && x <=5, 'Number must be between 0 and 5' );
                    
    console.log( numLink.error );                    
  • Chained validation asserts

    var numLink = List.state( this, 'num' )
                    .check( x => x >= 0, 'Negative numbers are not allowed' )
                    .check( x => x <= 5, 'Number should be not greater than 5' );
                    
    console.log( numLink.error );                    

If linked value is plain object or array, it's possible to generate links to their members. Whenever this derivative links will be updated, it will lead to proper purely functional update of the whole structure. I.e. if you have array in component state, and link to its element will be updated, it will lead to proper update of stateful component.

  • Take link to array or object member: link.at( key )

        const firstElementLink = arrayLink.at( 0 );

    or

        const nameLink = objectLink.at( 'name' );
  • Map and filter through array or object: link.map( iterator )

    var list = stringArrayLink.map( ( itemLink, index ) => {
        if( itemLink.value ){        
            return (
                <div key={ index }>
                    <Input valueLink={ itemLink } />            
                </div>
            );
        }
    });
  • Link to the presence of value in array: arrayLink.contains( value )

    const optionXLink = arrayLink.contains( 'optionX' );
  • Link to value equality: link.equals( value )

    const optionXLink = stringLink.equals( 'optionX' );

Data binding examples

Here are the set of working examples for typical data binding use cases. Sources are here.