ref 为 null Typescript + NextJS
ref is null Typescript + NextJS
我需要从父组件中的自定义子组件调用方法。
但不幸的是,对子组件(称为 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;
}
我省略了不重要的代码以使其更具可读性
您不能在组件中使用 ref
作为 prop,因为它是 reserved(就像 key
)。当调用你的函数组件时,React 将省略 props
中的 ref
属性。
相反,您应该将 ref
定位为 CanvasUI
组件的第二个参数,然后使用 forwardRef
. This is explained in the documentation for useImperativeHandle
:
创建它
useImperativeHandle
useImperativeHandle(ref, createHandle, [deps])
useImperativeHandle
customizes the instance value that is exposed to parent components when using ref
. As always, imperative code using refs should be avoided in most cases. useImperativeHandle
should be used with forwardRef
:
function FancyInput(props, ref) {
const inputRef = useRef();
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current.focus();
}
}));
return <input ref={inputRef} ... />;
}
FancyInput = forwardRef(FancyInput);
In this example, a parent component that renders <FancyInput ref={inputRef} />
would be able to call inputRef.current.focus()
.
我需要从父组件中的自定义子组件调用方法。
但不幸的是,对子组件(称为 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;
}
我省略了不重要的代码以使其更具可读性
您不能在组件中使用 ref
作为 prop,因为它是 reserved(就像 key
)。当调用你的函数组件时,React 将省略 props
中的 ref
属性。
相反,您应该将 ref
定位为 CanvasUI
组件的第二个参数,然后使用 forwardRef
. This is explained in the documentation for useImperativeHandle
:
useImperativeHandle
useImperativeHandle(ref, createHandle, [deps])
useImperativeHandle
customizes the instance value that is exposed to parent components when usingref
. As always, imperative code using refs should be avoided in most cases.useImperativeHandle
should be used withforwardRef
:function FancyInput(props, ref) { const inputRef = useRef(); useImperativeHandle(ref, () => ({ focus: () => { inputRef.current.focus(); } })); return <input ref={inputRef} ... />; } FancyInput = forwardRef(FancyInput);
In this example, a parent component that renders
<FancyInput ref={inputRef} />
would be able to callinputRef.current.focus()
.