英文:
React forwardref and various Props in TypeScript
问题
type Ref = any
forwardRef<Ref, FooProps>((props, ref) => {...})
英文:
I have a component like this
interface FooProps{
children: JSX.Element,
id?: string,
error?: boolean,
width?: number,
ref?: any
}
const Foo = forwardRef(({
children,
id,
error,
ref,
width,
}: FooProps) => {
return <ul
id={id}
ref={ref}
style={{width: width, backgroundColor: error ? 'red' . 'green'}}>
{children}
</ul>
})
export default Foo;
Now, the compiler complains that forwardRef()
only accepts two parameters, props
and ref
.
How would I tell TypeScript that the shape props
is the shape of FooProps
? This
type Ref = any
forwardRef(<Ref, FooProps>((props, ref)) => {...})
Does not work.
答案1
得分: 1
你的代码中有几个需要注意的地方:
- 在使用
forwardRef
时,ref
不是props
的一部分。它是渲染函数的第二个参数。我知道这有点不直观,但目前是这样的(React 团队内部可能有讨论要更改这一点)。 - 我建议在声明组件属性中的
children
时,始终使用React.ReactNode
,以确保能够匹配任何可以作为任何渲染函数的有效返回值的内容,包括null
或string
。 - 为
forwardRef
提供类型是在括号之前进行的:forwardRef<Type-of-ref, Type-of-Props>(...)
示例:
接口 PopupAPI {
打开: () => void;
关闭: () => void;
}
接口 PopupProps {
children: React.ReactNode;
在关闭时?: () => void;
标题?: string;
}
输出 const Popup= forwardRef<PopupAPI, PopupProps>(({ 在关闭时, children, 标题 }, ref) => {
// useImperativeHandle(...);
// ...
});
另一个与您的用例更接近的示例:
接口 FooProps {
children: React.ReactNode;
标识?: string;
错误?: boolean;
宽度?: number;
}
输出 const Foo = forwardRef<HTMLElement, FooProps>(({children, 标识, 错误, 宽度}, ref) => (
<ul id={标识} ref={ref}>
{children}
</ul>
));
英文:
There are several things that need to be addressed in your code:
- when using
forwardRef
theref
is not part of theprops
. It is a second argument to the render function. I know this is unintuitive but that's the way it is currently (there is or was some discussion within the react team to change this) - I recommend to use
React.ReactNode
whenever you declarechildren
in component props, to actually match anything that could count as valid return value of any render function, includingnull
orstring
. - providing types to
forwardRef
is done before the parentheses:forwardRef<Type-of-ref, Type-of-Props>(...)
An example:
interface PopupAPI {
open: () => void;
close: () => void;
}
interface PopupProps {
children: React.ReactNode;
onClose?: () => void;
title?: string;
}
export const Popup= forwardRef<PopupAPI, PopupProps>(({ onClose, children, title }, ref) => {
// useImperativeHandle(...);
// ...
});
and one example nearer to your use case:
interface FooProps {
children: React.ReactNode;
id?: string;
error?: boolean;
width?: number;
}
export const Foo = forwardRef<HTMLElement, FooProps>(({children, id, error, width}, ref) => (
<ul id={id} ref={ref}>
{children}
</ul>
));
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论