我正在尝试将一个参考文件传递给一个自定义组件(这样我就可以将焦点设置到组件上)。
但我一直在犯这个错误
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
添加到道具中来解决这一问题。
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
既是道具的一部分,也是传递给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:
function forwardRef<T, P = {}>(Component: RefForwardingComponent<T, P>): ForwardRefExoticComponent<PropsWithoutRef<P> & RefAttributes<T>>;
因此,forwardRef
函数返回类型为ForwardRefExoticComponent<PropsWithoutRef<P> & RefAttributes<T>>
的组件。这是一个组件,它的道具类型为PropsWithoutRef<P>
与RefAttributes<T>
相交。这两种类型也在同一个文件中定义。
据我所知,第一个基本不包括P中的ref
(在我最初的示例中是Props
)。第二个定义为
interface RefAttributes<T> extends Attributes {
ref?: Ref<T>;
}
考虑到这些信息,我真的不明白为什么要将ref
添加到自己的Props
中。看起来forwardRef
真的应该为我做这件事--甚至从我自己的Props
中移除ref
.
有人能解释一下这是怎么回事吗?
发布于 2020-03-10 14:01:00
问题是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://stackoverflow.com/questions/60052450
复制相似问题