【问题标题】:ref is null Typescript + NextJSref 为空 Typescript + NextJS
【发布时间】:2022-01-18 17:25:49
【问题描述】:

我需要从父组件中的自定义子组件调用方法。

但不幸的是,子组件(称为 CanvasUI)的引用始终为空。我不明白为什么在我看来我已经正确地实现了一切。

这是我的父组件

...

export default function Home() {
  ...
  const canvas = useRef<CanvasRef>(null);

  ...
  function clearCanvas() {
    // canvas.current.resetCanvas();
    console.log(canvas.current);
  }
  return (
    <div className="flex justify-center items-center min-h-screen min-w-screen bg-main">
      <div className="flex flex-col">
        ...
        <div className="flex justify-center">
          ...
          <CanvasUI disabled={disableCanvas} word={activeWord} ref={canvas} />
          ...
        </div>
        ...
        <button onClick={() => clearCanvas()}>clear canvas</button>
      </div>
    </div>
  );
}

这是 CanvasUI 组件

...

export default function CanvasUI({
  disabled,
  word,
  ref,
}: {
  disabled: boolean;
  word: string;
  ref: Ref<CanvasRef>;
}) {
  ...
  useImperativeHandle(ref, () => ({ getCanvas, loadCanvas, resetCanvas }));

  ...

  function resetCanvas(): void {
    ...
  }

  ...

  function getCanvas(): String {
    ...
  }

  function loadCanvas(data: String, immediate: Boolean): void {
    ...
  }

  return (
    ...
  );
}

CanvasRef 接口

export default interface CanvasRef {
  getCanvas: () => String;
  loadCanvas: (data: String, immediate: Boolean) => void;
  resetCanvas: () => void;
}

我省略了不重要的代码以使其更具可读性

【问题讨论】:

    标签: javascript reactjs typescript ref use-ref


    【解决方案1】:

    您不能将ref 用作组件中的道具,因为它是reserved(就像key)。 React 在调用你的函数组件时会忽略 props 中的 ref 属性。

    相反,您应该将ref 定位为CanvasUI 组件的第二个参数,然后使用forwardRef 创建它。 useImperativeHandle 的文档中对此进行了解释:

    使用ImperativeHandle

    useImperativeHandle(ref, createHandle, [deps])
    

    useImperativeHandle 自定义使用ref 时暴露给父组件的实例值。与往常一样,在大多数情况下应避免使用 refs 的命令式代码。 useImperativeHandle 应与forwardRef 一起使用:

    function FancyInput(props, ref) {
      const inputRef = useRef();
      useImperativeHandle(ref, () => ({
        focus: () => {
          inputRef.current.focus();
        }
      }));
      return <input ref={inputRef} ... />;
    }
    FancyInput = forwardRef(FancyInput);
    

    在此示例中,呈现&lt;FancyInput ref={inputRef} /&gt; 的父组件将能够调用inputRef.current.focus()

    【讨论】:

      猜你喜欢
      • 2021-12-23
      • 1970-01-01
      • 2017-10-24
      • 1970-01-01
      • 2022-12-01
      • 1970-01-01
      • 2020-05-28
      • 2022-12-07
      • 2021-09-18
      相关资源
      最近更新 更多