Controlled inputs
Writing controlled inputs is a bit different than in React. There are two parts to this.
Controlling native inputs
Section titled “Controlling native inputs”function App() { const refs = useRefProxy();
const [get, set] = useTextInput(refs.input);
function handleChange(event) { /* ... */ }
return ( <input ref={refs.input} onChange={handleChange} value="defaultValue" /> );}You have several handles on this element:
- Set its default value with the
valueprop - Get its current value with
get - Change its current value with
set - Respond to user changes with
onChange
Controlling custom components
Section titled “Controlling custom components”To replicate these handles for custom components, expose get and set
functions through a context, then consume them with useControlledInput.
Start with a simple input component that wraps a native input:
function MyInput({ value, onChange }) { return <input value={value} onChange={onChange} />;}Expose its get and set functions through context:
function MyInput({ value, onChange }) { const refs = useRefProxy(); const [get, set] = useTextInput(refs.input);
return ( <MyInput.Context.Provider value={{ get, set }}> <input value={value} onChange={onChange} ref={refs.input} /> </MyInput.Context.Provider> );}MyInput.Context = createContext();Then use it like any controlled input:
function App() { const refs = useRefProxy();
const [get, set] = useControlledInput(refs.input);
function handleChange(event) { /* ... */ }
return ( <MyInput ref={refs.input} onChange={handleChange} value="defaultValue" /> );}useControlledInput works with any component that exposes get and set
through its context, not just wrappers of native inputs.
Live example
Section titled “Live example” Controlled custom radio group
Source
import './examples.css';
import { useTextContent, useControlledInput, useRefProxy } from 'domstatejsx';
import Radio from './Radio.jsx';
export default function App() {
const refs = useRefProxy();
const [getRadio, setRadio] = useControlledInput(refs.radio);
const [, setSpan] = useTextContent(refs.span);
function refreshSpan() {
setSpan(getRadio());
}
setTimeout(refreshSpan, 0);
return (
<>
<Radio
defaultValue={3}
onChange={setSpan}
options={[
[0, 'Zero'],
[1, 'One'],
[2, 'Two'],
[3, 'Three'],
]}
ref={refs.radio}
/>
<p>
<button
class="dx-btn"
onClick={() => {
setRadio(2);
refreshSpan();
}}
>
Select "two"
</button>
</p>
<p>
Selected Value: <span ref={refs.span} />
</p>
</>
);
}