react-controllable
A higher-order-component to add overwritable internal state to a react component. The wrapped
will act like a controlled component (for example, an <input />
).
Installation
npm install --save @ngard/react-controllable
or, if you are using Yarn
yarn add @ngard/react-controllable
Use
controllable
accepts three arguments for configuration, and returns a function that accepts a
React component to wrap. That function returns a controllable React component.
Signature
controllable(initialState, mapControllersToState, [options])(Component)
// returns React component that accepts the same props as Component as well as notifier props
Arguments
initialState
An object mapping the controllable properties of Component to their initial valuesmapControllersToState
An object mapping the controller properties of Component to an object or function to be passed tosetState
when the controller is invoked.
options
An optional object with the propertyisEqual
that will override the default triple-equal (===
)
check that controllable
uses for determining if a controlled prop changed.
Component
A React component.Return Value
Controllable Component
A new React component that can either be controlled or uncontrolled. This component also accepts notifier props of the formon*DidChange
for each controllable prop. For example, given the following
setup, the returned component, ControllableFoo
would accept a prop onBarDidChange
that would
fire when bar
was changed.
const ControllableFoo = controllable({ bar: 'bar' }, { onClick: { bar: 'BAR' }})(Foo);Notifier functions get the new value and the old value for the prop that changed as arguments. This is useful for when you don't want to control the behavior of the controllable component (that is, you leave it uncontrolled) but you want to respond to changes in it.
Example
import { controllable } from '@ntgard/react-controllable';
// ...
const initialState = { count: 0 };
const mapControllersToState = {
inc: ({ count }) => ({ count + 1 }),
dec: ({ count }) => ({ count - 1 }),
reset: { count: 0 },
}
const ControllableCounter = controllable(initialState, mapControllersToState)(Counter);
// ...
{/* With no overrides, this counter starts at 0 and increments and decrements by 1 */}
<ControllableCounter />
{/* This counter is controlled. It starts at 10 and increments and decrements by 2 */}
let c = 10;
<ControllableCounter count={c} inc={() => { c += 2; }} dec={() => { c -= 2; }} />
License
MIT