Ifyouareabitunsureonthe_why_ofthismodulereadthenextsectionfirst.Ifyoujustwanttoseesomereal-worldexamples,checkout[ReactWidgets](https://github.com/jquense/react-widgets) which makes [heavy use of this strategy](https://github.com/jquense/react-widgets/blob/5d1b530cb094cdc72f577fe01abe4a02dd265400/src/Multiselect.jsx#L521).
Foreverypropyouindicateasuncontrollable,thereturnedcomponentwillalsoacceptaninitial,`default` value for that prop. For example, `open` can be left uncontrolled but the initial value can be set via `defaultOpen={true}`ifwewantittostartopen.
// filters out defaultValue, defaultOpen and returns controlled
// versions of onChange, and onToggle.
constcontrolledProps=useUncontrolled(props,{
value:'onChange',
open:'onToggle',
})
return<Checkbox{...controlledProps}/>
}
```
###UseCase
OneofthestrengthsofReactisitsextensibilitymodel,enabledbyacommonpracticeofpushingcomponentstateashighupthetreeaspossible.Whilegreatforenablingextremelyflexibleandeasytoreasonaboutcomponents,thiscanproducealotofboilerplatetowirecomponentsupwitheveryuse.Forsimplecomponents(likeaninput)thisisusuallyamatteroftyingtheinput`value` prop to a parent state property via its `onChange`handler.Hereisanextremelycommonpattern:
Thispatternmovestheresponsibilityofmanagingthe`value` from the input to its parent and mimics "two-way" databinding. Sometimes, however, there is no need for the parent to manage the input's state directly. In that case, all we want to do is set the initial `value` of the input and let the input manage it from then on. React deals with this through "uncontrolled" inputs, where if you don't indicate that you want to control the state of the input externally via a `value`propitwilljustdothebook-keepingforyou.
Noticehowwedon'ttrackanystateinoursimpledropdown?Thisisgreatbecauseaconsumerofourmodulewillhavethealltheflexibilitytodecidewhatthebehaviorofthedropdownshouldbe.AlsonoticeourpublicAPI(propTypes),itconsistsofcommonpattern:apropertywewantset(`value`, `open`), and a set of handlers that indicate _when_ we want them set (`onChange`, `onToggle`). It is up to the parent component to change the `value` and `open`propsinresponsetothehandlers.
Whilethispatternoffersanexcellentamountofflexibilitytoconsumers,italsorequiresthemtowriteabunchofboilerplatecodethatprobablywon'tchangemuchfromusetouse.Inalllikelihoodtheywillalwayswanttoset`open` in response to `onToggle`,andonlyinrarecaseswillwanttooverridethatbehavior.Thisiswherethecontrolled/uncontrolledpatterncomesin.
value={this.state.val}// we can still control these props if we want
onChange={val=>this.setState({val})}
defaultOpen={true}/>// or just let the UncontrollableDropdown handle it
// and we just set an initial value (or leave it out completely)!
```
Nowwedon'tneedtoworryabouttheopenonToggle!Thereturnedcomponentwilltrack`open` for us by assuming that it should just set `open` to whatever `onToggle` returns. If we _do_ want to worry about it we can just provide `open` and `onToggle`propsandtheuncontrolledinputwilljustpassthemthrough.
TheaboveisacontrivedexamplebutitallowsyoutowrapevenmorecomplexComponents,givingyoualotofflexibilityintheAPIyoucanofferaconsumerofyourComponent.Foreverypairofprop/handlersyoualsogetadefaultPropoftheform"default[PropName]"so`value` -> `defaultValue`, and `open` -> `defaultOpen`,etc.[ReactWidgets](https://github.com/jquense/react-widgets) makes heavy use of this strategy, you can see it in action here: https://github.com/jquense/react-widgets/blob/5d1b530cb094cdc72f577fe01abe4a02dd265400/src/Multiselect.jsx#L521