ref 为空 Typescript + NextJS

问题描述 投票:0回答:1

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

但不幸的是,子组件(称为 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个回答
3
投票

您不能将

ref
用作组件中的 prop,因为它是保留的 1 2 3(就像
key
)。当调用函数组件时,React 将省略
ref
中的
props
属性。

相反,您应该将

ref
作为
CanvasUI
组件的第二个参数,然后使用
forwardRef
创建它。
useImperativeHandle
的文档对此进行了解释:

使用命令句柄

useImperativeHandle(ref, createHandle, [deps])

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

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

在此示例中,呈现

<FancyInput ref={inputRef} />
的父组件将能够调用
inputRef.current.focus()

© www.soinside.com 2019 - 2024. All rights reserved.