美文网首页
React v18+ 中 React.FC读取children报

React v18+ 中 React.FC读取children报

作者: 拜仁的月饼 | 来源:发表于2024-01-15 16:46 被阅读0次

问题

代码如下:

import React from "react";

interface TestComponentProps {
  hello: string;
}

const TestComponent: React.FC<TestComponentProps> = (props) => {
  // 注意下面的children
  const { hello, children } = props;
  return <div className="TestComponent">{hello}</div>;
};

export default TestComponent;

如果你用的是React18,那么会发现编辑器提示如下图(如果eslint配的非常严格,你的程序此时应该会报ts错误了):

报错截图

你会发现, children从props中消失了。

在固有认知中,用React.FC<TestComponentProps>包起来的props就应该天生具有一个可选的children,但为什么在React 18不行了?

原因

这是因为ts类型定义导致。直接看18的ts定义源码:

// react 18+ FC类型定义
type FC<P = {}> = FunctionComponent<P>;

interface FunctionComponent<P = {}> {
    // 注意这一行的差别
    (props: P, context?: any): ReactNode;
    propTypes?: WeakValidationMap<P> | undefined;
    contextTypes?: ValidationMap<any> | undefined;
    defaultProps?: Partial<P> | undefined;
    displayName?: string | undefined;
}

那么,为什么16.817不会报这个错误呢?还是看源码:

// react 16.8 / 17 FC类型定义
type FC<P = {}> = FunctionComponent<P>;

interface FunctionComponent<P = {}> {
    // 注意这一行的差别
    (props: PropsWithChildren<P>, context?: any): ReactElement<any, any> | null;
    propTypes?: WeakValidationMap<P>;
    contextTypes?: ValidationMap<any>;
    defaultProps?: Partial<P>;
    displayName?: string;
}

可以看出, FunctionalComponent(即FC)在18与16.8 / 17类型定义不完全相同,18将PropsWithChildren移除了,即props不会天生包含children了,所以导致了上一部分的ts错误。

解决

重新定义一个补充类型即可:

import { PropsWithChildren, FC } from 'react';

export type RFC<T = unknown> = FC<PropsWithChildren<T>>;

然后在适当的时机import { RFC } from '@/your-type-file.ts';,并且用RFC<IProps>替代React.FC<IProps>即可。

相关文章

网友评论

      本文标题:React v18+ 中 React.FC读取children报

      本文链接:https://www.haomeiwen.com/subject/snshodtx.html