简体   繁体   English

如何正确标记回调引用的类型

[英]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}/>
})

My code is as above, but there is a error: Property 'current' does not exist on type '(instance: ITextInputRef | null) => void'.If I set the type to any, it works fine我的代码如上,但有一个错误:属性 'current' 在类型 '(instance: ITextInputRef | null) => void' 上不存在。如果我将类型设置为 any,它工作正常

To answer your question directly, useCallback does not return a React.MutableRefObject<> like useRef does.要直接回答您的问题, useCallback不会像useRef那样返回React.MutableRefObject<> It simply memoizes your function so that it doesn't change between renders.它只是记住你的函数,这样它就不会在渲染之间改变。 The return type of useCallback is the same as your function, which in your example is (node: ITextInputRef) => void . useCallback的返回类型与您的函数相同,在您的示例中为(node: ITextInputRef) => void

If you want to store the reference passed to a callback ref, you have to supply your own ref object.如果要存储传递给回调 ref 的引用,则必须提供自己的 ref 对象。 The type passed to your callback will be HTMLInputElement for input elements:传递给回调的类型将为输入元素的HTMLInputElement

const inputRef = useRef<HTMLInputElement>(null);
const storeRef = useCallback((ref: HTMLInputElement) {
  if (ref !== null)
    inputRef.current = ref;
}, []);

return <input ref={storeRef} />;

Callback refs are a lower level tool for when you need to do something precisely on mount or unmount.当您需要在装载或卸载时精确执行某些操作时,回调引用是一种较低级别的工具。 They'll get called on mount with the reference value, and on unmount with null .它们将在 mount 时使用参考值调用,在 unmount 时使用null调用。 If all you need is to do is use the reference during events, you can take a shortcut and pass the ref object directly to the ref attribute.如果您需要做的只是在事件期间使用引用,您可以走捷径,将 ref 对象直接传递给ref属性。 You just have to assume that the current property might be null when you try to use it:当您尝试使用它时,您只需要假设current属性可能为null

const inputRef = useRef<HTMLInputRef>(null);
return <input ref={inputRef} />

Since your example is doing a lot of interesting experiments, also consider this: callback refs and useImparativeHandle are tools of last resort, for when you can't fit what you're doing into React's model.由于您的示例进行了许多有趣的实验,因此还要考虑这一点:回调 refs 和useImparativeHandle是最后的工具,因为当您无法将正在做的事情放入 React 模型时。

To simply set the state for an input, first try using plain React events:要简单地为输入设置状态,首先尝试使用普通的 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM