Javascript 何时使用JSX.Element vs ReactNode vs ReactElement?
我目前正在将React应用程序迁移到TypeScript。到目前为止,这工作得很好,但是我的Javascript 何时使用JSX.Element vs ReactNode vs ReactElement?,javascript,reactjs,typescript,Javascript,Reactjs,Typescript,我目前正在将React应用程序迁移到TypeScript。到目前为止,这工作得很好,但是我的render函数的返回类型和我的函数组件都有问题 到目前为止,我一直使用JSX.Element作为返回类型,现在如果组件决定不呈现任何内容,即返回null,这将不再有效,因为null对于JSX.Element来说不是有效的值。这是我旅程的开始,因为现在我搜索了web,发现您应该使用ReactNode,它还包括null以及其他一些可能发生的事情。这似乎是更好的选择 但是,现在在创建函数组件时,TypeScr
render
函数的返回类型和我的函数组件都有问题
到目前为止,我一直使用JSX.Element
作为返回类型,现在如果组件决定不呈现任何内容,即返回null
,这将不再有效,因为null
对于JSX.Element
来说不是有效的值。这是我旅程的开始,因为现在我搜索了web,发现您应该使用ReactNode
,它还包括null
以及其他一些可能发生的事情。这似乎是更好的选择
但是,现在在创建函数组件时,TypeScript会抱怨ReactNode
类型。同样,经过一些搜索,我发现对于函数组件,应该使用ReactElement
。但是,如果我这样做,兼容性问题就消失了,但是现在TypeScript再次抱怨null
不是有效值
长话短说,我有三个问题:
JSX.Element
、ReactNode
和ReactElement
之间有什么区别render
方法返回ReactNode
,而函数组件返回ReactElement
null
,如何解决此问题 type Key = string | number
interface ReactElement<P = any, T extends string | JSXElementConstructor<any> = string | JSXElementConstructor<any>> {
type: T;
props: P;
key: Key | null;
}
函数是“无状态组件”:
接口组件{
(props:P&{children?:ReactNode},context?:any):ReactElement | null;
//…没关系
}
这实际上是由于
关于null,我如何解决这个问题
将其输入为ReactElement | null
,就像react一样。或者让Typescript推断类型
1.)JSX.Element、ReactNode和ReactElement之间有什么区别
ReactElement和JSX.Element
是直接调用或通过JSX Transfilation调用的结果。它是一个具有类型
、道具
和键
的对象。是ReactElement
,其props
和type
具有typeany
,因此它们大致相同
const jsx = <div>hello</div>
const ele = React.createElement("div", null, "hello");
在中,它看起来更复杂,但相当于:
您可以将几乎所有内容分配给ReactNode
。我通常更喜欢更强的类型,但可能会有一些有效的情况下使用它
2.)为什么类组件的呈现方法返回ReactNode,而函数组件返回ReactElement tl;dr:这是当前TS类型的不兼容
- TS类组件:使用
返回render()
,比React/JS更具权限ReactNode
- TS函数组件:返回
,比React/JS更严格JSX.Element | null
render()
在React/JS类组件中作为函数组件。关于TS,由于历史原因和向后兼容性的需要,不同的类型仍然是一种类型不一致性
理想情况下,a可能更像这样:
declare global {
namespace JSX {
interface Element extends React.ReactElement<any, any> { }
}
}
type ComponentReturnType = ReactElement | Array<ComponentReturnType> | string | number
| boolean | null // Note: undefined is invalid
我很惊讶会出现这种情况,因为通常不需要使用组件指定返回类型。您要为组件做什么类型的签名?类的
类示例扩展组件{
,函数组件的常量示例:FunctionComponent=(props)=>{
(其中ExampleProps
是预期props的接口)。然后这些类型有足够的信息来推断返回类型。这些类型是在@NicholasTower定义的。我们的linting规则强制显式地提供返回类型,这就是为什么会出现这种情况(这是一件好事,因为你对自己所做的事情思考得更多,这有助于理解,而不是让编译器推断一切).很公平,我没有想到林廷规则。@Jonaswillms谢谢你的链接,但我不认为这回答了我的问题。谢谢你的详细回答!这完美地回答了问题1,但仍然没有回答问题2和问题3。你也能提供一些关于它们的指导吗?@goloRoden当然,我现在只是有点累,没有花点时间浏览手机上的类型…;)Hi@Jonaswillms。关于“它们没有。ReactComponent定义为:render():JSX.Element | null | false;”,你在哪里看到的?它看起来像是将ReactNode返回给我()还有一个小的打字错误,我认为ReactComponent
应该是React.Component
或Component
@MarkDoliner奇怪,我可以发誓我从文件中复制了那种类型……不管怎样,你完全正确,我会编辑的伙计们,网上有关于React&typescript的正式文档吗?
render(): ReactNode;
interface StatelessComponent<P = {}> {
(props: P & { children?: ReactNode }, context?: any): ReactElement | null;
// ... doesn't matter
}
const jsx = <div>hello</div>
const ele = React.createElement("div", null, "hello");
const Comp: FunctionComponent = props => <div>{props.children}</div>
// children?: React.ReactNode
type ReactNode = {} | null | undefined;
// super type `{}` has absorbed *all* other types, which are sub types of `{}`
// so it is a very "broad" type (I don't want to say useless...)
type ComponentReturnType = ReactElement | Array<ComponentReturnType> | string | number
| boolean | null // Note: undefined is invalid
// Use type inference; inferred return type is `JSX.Element | null`
const MyComp1 = ({ condition }: { condition: boolean }) =>
condition ? <div>Hello</div> : null
// Use explicit function return types; Add `null`, if needed
const MyComp2 = (): JSX.Element => <div>Hello</div>;
const MyComp3 = (): React.ReactElement => <div>Hello</div>;
// Option 3 is equivalent to 2 + we don't need to use a global (JSX namespace)
// Use built-in `FunctionComponent` or `FC` type
const MyComp4: React.FC<MyProps> = () => <div>Hello</div>;
const MyCompFragment: FunctionComponent = () => <>"Hello"</>
const MyCompCast: FunctionComponent = () => "Hello" as any
// alternative to `as any`: `as unknown as JSX.Element | null`