2
1

More than 3 years have passed since last update.

React Bootstrap + TypeScript: Buttonのプロパティを動的に定める

Last updated at Posted at 2020-06-08

React Bootstrapは、Bootstrapのスタイルが適用されたコンポーネントをReactアプリケーションに組み込めるライブラリです。今年3月24日に正規バージョンv1.0.0がリリースされ、4月23日には1.0.1にアップデートされました。Bootstrapのみでは<div>などにやたらとクラスを詰め込んだDOM要素があふれます。それに対して、アプリケーションをReactのコンポーネントですっきりと組み立てられるのが利点です。

ButtonコンポーネントのプロパティをJavaScript形式で定める

山盛りのクラスと<div>の入れ子を書くことなく、設定はタグの属性(プロパティ)で済ませられたりします。Buttonコンポーネントのテキストやカラーテーマ(variant)、大きさ(size)なども、JavaScript形式(jsファイル)のコードでつぎのように動的に定められます(図001)。

src/App.js
import React from 'react';
import { Container, Button } from 'react-bootstrap';

function App() {
    const buttonProps = {
        text: 'Button Text',
        variant: 'success',
        size: 'lg',
    };
    return (
        <div>
            <Container>
                <Button
                    variant={buttonProps.variant}
                    size={buttonProps.size}
                >
                    {buttonProps.text}
                </Button>
            </Container>
        </div>
    );
}

export default App;

図001■ButtonコンポーネントのプロパティをJavaScriptコードで定めた

2006001_02.png

ButtonコンポーネントのプロパティをTypeScript形式で定める

前掲のJavaScriptコードを、TypeScript形式(tsxファイル)にそのままコピーしてみましょう(TypeScript形式のひな形Reactアプリケーションのつくり方については「Create React App + TypeScript: 関数コンポーネントにTypeScriptで型づけする」をお読みください)。たちまち、えらい剣幕で怒られます(図002)。

図002■プロパティの指定が型に合わないというエラーメッセージ

2006001_01.png

プロパティ(variantsize)がとれる値(文字列)は決まっています。そのため、それら特定の文字列が型として定められているからです。使う値を型エイリアスtypeで宣言してしまえばよいでしょう。そのうえで、変数にasを用いて型変換(キャスト)します。

src/App.tsx
type variant = 
    | 'primary'
    | 'secondary'
    | 'success'
    | 'danger'
    | 'warning'
    | 'info'
    | 'dark'
    | 'light'
    | 'link'
    | 'outline-primary'
    | 'outline-secondary'
    | 'outline-success'
    | 'outline-danger'
    | 'outline-warning'
    | 'outline-info'
    | 'outline-dark'
    | 'outline-light'
;
type size = 'sm' | 'lg';
function App() {
    /* ...[中略]... */
    return (
        <div className="App">
            <Container>
                {/* <Button
                    variant={buttonProps.variant}
                    size={buttonProps.size}
                > */}
                <Button
                    variant={buttonProps.variant as variant}
                    size={buttonProps.size as size}
                >
                    {buttonProps.text}
                </Button>
            </Container>
        </div>
    );
}

ButtonPropsインタフェースを使う

エラーメッセージからソースを探ると、ButtonPropsがインタフェースだとわかります。したがって、このインタフェースをimportすれば、型づけできるということです。

ただし、ドットアクセスButtonProps.variantで型を得ることはできません。つぎのような警告が示されるでしょう。型はブラケット参照ButtonProps['variant']で取り出さなければならないのです。

'ButtonProps.variant' にアクセスできません。'ButtonProps' は型で、名前空間ではありません。'ButtonProps["variant"]' で 'ButtonProps' のプロパティ 'variant' の型を取得するつもりでしたか?

インタフェースButtonPropsで型をキャストしたのが、つぎのコードです。サンプルをCodeSandbox「React Boostrap + TypeScript: Dynamically changing Button properties」に公開します。

src/App.tsx
import React from 'react';
import {
    Container,
    Button,
    ButtonProps,
} from 'react-bootstrap';

function App() {
    const buttonProps = {
        text: 'Button Text',
        variant: 'success',
        size: 'lg',
    };
    return (
        <div className="App">
            <Container>
                <Button
                    variant={buttonProps.variant as ButtonProps['variant']}
                    size={buttonProps.size as ButtonProps['size']}
                >
                    {buttonProps.text}
                </Button>
            </Container>
        </div>
    );
}

export default App;
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1