如何使用 TypeScript 为无状态、功能性 React 组件指定(可选)默认props?

IT技术 javascript reactjs typescript react-native
2021-05-11 07:20:52

我正在尝试使用 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”时什么也没有。

任何帮助是极大的赞赏。

4个回答

这是一个带有答案的类似问题: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;

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

例子:

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

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

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

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;