1.)JSX.Element,ReactNode和ReactElement有什么区别?
ReactElement和JSX.Element
是React.createElement
直接调用或通过JSX翻译进行调用的结果。这是一个对象type
,props
和key
。JSX.Element
是ReactElement
,其props
和type
具有类型any
,因此它们大致相同。
const jsx = <div>hello</div>
const ele = React.createElement("div", null, "hello");
ReactNode用作render()
类组件的返回类型。这也是children
属性的默认类型PropsWithChildren
。
const Comp: FunctionComponent = props => <div>{props.children}</div>
在React类型声明中,它看起来更加复杂,但等效于:
type ReactNode = {} | null | undefined;
您几乎可以将所有内容分配给ReactNode
。我通常更喜欢更强的类型,但是可能会有一些有效的情况来使用它。
2.)为什么类组件的render方法返回ReactNode,而函数组件返回ReactElement?
tl; dr:这是当前与TS核心不相关的TS类型不兼容。
原则上,render()
在React / JS中,类组件支持与函数组件相同的返回类型。关于TS,由于历史原因和对向后兼容性的需要,不同类型仍然保持类型不一致。
理想情况下,有效的返回类型可能看起来像这样:
type ComponentReturnType = ReactElement | Array<ComponentReturnType> | string | number
| boolean | null
3.)我该如何解决null问题?
一些选项:
const MyComp1 = ({ condition }: { condition: boolean }) =>
condition ? <div>Hello</div> : null
const MyComp2 = (): JSX.Element => <div>Hello</div>;
const MyComp3 = (): React.ReactElement => <div>Hello</div>;
const MyComp4: React.FC<MyProps> = () => <div>Hello</div>;
注意:避免操作React.FC
不会使您摆脱JSX.Element | null
返回类型的限制。
Create React App最近从其模板中删除React.FC
,因为它具有一些隐式{children?: ReactNode}
类型定义之类的怪癖。因此,React.FC
谨慎使用可能更可取。
在极端情况下,您可以添加类型断言或片段作为解决方法:
const MyCompFragment: FunctionComponent = () => <>"Hello"</>
const MyCompCast: FunctionComponent = () => "Hello" as any
class Example extends Component<ExampleProps> {
对于类和const Example: FunctionComponent<ExampleProps> = (props) => {
函数组件,应该看起来像(ExampleProps
期望道具的接口在哪里)。然后,这些类型具有足够的信息,可以推断出返回类型。