Mic*_*bry 168 javascript typescript reactjs
我升级到 React 18 并且编译得很好。如今,似乎每个使用子组件的组件都会抛出错误。Property 'children' does not exist on type 'IPageProps'.
在儿童道具自动包含在FC
界面中之前。现在看来我必须手动添加children: ReactNode
。对于反应儿童来说,正确的打字稿类型是什么?
这是 React 18 更新的一部分,还是我的环境出了问题?
包.json
"react": "^18.0.0",
"react-dom": "^18.0.0",
"next": "12.1.4",
"@types/react": "18.0.0",
"@types/react-dom": "18.0.0",
Run Code Online (Sandbox Code Playgroud)
tsconfig.json
{
"compilerOptions": {
"target": "esnext",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "preserve",
"alwaysStrict": true,
"sourceMap": true,
"incremental": true
},
"include": ["src"],
"exclude": ["node_modules"]
}
Run Code Online (Sandbox Code Playgroud)
Dan*_*mov 224
尽管这个答案是正确的,但我想指出的是,您绝对不必使用这个PropsWithChildren
助手。(它主要用于 codemod ,而不是手动使用。)
相反,我发现手动定义它们更容易。
import * as React from 'react';
type Props = {};
const Component: React.FC<Props> = ({children}) => {...}
Run Code Online (Sandbox Code Playgroud)
import * as React from 'react';
type Props = {
children?: React.ReactNode
};
const Component: React.FC<Props> = ({children}) => {...}
Run Code Online (Sandbox Code Playgroud)
这就是所需要的一切。
或者您可以React.FC
完全停止使用。
import * as React from 'react';
type Props = {
children?: React.ReactNode
};
function Component({children}: Props): React.ReactNode {
...
}
Run Code Online (Sandbox Code Playgroud)
在 React 中,children
是一个常规的 prop,并不是什么特殊的东西。因此,您需要像定义所有其他 props 一样定义它。之前隐藏它的打字是错误的。
sim*_*Pod 82
import React from 'react';
const Component: React.FC = ({children}) => {...}
Run Code Online (Sandbox Code Playgroud)
创建例如react.d.ts来定义你的助手类型 1
import React from 'react';
export type ReactFCWithChildren = React.FC<PropsWithChildren>;
Run Code Online (Sandbox Code Playgroud)
import {ReactFCWithChildren } from './react';
const Component: ReactFCWithChildren = ({children}) => {...}
Run Code Online (Sandbox Code Playgroud)
或者
import React from 'react';
const Component: React.FC<React.PropsWithChildren> = ({children}) => {...}
Run Code Online (Sandbox Code Playgroud)
import React from 'react';
interface Props {
...
}
const Component: React.FC<Props> = ({children}) => {...}
Run Code Online (Sandbox Code Playgroud)
import React from 'react';
interface Props {
...
}
const Component: React.FC<React.PropsWithChildren<Props>> = ({children}) => {...}
Run Code Online (Sandbox Code Playgroud)
或者
import React from 'react';
interface Props extends React.PropsWithChildren {
...
}
const Component: React.FC<Props> = ({children}) => {...}
Run Code Online (Sandbox Code Playgroud)
1虽然手动定义似乎很容易,但最好利用 @types 包中已为您准备的类型。当将来类型发生更改时,它将自动从库中传播到代码中的任何位置,因此您不必亲自接触它。 children
您可以通过创建react.d.ts
具有以下定义的文件来覆盖反应类型,这会将类型恢复为 @types/react v17
import * as React from '@types/react';
declare module 'react' {
interface FunctionComponent<P = {}> {
(props: PropsWithChildren<P>, context?: any): ReactElement<any, any> | null;
}
}
Run Code Online (Sandbox Code Playgroud)
children
prop 已从React.FunctionComponent
( React.FC
) 中删除,因此您必须显式声明它。
TS 会告诉你错误,例如
输入 '{ 孩子:...; }' 与类型“IntrinsicAttributes”没有共同的属性。”
您可以在此处阅读原因。TLDR 它可以防止像这样的错误
const ComponentWithNoChildren: React.FC = () => <>Hello</>;
...
<ComponentWithNoChildren>
// passing children is wrong since component does not accept any
<UnusedChildrenSinceComponentHasNoChildren />
</ComponentWithNoChildren>
Run Code Online (Sandbox Code Playgroud)
Gar*_*vae 12
是的,React.FC 类型已经改变。但是你可以用二十一点和反应孩子来声明你自己的类型。
我的方法是src/types/react.d.ts
使用这样的内容进行创建:
import React, { PropsWithChildren } from 'react';
export type ReactFCC<T> = React.FC<PropsWithChildren<T>>;
Run Code Online (Sandbox Code Playgroud)
您可以为参数添加默认值T
:
import React, { PropsWithChildren } from 'react';
export type ReactFCC<T = Record<string, unknown>> = React.FC<PropsWithChildren<T>>;
Run Code Online (Sandbox Code Playgroud)
或者
import React, { PropsWithChildren } from 'react';
export type ReactFCC<T = unknown> = React.FC<PropsWithChildren<T>>;
Run Code Online (Sandbox Code Playgroud)
您现在可以选择不在泛型中指定类型ReactFCC
而不发出警告。
前:
export const Component: ReactFCC<SomeType> = props => {
const { children } = props;
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
后:
export const Component: ReactFCC = props => {
const { children } = props;
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
FC
)。FCC
(表示:- 带子项的功能组件;))// Put this in your global types.ts
import { FC, PropsWithChildren } from "react";
// Custom Type for a React functional component with props AND CHILDREN
export type FCC<P={}> = FC<PropsWithChildren<P>>
Run Code Online (Sandbox Code Playgroud)
children
Component 中的属性时props
,请像这样使用它:// import FCC from types.ts
const MyComponent: FCC = ({children}) => {
return (
<>{children}</>
)
}
Run Code Online (Sandbox Code Playgroud)
或者
interface MyCompoProps{
prop1: string
}
const MyComponent: FCC<MyCompoProps> = ({children, prop1}) => {
return (
<>{children}</>
)
}
Run Code Online (Sandbox Code Playgroud)
PS这个答案可能看起来与 @Garvae 的答案类似,但他的
ReactFCC<P>
type
答案应该这样写ReactFCC<P={}>
,以防止出现以下错误:
Generic type 'ReactFCC' requires 1 type argument(s)
当您没有向组件传递任何 props 时,会发生此错误。儿童道具应该是可选道具。因此,给这些 props 一个默认
{}
值(即P = {}
)可以解决这个问题。
归档时间: |
|
查看次数: |
133743 次 |
最近记录: |