gpt4 book ai didi

reactjs - 在 React 中,使用 TypeScript,如何使用 RefForwardingComponent 和 forwardRef 将 ref 传递给自定义组件?

转载 作者:行者123 更新时间:2023-12-04 14:40:24 28 4
gpt4 key购买 nike

我正在尝试将 ref 传递给自定义组件(以便我可以将焦点设置到该组件)。

但我不断收到此错误

const RefComp: React.RefForwardingComponent<HTMLInputElement, Props>
Type '{ value: string; onChange: Dispatch<SetStateAction<string>>; ref: MutableRefObject<HTMLInputElement | undefined>; }'
is not assignable to type 'IntrinsicAttributes & Props & { children?: ReactNode; }'.
Property 'ref' does not exist on type 'IntrinsicAttributes & Props & { children?: ReactNode; }'.ts(2322)

这是我的代码
import * as React from 'react';
import {useRef, useState, RefForwardingComponent, forwardRef} from 'react';

interface Props {
value: string;
onChange(event: string): void;
}

const RefComp: RefForwardingComponent<HTMLInputElement, Props> = forwardRef<
HTMLInputElement,
Props
>(({value, onChange}, ref) => (
<input
value={value}
onChange={event => onChange(event.target.value)}
ref={ref}
/>
));

export default function App() {
const [val, setVal] = useState('');
const inputRef = useRef<HTMLInputElement>();

return (
<div className="App">
<RefComp value={val} onChange={setVal} ref={inputRef} />
<p>{val}</p>
</div>
);
}

这是一个代码沙盒
https://codesandbox.io/s/crimson-cdn-klfp5

如果我忽略错误,代码似乎工作正常。所以不知道为什么我得到它......

任何人都可以解释为什么我收到错误,以及我如何解决它? :)

编辑:

如评论中所述,您可以通过添加 ref 来解决此问题。到你的 Prop 。
import * as React from 'react';
import {
useRef,
useState,
RefForwardingComponent,
forwardRef,
MutableRefObject,
} from 'react';

interface Props {
value: string;
onChange(event: string): void;
ref?: MutableRefObject<HTMLInputElement | null>;
}

const RefComp: RefForwardingComponent<HTMLInputElement, Props> = forwardRef<
HTMLInputElement,
Props
>(({value, onChange}, ref) => (
<input
value={value}
onChange={event => onChange(event.target.value)}
ref={ref}
/>
));

export default function App() {
const [val, setVal] = useState('');
const inputRef = useRef<HTMLInputElement>(null);

return (
<div className="App">
<RefComp value={val} onChange={setVal} ref={inputRef} />
<p>{val}</p>
</div>
);
}

但这感觉不对。现在我们说我们有 ref既作为 Prop 的一部分,又作为传递给 forwardRef 的函数的第二个回调参数

如果我这样写,我的问题可能会更清楚
const RefComp: RefForwardingComponent<HTMLInputElement, Props> = forwardRef<
HTMLInputElement,
Props
>((props: Props, ref) => (
<input
value={props.value}
onChange={event => props.onChange(event.target.value)}
ref={ref /* here, props.ref is also available, but wouldn't work */ }
/>
));

编辑 2:

这是一个相关的问题

Typescript RefForwardingComponent not working

编辑 3:

我找到了相关的源代码。 https://github.com/DefinitelyTyped/DefinitelyTyped/blob/33f6179e0f25b0ca798ad89a667c0a27ea0c98dd/types/react/index.d.ts#L702
function forwardRef<T, P = {}>(Component: RefForwardingComponent<T, P>): ForwardRefExoticComponent<PropsWithoutRef<P> & RefAttributes<T>>;

所以 forwardRef函数返回 ForwardRefExoticComponent<PropsWithoutRef<P> & RefAttributes<T>> 类型的组件.这是一个接受类型为 PropsWithoutRef<P> 的 Prop 的组件与 RefAttributes<T> 相交.这两种类型也在同一个文件中定义。

据我所知,第一个基本上只是排除了 ref来自 P(在我的原始示例中为 Props)。第二个定义为
interface RefAttributes<T> extends Attributes {
ref?: Ref<T>;
}

鉴于这些信息,我真的不明白为什么我必须添加 ref给我自己 Props .真的好像 forwardRef应该为我做 - 甚至实际上删除 ref来自我自己的 Props ...

有人可以解释一下这里发生了什么吗?

最佳答案

问题是 RefComp 的类型定义错误.删除它(让 TypeScript 推断类型)并且代码工作得很好。

import * as React from 'react';
import {useRef, useState, forwardRef} from 'react';

interface Props {
value: string;
onChange(event: string): void;
}

const RefComp = forwardRef<HTMLInputElement, Props>(
({value, onChange}, ref) => (
<input
value={value}
onChange={event => onChange(event.target.value)}
ref={ref}
/>
),
);

export default function App() {
const [val, setVal] = useState('');
const inputRef = useRef<HTMLInputElement>(null);

React.useEffect(() => {
if (inputRef.current) {
inputRef.current.focus();
}
}, []);

return (
<div className="App">
<RefComp value={val} onChange={setVal} ref={inputRef} />
<p>{val}</p>
</div>
);
}


https://codesandbox.io/s/quizzical-liskov-bsruh

关于reactjs - 在 React 中,使用 TypeScript,如何使用 RefForwardingComponent 和 forwardRef 将 ref 传递给自定义组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60052450/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com