useImperativeHandle function
Customizes the ref
value that is exposed to parent components when using forwardRef2 by setting ref.current
to the return value of createHandle
.
In most cases, imperative code using refs should be avoided. For more information, see reactjs.org/docs/refs-and-the-dom.html#when-to-use-refs.
Note: there are two rules for using Hooks:
- Only call Hooks at the top level.
- Only call Hooks from inside a DartFunctionComponent.
Example:
class FancyInputApi {
final void Function() focus;
FancyInputApi(this.focus);
}
final FancyInput = react.forwardRef2((props, ref) {
final inputRef = useRef<InputElement>();
useImperativeHandle(
ref,
() => FancyInputApi(() => inputRef.current.focus()),
/// Because the return value of [createHandle] never changes, it is not necessary for [ref.current]
/// to be re-set on each render so this dependency list is empty.
[],
);
return react.input({
'ref': inputRef,
'value': props['value'],
'onChange': (e) => props['update'](e.target.value),
});
});
UseImperativeHandleTestComponent(Map props) {
final inputValue = useState('');
final fancyInputRef = useRef<FancyInputApi>();
return react.Fragment({}, [
FancyInput({
'value': inputValue.value,
'update': inputValue.set,
'ref': fancyInputRef,
}, []),
react.button({'onClick': (_) => fancyInputRef.current.focus()}, ['Focus Input']),
]);
}
Learn more: reactjs.org/docs/hooks-reference.html#useimperativehandle.
Implementation
void useImperativeHandle(dynamic ref, dynamic Function() createHandle, [List<dynamic>? dependencies]) =>
// ref will be a JsRef in forwardRef2, or a Ref in forwardRef. (Or null if no ref is provided)
//
// For some reason the ref argument to React.forwardRef is usually a JsRef object no matter the input ref type,
// but according to React the ref argument to useImperativeHandle and React.forwardRef can be any ref type...
// - https://github.com/facebook/flow/blob/master@%7B2020-09-08%7D/lib/react.js#L373
// - https://github.com/facebook/flow/blob/master@%7B2020-09-08%7D/lib/react.js#L305
// and not just a ref object, so we type it as dynamic here.
React.useImperativeHandle(ref is Ref ? ref.jsRef : ref, allowInterop(createHandle), dependencies);