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

今回は、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;
画面を確認してみます。

はい、できました。