開発環境の構築
Reactアプリの開発環境の構築についてはReactの開発環境を構築するをご覧ください。
ディレクトリ構成
プロジェクトのディレクトリ構成を下記のようにします。「my-app」はプロジェクト名です。
my-app
└── src
├── components
│ └── Button.js
├── App.css
├── App.js
├── index.css
└── index.js
styled-componentsのインストール
ターミナルで以下のコマンドを実行してstyled-componentsをインストールします。
yarn add styled-components
Buttonコンポーネントを作成する
Reactでは、コンポーネントと呼ばれる部品を組み合わせてUIを構築します。
コンポーネントはpropsと呼ばれるパラメータを受け取り、表示するビューの階層構造を返します。
ということで、src/components配下に以下のコンポーネントを作成します。
Button
ボタン要素を返すButtonコンポーネントをstyled-componentsで作成します。
components/Button.js
import React from 'react'
import styled from 'styled-components'
const Button = styled.button`
background-color: ${({ theme }) => (theme && theme.background) || "lightgray"};
border: none;
border-radius: 0.6vmin;
cursor: ${({ isDisabled }) => (isDisabled ? "cursor" : "pointer")};
color: ${({ theme }) => (theme && theme.color) || "#333333"};
font-size: ${({ size }) => (size && size.fontSize) || "1em"};
outline: none;
opacity: ${({ isDisabled }) => (isDisabled ? 0.5 : 1)};
padding: ${({ size }) => (size && size.fontSize) || "1em 2em"};
pointer-events: ${({ isDisabled }) => (isDisabled ? "none" : "auto")};
user-select: none;
`;
export default Button
このコンポーネントはpropsとして4つの値(theme、size、isDisabled、onClick)を受け取ります。
4つの値については次の通りです。
theme
backgroundとcolorのプロパティを持つオブジェクトであり、値はいずれもカラーコードまたはカラー名を文字列で指定します。
<Button
theme={{
background: '#aaaaaa',
color: 'white'
}}
>
受け取った値は、以下のようにしてcssのbackground-colorプロパティとcolorプロパティにセットされ、これによりボタンのテーマが設定されます。
background-color: ${({ theme }) => (theme && theme.background) || BUTTON_THEMES.default.background};
color: ${({ theme }) => (theme && theme.color) || BUTTON_THEMES.default.color};
尚、themeを受け取らなかった場合は、それぞれデフォルトのカラーが設定されます。
size
fontSizeとpaddingのプロパティを持つオブジェクトであり、fontSizeプロパティにはフォントサイズを、paddingプロパティには上下左右のパディングをいずれも文字列で以下のように指定します。
<Button
size={{
fontSize: '1em',
padding: '10px 20px'
}}
>
受け取った値は、以下のようにしてcssのfont-sizeプロパティとpaddingプロパティにセットされ、これによりボタンのテーマが設定されます。
font-size: ${({ size }) => (size && size.fontSize) || BUTTON_SIZES.md.fontSize};
padding: ${({ size }) => (size && size.fontSize) || BUTTON_SIZES.md.padding};
尚、themeを受け取らなかった場合は、それぞれデフォルトのフォントサイズとパディングが設定されます。
isDisabled
ボタンのクリックが有効または無効の状態を示す真偽値であり、falseであればボタンのクリックが有効になり、trueであれば無効になります。
受け取った値は、以下のようにしてcssのcursor、opacity、pointer-eventsプロパティの値が設定される際の条件式で使われます。
cursor: ${({ isDisabled }) => (isDisabled ? "cursor" : "pointer")};
opacity: ${({ isDisabled }) => (isDisabled ? 0.5 : 1)};
pointer-events: ${({ isDisabled }) => (isDisabled ? "none" : "auto")};
isDisabledがtrueであればcssは
cursor: default;
opacity: .5;
pointer-events: none;
となり、ボタンのクリックは無効になります。
反対にfalseであればcssは、
cursor: pointer;
opacity: 1;
pointer-events: auto;
となり、ボタンのクリックが有効になります。
onClick
クリックされたときに実行する関数であり、関数名か無名関数で以下のように指定します。
// 関数名の場合
<Button
onClick={handleClick}
>
// 無名関数の場合
<Button
onClick={() => handleClick()}
>
受け取った値はbutton要素のonclick属性に設定されます。
Buttonコンポーネントの使いかた
Buttonコンポーネントは以下のようにして使用します。以下の例ではButtonコンポーネントはCount upボタンとして使われています。
App.js
import React from 'react'
import './App.css'
import Button from './components/Button'
const App = () => {
const [count, setCount] = useState(0);
const countUp = useCallback(() => setCount((p) => p + 1), []);
const buttonTheme = {
background: "orange",
color: "#ffffff"
};
const style = {
display: "flex",
flexDirection: "column",
alignItems: "center",
height: "100vh",
justifyContent: "center"
};
return (
<div style={style}>
<div>count: {count}</div>
<Button onClick={countUp} theme={buttonTheme}>
Count up
</Button>
</div>
);
};
export default App
App.jsを上書きするとブラウザがリロードされてCount upボタンと現在のカウント数が表示されます。Count upボタンをクリックすると現在のカウント数が1ずつカウントアップされます。
Demo
下記で実際の動作を確認できます。