@types/react
包但遇到了问题。Definitions by:
中的index.d.ts
)以便他们可以回应。以下组件
const SFC: React.StatelessComponent = (props) => props.children;
class C extends React.Component {
render() {
return this.props.children;
}
}
给出错误
Type '(props: { children?: ReactNode; }) => ReactNode' is not assignable to type 'StatelessComponent<{}>'.
Type 'ReactNode' is not assignable to type 'ReactElement<any> | null'.
Type 'undefined' is not assignable to type 'ReactElement<any> | null'.
Class 'C' incorrectly extends base class 'Component<{}, {}>'.
Types of property 'render' are incompatible.
Type '() => ReactNode' is not assignable to type '() => false | Element | null'.
Type 'ReactNode' is not assignable to type 'false | Element | null'.
Type 'undefined' is not assignable to type 'false | Element | null'.
如果您将children
包装在Element
$ 中,它会起作用。
在制作只是向context
添加一些内容的 Provider 组件时,返回children
是很常见的。
我尝试对index.d.ts
进行以下修复
- render(): JSX.Element | null | false;
+ render(): ReactNode;
- (props: P & { children?: ReactNode }, context?: any): ReactElement<any> | null;
+ (props: P & { children?: ReactNode }, context?: any): ReactNode;
但是当我尝试 lint 时,我到处都遇到了错误,我不确定如何修复。
TypeScript compile error: JSX element type 'ReactNode' is not a constructor function for JSX elements.
不,这种变化是不正确的。 你目前不能在 React 中返回多个元素。 即使您在某处进行,也很可能它以某种方式封装在一个中。
只有在带有 Fiber 的 React 16 中才有可能:)
不确定他们是否改变了反应行为,但 redux / react 作者展示了返回 this.props.children 以创建瘦包装器(仅将 childContext 添加到元素)的能力,如https://egghead.io/lessons/中所示
不过,react-native 确实允许您从渲染中返回一组 JSX 元素。 一种解决方法是用React.Children.only(this.props.children)
包装this.props.children
如果有多个元素作为根,它会抛出
对,您可以使用React.Children.only
但ReactNode
和ReactElement
都是this.props.children
的有效值。
const Title = props => <h1>{props.children}</h1>;
<Title>Woah</Title>
是有效且合理的 React 代码。
你可以在 react 16 中返回一个元素数组,但是 TS 会抛出一个错误,因为它认为你不能。
编辑:这样做children: JSX.Element[];
来修复它
根据我目前的经验,似乎 ReactNode 应该是有效的。
const Id: React.SFC<{}> = (props) => props.children
const App = ()= > <Id>This should work but instead fails</Id>
这是否有可能反映在@types/react
中?
没有这个我无法输入 React children
我目前正在将children
包装在React.Fragment
中以解决此问题。
有任何更新吗?
不确定这是否比将children
包装在React.Fragment
中是否正确,但我很幸运这样做
return (children as React.ReactElement);
return <>{foo(}</>;
整晚。 <>
是一种解决方法。
这也给我带来了问题。
我有一个向给定组件添加道具的 HOC,我正在尝试将它与具有return children;
的功能组件一起使用。 仅当我使用解决方法return <>{children}</>;
时它才有效。
这是 HOC 的简化版本:
export interface ExtraProps {
extraProp1: string;
}
export const withExtraProps = <P extends object>(Component: React.ComponentType<P>) => {
return class extends React.Component<Omit<P, keyof ExtraProps>> {
render() {
const extraProps = {
extraProp1: 'test'
};
return (
<Component {...this.props as P} {...extraProps} />
)
}
}
}
这是功能组件的简化版本:
interface ComponentProps extends ExtraProps {
children?: React.ReactNode;
loadingComponent?: ReactElement;
}
export function ExampleComponent(props: ComponentProps) {
const { children, loadingComponent } = props;
const [loading, setLoading] = useState(false);
useEffect(() => {
const fetchData = async () => {
setLoading(true);
await someAsyncCall();
setLoading(false);
}
fetchData();
});
if (loading) {
return loadingComponent || null;
}
return children;
}
// This line errors:
export const FeatureFlag = withExtraProps(ExampleComponent);
我收到以下错误:
Argument of type '(props: ComponentProps) => {} | null | undefined' is not assignable to parameter of type 'ComponentType<ComponentProps>'.
Type '(props: ComponentProps) => {} | null | undefined' is not assignable to type 'FunctionComponent<ComponentProps>'.
Type '{} | null | undefined' is not assignable to type 'ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)> | null) | (new (props: any) => Component<any, any, any>)> | null'.
Type 'undefined' is not assignable to type 'ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)> | null) | (new (props: any) => Component<any, any, any>)> | null'.
如果我将ReactElement | null
的返回类型添加到 ExampleComponent,它会停止抱怨将其传递给 HOC,但在返回子项时仍然会出错:
export function ExampleComponent(props: ComponentProps): ReactElement | null {
...
...
return children; // Type 'ReactNode' is not assignable to type 'ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)> | null) | (new (props: any) => Component<any, any, any>)> | null'.
}
与这里的其他人一样,如果我将其更改为return <>{children}</>;
,它可以工作,但感觉很恶心和不必要。
我有与@kyrstenkelly _exact_ 相同的问题 - 一个 HOC 函数被传递了一个React.FC
,它呈现它的孩子。
<> children(...) </>
修复有效,但还有更好的解决方案吗?
也有这个问题! 目前正在使用 React.Fragment 包装解决方案的建议解决方案
同样在这里
interface IIntlMessageProps {
id: string;
valuesGiven?: {[key:string]:string};
}
// this doesn't work - -- TS2769 Type 'null' is not assignable to type '(nodes:ReactNodeARray) => ReactNode' | ... | undefined
export const IntlMessage: React.FC<IIntlMessageProps> = (props) => {
return (
<FormattedMessage id={props.id} values={props.valuesGiven}>
{props.children}
</FormattedMessage>
)
};
//Nope -- TS2769 Type 'Element' is not assignable to type '(nodes:ReactNodeARray) => ReactNode'
export const IntlMessage: React.FC<IIntlMessageProps> = (props) => {
return (
<FormattedMessage id={props.id} values={props.valuesGiven}>
<React.Fragment>{props.children}</React.Fragment>
</FormattedMessage>
)
};
// Nope -- TS2769 Type 'Element' is not assignable to type '(nodes:ReactNodeARray) => ReactNode'
export const IntlMessage: React.FC<IIntlMessageProps> | null = (props) => {
return (
<FormattedMessage id={props.id} values={props.valuesGiven}>
<>{props.children}</>
</FormattedMessage>
)
};
// Nope -- TS2769 Type '{}' is not assignable to type '(nodes:ReactNodeARray) => ReactNode'
export const IntlMessage: React.FC<IIntlMessageProps> = (props) => {
return (
<FormattedMessage id={props.id} values={props.valuesGiven}>
{props.children ? props.children : undefined}
</FormattedMessage>
)
};
我相信我已经尝试了这里建议的所有内容...... :( 任何线索?
解决方案是您需要将其包装在片段中。
import React from 'react'
const Something: React.FC = ({ children }) => (
<> { children } </>
)
这将修复Type '({ children }: { children?: ReactNode; }) => ReactNode' is not assignable to type 'FunctionComponent
错误。
如果可能的话,我想避免使用碎片,让 JSX 类型系统支持 JavaScript 和 Flow React 支持的相同类型的构造,这有助于 TypeScript 更好地与 3rd 方库模式一起工作。
我发现的另一个不理想是片段加深了组件树,尤其是在实用程序/包装器组件中(案例:react-placeholder)。 在这类库中,转换为React.ReactElement
似乎是一种更好的方法,但我宁愿不需要转换。
我尝试了一种方法来更改该类型,但使用新类型的功能组件进行 JSX 类型检查时卡住了。 我仍然有分支,可以发誓我做了一个 PR 寻求帮助,找不到它......
好的,如果类型需要禁止节点数组,这并不意味着它应该禁止ReactText
、 ReactPortal
、 boolean
、 null
和undefined
以及ReactElement
的用途。
禁止这些额外类型的理由是什么?
最有用的评论
我目前正在将
children
包装在React.Fragment
中以解决此问题。