![](/img/trans.png)
[英]React 15, Typescript 2.2.1. How to cast types for functional/stateless components?
[英]How to specify (optional) default props with TypeScript for stateless, functional React components?
我正在尝试在 Typescript 中创建一个带有可选 props 和 defaultProps 的无状态 React 组件(用于 React Native 项目)。 这对于 vanilla JS 来说是微不足道的,但我对如何在 TypeScript 中实现它感到困惑。
使用以下代码:
import React, { Component } from 'react';
import { Text } from 'react-native';
interface TestProps {
title?: string,
name?: string
}
const defaultProps: TestProps = {
title: 'Mr',
name: 'McGee'
}
const Test = (props = defaultProps) => (
<Text>
{props.title} {props.name}
</Text>
);
export default Test;
调用<Test title="Sir" name="Lancelot" />
会按预期呈现“Sir Lancelot”,但<Test />
应该输出“Mr McGee”时什么结果都没有。
任何帮助是极大的赞赏。
这是一个带有答案的类似问题: React with TypeScript - 在无状态函数中定义 defaultProps
import React, { Component } from 'react';
import { Text } from 'react-native';
interface TestProps {
title?: string,
name?: string
}
const defaultProps: TestProps = {
title: 'Mr',
name: 'McGee'
}
const Test: React.SFC<TestProps> = (props) => (
<Text>
{props.title} {props.name}
</Text>
);
Test.defaultProps = defaultProps;
export default Test;
这是我喜欢这样做的方式:
type TestProps = { foo: Foo } & DefaultProps
type DefaultProps = Partial<typeof defaultProps>
const defaultProps = {
title: 'Mr',
name: 'McGee'
}
const Test = (props: Props) => {
props = {...defaultProps, ...props}
return (
<Text>
{props.title} {props.name}
</Text>
)
}
export default Test
将我的解决方案添加到锅中,我认为它为现有解决方案增加了额外的可读性和优雅度。
假设您有一个MyComponent
组件,其中包含必需和可选的 props。 我们可以将这些必需的和可选的 props 分成两个接口,将它们组合起来作为组件的完整 prop 接口,但只使用可选的一个来设置默认的 props:
import * as React from "react";
// Required props
interface IMyComponentRequiredProps {
title: string;
}
// Optional props
interface IMyComponentOptionalProps {
color: string;
fontSize: number;
}
// Combine required and optional props to build the full prop interface
interface IMyComponentProps
extends IMyComponentRequiredProps,
IMyComponentOptionalProps {}
// Use the optional prop interface to define the default props
const defaultProps: IMyComponentOptionalProps = {
color: "red",
fontSize: 40,
};
// Use the full props within the actual component
const MyComponent = (props: IMyComponentProps) => {
const { title, color, fontSize } = props;
return <h1 style={{ color, fontSize }}>{title}</h1>;
};
// Be sure to set the default props
MyComponent.defaultProps = defaultProps;
export default MyComponent;
我可能是错的,但是在函数上传递一个默认的 prop 值作为第二个投票的回复说可能会导致微妙的错误或过度执行 useEffects(我没有足够的代表来回复那里,所以这里有一个可重复的 codesanbox)
即使它是一个非常人为的例子,并且可能在大多数情况下只是糟糕的组件设计,我已经不止一次看到这种情况,甚至打破了整页。
对于功能组件,确实有可能弃用defaultProps
字段。 我不相信这会很快发生,因为已经用它编写了大量的代码,但是很可能会在控制台中显示警告。
我正在使用下面的解决方案,它提供了正确的行为和正确的 TypeScript 验证。 它适用于混合定义/未定义的属性,也适用于有/没有默认值的属性——也就是说,它涵盖了所有情况:
interface Props {
name: string;
surname?: string;
age?: number;
}
const defaultProps = {
surname: 'Doe',
};
function MyComponent(propsIn: Props) {
const props = {...defaultProps, ...propsIn};
return <div>{props.surname}</div>;
}
VSCode 自动完成功能在:
它已经使用 TypeScript 4.7 进行了测试。
对我来说,这看起来不像是打字稿问题。
免责声明:我只用打字稿试过这个。
然而,问题在于 props总是存在的(即使没有传入任何内容时作为空对象)。 不过,有两种解决方法。
不幸的是,第一个会扼杀您拥有的超级干净的无花括号语法,但让我们保留defaultProps
。
interface TestProps {
title?: string;
name?: string;
}
const defaultProps: TestProps = {
title: 'Mr',
name: 'McGee'
}
const Test = (passedIn: TestProps) => {
const props = Object.assign({}, defaultProps, passedIn);
return (
<p>
{props.title} {props.name}
</p>
);
}
如果您有大量道具,另一种选择可能会有点麻烦,但这可以让您保留原始语法,如下所示:
const Test = (props: TestProps) => (
<Text>
{props.title || 'Mr'} {props.name || 'McGee'}
</Text>
);
希望这有帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.