What is uncontrollable?
The 'uncontrollable' npm package is a utility for creating controlled components that can also be uncontrolled. It allows you to manage the state of a component internally while still providing the ability to control it externally via props.
What are uncontrollable's main functionalities?
Creating Uncontrolled Components
This feature allows you to create components that can manage their own state internally but can also be controlled externally via props. The `uncontrollable` function wraps your component and allows you to specify which props should be treated as controlled.
const { uncontrollable } = require('uncontrollable');
class MyComponent extends React.Component {
render() {
return <input value={this.props.value} onChange={this.props.onChange} />;
}
}
const UncontrolledComponent = uncontrollable(MyComponent, { value: 'onChange' });
// Usage
<UncontrolledComponent defaultValue="initial value" />;
Handling Multiple Controlled Props
This feature allows you to handle multiple controlled props within a single component. You can specify multiple props that should be treated as controlled, and the `uncontrollable` function will manage them accordingly.
const { uncontrollable } = require('uncontrollable');
class MyComponent extends React.Component {
render() {
return (
<div>
<input value={this.props.value} onChange={this.props.onChange} />
<input value={this.props.otherValue} onChange={this.props.onOtherChange} />
</div>
);
}
}
const UncontrolledComponent = uncontrollable(MyComponent, { value: 'onChange', otherValue: 'onOtherChange' });
// Usage
<UncontrolledComponent defaultValue="initial value" defaultOtherValue="initial other value" />;
Other packages similar to uncontrollable
react-controlled
The 'react-controlled' package provides similar functionality by allowing you to create components that can be both controlled and uncontrolled. It offers a more modern API and better integration with hooks compared to 'uncontrollable'.
recompose
The 'recompose' package offers a variety of higher-order components and utilities for managing state and props in React components. While it is more feature-rich and versatile, it can be more complex to use compared to 'uncontrollable'.
uncontrollable
Wrap a controlled react component, to allow spcific prop/handler pairs to be uncontrolled. Uncontrollable allows you to write pure react components, with minimal state, and then wrap them in a component that will manage state for prop/handlers if they are excluded.
Install
npm i -S uncontrollable
use
Take the following simple component and essentially mimic how React inputs already work.
var MyInput = React.createClass({
propTypes: {
value: React.PropTypes.number,
onChange: React.PropTypes.func,
},
render: function() {
return (
<input
type='text'
value={this.props.value}
onChange={ e => this.props.onChange(e.target.value)}/>
)
}
});
It will be effectively Readonly if you neglect to include an onChange
handler. What about if you only want to set a initial value and then let the input manage the value prop itself? React inputs do this for you automatically with value
and onChange
, but if you are creating slightly more complex inputs you may have other prop pairs you wish to leave to the consumer to handler.
Uncontrollable allows you serperate out the logic necessary to create controlled/uncontrolled inputs letting you focus on creating a completely controlled input and wrapping it later. This tends to be a lot simplier to reason about as well.
var uncontrollable = require('uncontrollable');
var UncontrollableMyInput = uncontrollable(
MyInput,
{ value: 'onChange' })
<UncontrollableMyInput defaultValue={4} />
The above is a contrived example but it allows you to wrap even more complex Components, giving you a lot of flexibiltity in the API you can offer a consumer of your Component.
React Widgets makes heavy use of this strategy, you can see it in action here: https://github.com/jquense/react-widgets/blob/master/src/Multiselect.jsx#L408