react-link-state-vm

Link state with virtual method.


Keywords
function-bind, react, state
License
ISC
Install
npm install react-link-state-vm@0.1.1

Documentation

react-link-state-vm

Link state with virtual method.

Live example

To use the experimental function bind operator ::, you need @babel/plugin-proposal-function-bind (or @babel/preset-stage-0). Or you can use Function.prototype.call to assign correct this value. Example:

// Proposal 👍
this::valueLink("name");

// Standard
valueLink.call(this, "name");

Example Input

import { valueLink } from "react-link-state-vm";

class ExampleComponentWithInput extends Component {
  render() {
    // this.state.name -> undefined | "some text"
    return <input type="text" {...this::valueLink("name")} />;
  }
}

Checkbox and Radio

import { checkedLink } from "react-link-state-vm";

class ExampleComponentWithCheckbox extends Component {
  render() {
    // this.state.race -> undefined | true | false
    return <input type="checkbox" {...this::checkedLink("race")} />;
  }
}

class ExampleComponentWithMultiCheckbox extends Component {
  render() {
    // this.state.category -> undefined | [] | ["motogp", "moto3", ...]
    return (
      <div>
        <input type="checkbox" {...this::checkedLink("category", "motogp")} />
        <input type="checkbox" {...this::checkedLink("category", "moto2")} />
        <input type="checkbox" {...this::checkedLink("category", "moto3")} />
      </div>
    );
  }
}

class ExampleComponentWithRadio extends Component {
  render() {
    // this.state.category -> undefined | "motogp" | ...
    return (
      <div>
        <input type="radio" {...this::checkedLink("category", "motogp")} />
        <input type="radio" {...this::checkedLink("category", "moto2")} />
        <input type="radio" {...this::checkedLink("category", "moto3")} />
      </div>
    );
  }
}

Select

import { selectedLink } from "react-link-state-vm";

class ExampleComponentWithSelect extends Component {
  render() {
    // this.state.bike -> undefined | "ducati" | ...
    return (
      <select {...this::selectedLink("bike")}>
        <option value="ducati">Ducati</option>
        <option value="honda">Honda</option>
        <option value="suzuki">Suzuki</option>
        <option value="yamaha">Yamaha</option>
      </select>
    );
  }
}

class ExampleComponentWithMultiSelect extends Component {
  render() {
    // this.state.bikes -> undefined | [] | ["ducati", "honda", ...]
    return (
      <select {...this::selectedLink("bikes", true)}>
        <option value="ducati">Ducati</option>
        <option value="honda">Honda</option>
        <option value="suzuki">Suzuki</option>
        <option value="yamaha">Yamaha</option>
      </select>
    );
  }
}

About the Implementation

In a simple form, valueLink could be just a function that returns value and onChange handler.

function valueLink(name) {
  return {
    value: this.state[name],
    onChange: ({ target: { value } }) =>
      this.setState({
        [name]: value
      })
  };
}