![](/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.