1. ホーム
  2. reactjs

[解決済み] TypeScriptを使ったReactコンポーネントのデフォルトプロパティ値

2022-04-15 07:34:37

質問

Typescript を使用して、自分のコンポーネントにデフォルトのプロパティ値を設定する方法がわかりません。

これはソースコードです。

class PageState
{
}

export class PageProps
{
    foo: string = "bar";
}

export class PageComponent extends React.Component<PageProps, PageState>
{
    public render(): JSX.Element
    {
        return (
            <span>Hello, world</span>
        );
    }
}

そして、このようにコンポーネントを使おうとすると。

ReactDOM.render(<PageComponent />, document.getElementById("page"));

プロパティというエラーが発生します。 foo が見つかりません。デフォルト値を使いたいのですが。また static defaultProps = ... をコンポーネント内で使用していますが、思ったような効果はありませんでした。

src/typescript/main.tsx(8,17): error TS2324: Property 'foo' is missing in type 'IntrinsicAttributes & IntrinsicClassAttributes<PageComponent> & PageProps & { children?: ReactEle...'.

デフォルトのプロパティ値を使用するにはどうしたらよいですか?私の会社が使っている多くのJSコンポーネントは、それらに依存しており、それらを使用しないことは選択肢にありません。

どのように解決するのですか?

クラスコンポーネントによるデフォルトのプロップス

使用方法 static defaultProps が正しいです。また、propsとstateにはクラスではなく、インターフェイスを使用する必要があります。

2018/12/1更新 : TypeScript では、以下の項目に関する型チェックが改善されました。 defaultProps を使用します。最新の使い方から、古い使い方、問題点まで、お読みください。

TypeScript 3.0以降用

TypeScriptに特化 をサポートしました。 defaultProps を追加し、タイプチェックが期待通りに動作するようにしました。例

interface PageProps {
  foo: string;
  bar: string;
}

export class PageComponent extends React.Component<PageProps, {}> {
    public static defaultProps = {
        foo: "default"
    };

    public render(): JSX.Element {
        return (
            <span>Hello, { this.props.foo.toUpperCase() }</span>
        );
    }
}

を渡さずにレンダリング、コンパイルすることができます。 foo 属性があります。

<PageComponent bar={ "hello" } />

注意してください。

  • foo ではない は、オプションとしてマークされています(つまり foo?: string JSX属性として要求されていないにもかかわらず、です。オプションとしてマークすることは、それが undefined になることはありませんが、実際には undefined なぜなら defaultProps はデフォルト値を提供します。同じように考えてください。 関数のパラメータをオプションでマークするか、デフォルト値でマークするかは自由ですが、両方はできません。 . TypeScript 3.0+のお菓子 defaultProps も同じような方法で、React ユーザーにとってはとてもクールなものです。
  • その defaultProps には明示的な型アノテーションがありません。その型は推論され、コンパイラがどのJSX属性が必要かを決定するために使用されます。あなたは defaultProps: Pick<PageProps, "foo"> を確実にするために defaultProps のサブセットにマッチします。 PageProps . この注意点についての詳細は 詳細はこちら .
  • これには @types/react バージョン 16.4.11 が正常に動作することを確認します。

TypeScript 2.1~3.0用

TypeScript 3.0にコンパイラサポートが実装される以前は defaultProps しかし、TypeScriptはJSXの属性をチェックするときにpropsを考慮するので、デフォルトを持つpropsをオプションとして ? . 例

interface PageProps {
    foo?: string;
    bar: number;
}

export class PageComponent extends React.Component<PageProps, {}> {
    public static defaultProps: Partial<PageProps> = {
        foo: "default"
    };

    public render(): JSX.Element {
        return (
            <span>Hello, world</span>
        );
    }
}

注意してください。

  • という注釈をつけるとよいでしょう。 defaultPropsPartial<> を使用すると、プロップに対して型チェックを行いますが、すべての必須プロパティにデフォルト値を提供する必要はありません。
  • を使用する場合 strictNullChecks の値は this.props.foo になります。 possibly undefined で、NULLでないアサーションが必要です(つまり this.props.foo! ) またはタイプガード (すなわち if (this.props.foo) ... を削除してください。 undefined . propのデフォルト値は、実際には決して未定義にならないことを意味するので、これは迷惑な話ですが、TSはこのフローを理解していませんでした。これが、TS 3.0が明示的に defaultProps .

TypeScript 2.1以前

これは同じように動作しますが Partial を省略することができます。 Partial<> で、必要なすべてのプロップにデフォルト値を与えるか(たとえそのデフォルト値が使われることはないとしても)、明示的な型アノテーションを完全に省略します。

によるデフォルトプロップス 機能的な構成要素

を使用することができます。 defaultProps は関数コンポーネントにも使えますが、関数を FunctionComponent ( StatelessComponent@types/react バージョンアップ前 16.7.2 ) インターフェイスを使用することで、TypeScript が defaultProps を関数に追加します。

interface PageProps {
  foo?: string;
  bar: number;
}

const PageComponent: FunctionComponent<PageProps> = (props) => {
  return (
    <span>Hello, {props.foo}, {props.bar}</span>
  );
};

PageComponent.defaultProps = {
  foo: "default"
};

を使う必要がないことに注意してください。 Partial<PageProps> というのは FunctionComponent.defaultProps は、TS 2.1+で既にパーシャルとして指定されている。

もう一つの良い方法(私が使っているのはこれです)は props パラメータに直接デフォルト値を割り当てています。

const PageComponent: FunctionComponent<PageProps> = ({foo = "default", bar}) => {
  return (
    <span>Hello, {foo}, {bar}</span>
  );
};

そうすると defaultProps を全く使わないでください。注意すべきは、もし する 提供する defaultProps を関数コンポーネントに渡すと、デフォルトのパラメータ値よりも優先されます。 defaultProps の値が使用されることはありません(したがって、パラメータが未定義になることはなく、したがって、デフォルトパラメータが使用されることはありません)。つまり、両方ではなく、どちらかを使うことになる。