![](/img/trans.png)
[英]How do I type a ref callback with useCallback (with Typescript)?
[英]How do I correctly mark the type of the callback ref
function App() {
const inputRef: any = useCallback((node: ITextInputRef)=> {
if(node !== null) {
setValue(node.value);
}
}, []);
const [value, setValue] = useState("");
const handleClick = () => {
console.log("textInput value", inputRef.current!.value);
setValue(inputRef.current!.value);
}
return (
<>
<input type="text" value={value} onChange={() => {}} /><br/>
<TextInput ref = {inputRef}/>
<button onClick={handleClick}>click</button>
</>
);
}
interface ITextInputRef {
value: string;
}
const TextInput = forwardRef((props,ref: ForwardedRef<ITextInputRef>) => {
const [value, setValue] = useState("");
const inputRef = useRef<HTMLInputElement>(null);
const changeValue = (e: ChangeEvent<HTMLInputElement>) => {
setValue(e.target.value);
};
useImperativeHandle(ref, () => ({
value: inputRef.current!.value,
}));
return <input ref = {inputRef} onChange={changeValue} value={value}/>
})
我的代码如上,但有一个错误:属性 'current' 在类型 '(instance: ITextInputRef | null) => void' 上不存在。如果我将类型设置为 any,它工作正常
要直接回答您的问题, useCallback
不会像useRef
那样返回React.MutableRefObject<>
。 它只是记住你的函数,这样它就不会在渲染之间改变。 useCallback
的返回类型与您的函数相同,在您的示例中为(node: ITextInputRef) => void
。
如果要存储传递给回调 ref 的引用,则必须提供自己的 ref 对象。 传递给回调的类型将为输入元素的HTMLInputElement
:
const inputRef = useRef<HTMLInputElement>(null);
const storeRef = useCallback((ref: HTMLInputElement) {
if (ref !== null)
inputRef.current = ref;
}, []);
return <input ref={storeRef} />;
当您需要在装载或卸载时精确执行某些操作时,回调引用是一种较低级别的工具。 它们将在 mount 时使用参考值调用,在 unmount 时使用null
调用。 如果您需要做的只是在事件期间使用引用,您可以走捷径,将 ref 对象直接传递给ref
属性。 当您尝试使用它时,您只需要假设current
属性可能为null
:
const inputRef = useRef<HTMLInputRef>(null);
return <input ref={inputRef} />
由于您的示例进行了许多有趣的实验,因此还要考虑这一点:回调 refs 和useImparativeHandle
是最后的工具,因为当您无法将正在做的事情放入 React 模型时。
要简单地为输入设置状态,首先尝试使用普通的 React 事件:
const TextInput = function() {
const [value, setValue] = useState('');
function changeValue(e: ChangeEvent<HTMLInputElement>) {
setValue(e.currentTarget.value);
}
return <input onChange={changeValue} value={value} />
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.