Learn about our RFC process, Open RFC meetings & more.Join in the discussion! »


1.1.0 • Public • Published


source bundle size build status license

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 />).


npm install --save @ngard/react-controllable

or, if you are using Yarn

yarn add @ngard/react-controllable


controllable accepts three arguments for configuration, and returns a function that accepts a React component to wrap. That function returns a controllable React component.


controllable(initialState, mapControllersToState, [options])(Component)
// returns React component that accepts the same props as Component as well as notifier props


initialState An object mapping the controllable properties of Component to their initial values

mapControllersToState An object mapping the controller properties of Component to an object or function to be passed to setState when the controller is invoked.

options An optional object with the property isEqual 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 form on*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.


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; }} />




npm i @ngard/react-controllable

DownloadsWeekly Downloads






Unpacked Size

235 kB

Total Files


Last publish


  • avatar