如何使用TypeScript为无状态的,功能齐全的React组件指定(可选)默认道具?

Mat*_*tow 16 javascript typescript reactjs react-native

我正在尝试在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;
Run Code Online (Sandbox Code Playgroud)

调用<Test title="Sir" name="Lancelot" />"Lancelot爵士"按预期呈现,但<Test />什么都没有,什么时候输出"Mr McGee".

任何帮助是极大的赞赏.

kDa*_*Dar 54

我发现最简单的方法是使用可选参数。请注意, defaultProps 最终将在功能组件上弃用

例子:

interface TestProps {
    title?: string;
    name?: string;
}

const Test = ({title = 'Mr', name = 'McGee'}: TestProps) => {
    return (
        <p>
            {title} {name}
        </p>
    );
}
Run Code Online (Sandbox Code Playgroud)


Mat*_*tow 37

这是一个类似的问题,答案是:与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;
Run Code Online (Sandbox Code Playgroud)

  • 这是正确答案。最近,SFC 被弃用,转而支持 FunctionComponent: const Test: React.FunctionComponent&lt;TestProps&gt; = ... (4认同)
  • 如果属性类似于“names?: string[]”怎么办?即使我给出这样的默认值,从打字稿的角度来看它仍然是可选的,所以我必须编写 `props.names?.join(',')` 而不是 `props.names.join(',')` (3认同)
  • 仅当所有道具都是可选的时才有效 (3认同)
  • 您还可以在打字稿中使用 React.FC,而不是 React.FunctionComponent (2认同)

Bar*_*azu 7

这是我喜欢这样做的方式:

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
Run Code Online (Sandbox Code Playgroud)

  • 这是拼写错误吗?“(props: Props)”不是应该说“(props: TestProps)”吗? (3认同)
  • 看起来很棒,你能解释一下第一行吗? (2认同)
  • 当道具是必需和非必需道具的混合时,这是唯一有效的正确答案。所有其他解决方案都涉及仅具有可选道具的组件。 (2认同)

Rod*_*igo 6

2022 年更新

\n

对于函数组件来说,确实存在可能弃用field的情况defaultProps。我不相信这种情况会这么快发生,因为已经用它编写了大量代码,但控制台中很可能会显示警告。

\n

我正在使用下面的解决方案,它提供了正确的行为和适当的 TypeScript 验证。它适用于混合定义/未定义的属性,也适用于具有/不具有默认值 \xe2\x80\x93 的属性,也就是说,它涵盖了所有情况:

\n
interface Props {\n  name: string;\n  surname?: string;\n  age?: number;\n}\n\nconst defaultProps = {\n  surname: \'Doe\',\n};\n\nfunction MyComponent(propsIn: Props) {\n  const props = {...defaultProps, ...propsIn};\n\n  return <div>{props.surname}</div>;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

VSCode 自动完成功能非常出色:

\n

VSCode 自动完成

\n

它已经使用 TypeScript 4.7 进行了测试。

\n