[React Bootstrap] Buttons を表示してみる | 心を無にして始める React

2022-08-30

今回は、Button コンポーネントを表示します。

Button コンポーネントは、通常のボタンがカスタムデザインされたものです。フォームやダイアログなどのユーザのアクションに利用できます。

準備

まだ components フォルダがなければ作ります。

src を右クリックして New Folder

components と入力してフォルダを作ります。

今回は、components フォルダに Button のコンポーネントを作って、表示してみます。

公式のドキュメントはここ。

https://react-bootstrap.github.io/components/buttons/

Button コンポーネントをつくる

component フォルダに Button.js を作ります。

Button.js を心を無にして編集してみます。

import React from 'react';
import { Button as BootstrapButton } from 'react-bootstrap';

function Button(props) {
  const {
    children,
    ...otherProps
  } = props;

  return (
    <BootstrapButton {...otherProps}>
      {children}
    </BootstrapButton>
  )
}

export default Button;

プロジェクトでは、コンポーネントを統一したデザインで利用することが多いです。

そのため、(React Bootstrap のコンポーネントをその場その場でカスタマイズしながら使うよりも、)プロジェクトでコンポーネントにしたものを使うほうが、変更をお手軽に漏れなくできることが多いです。

Button コンポーネントを表示する

それでは、 App.js を編集して Button コンポーネントを表示します。

import './App.css';
import Button from './components/Button';

function App() {
  return (
    <div className="m-5">
      <div className="m-2">
        <Button variant="primary">Button</Button>
      </div>
      <div className="m-2">
        <Button variant="outline-primary">Outline Button</Button>
      </div>
    </div>
  );
}

export default App;

画面を確認してみます。

はい、できました。

ボタンを押したあと、処理中はぐるぐるさせる

Button.js を編集して機能を増やします。

import React, { useEffect, useState } from 'react';
import {
   Button as BootstrapButton,
   Spinner,
} from 'react-bootstrap';

function Button(props) {
  const {
    children,
    onClick,
    ...otherProps
  } = props;

  const [isLoading, setLoading] = useState(false);

  const handleClick = () => {
    if (onClick) {
      setLoading(true);
    }
  }

  const cb = () => {
    setLoading(false);
  }

  useEffect(() => {
    if (isLoading) {
      onClick(cb);
    }
  }, [isLoading]); // eslint-disable-line react-hooks/exhaustive-deps

  return (
    <BootstrapButton
      onClick={handleClick}
      {...otherProps}
      disabled={isLoading}
    >
      {isLoading ? <Spinner animation="border" size="sm" /> : children}
    </BootstrapButton>
  )
}

export default Button;

App.js に1秒の時間がかかる処理をかいて、実験します。

import './App.css';
import Button from './components/Button';

function App() {
  return (
    <div className="m-5">
      <div className="m-2">
        <Button
          variant="primary"
          onClick={(cb) => setTimeout(() => cb(), 1000)}
        >
          Button
        </Button>
      </div>
      <div className="m-2">
        <Button
          variant="outline-primary"
          onClick={(cb) => setTimeout(() => cb(), 1000)}
        >
          Outline Button
        </Button>
      </div>
    </div>
  );
}

export default App;

画面を確認してみます。

はい、できました。