ミライトデザイン Advent Calendar 2024 16日目の記事になります。
15日目は takuma さんの 「DynamoDB 全くわからないのでまとめてみた」の記事でした。
私も DynamoDB 全くわからない勢ですが、
RDBと比べて設計の考え方が全然違うんだなと感じました。
とても参考になりました!
はじめに
現在、私は React を使用したプロジェクトに携わっています。
2024年も残りわずかとなり、今年お世話になったライブラリを振り返ってみることにしました。
目的
プロジェクトでは、自分以外のメンバーが導入したライブラリも多くあります。
そのため、これらのライブラリについて調べ、実際に試してみて、使い方をざっくり理解したいと考えています。
今回は、その中で紹介しやすかったり、便利だと思った5つのライブラリを紹介します。
ライブラリ紹介について
以下の構成で説明を進めます。
- 実現したいこと
- ライブラリ名
- ライブラリ概要
実現したいこと: UI コンポーネントを効率的に構築したい
ライブラリ名: Chakra UI
ライブラリ概要
Chakra UIとは、React ベースの UI コンポーネントライブラリの一つで、
開発者が簡単かつ効率的にモダンな UI を構築できるよう設計されています。
特に、スタイルとテーマのカスタマイズが容易なため、デザインの一貫性を保ちながら柔軟な対応が可能です。
例として以下のようなデザインを作成してみます。
実装例
const Component = () => {
return (
<Box
maxW="sm"
borderWidth="1px"
borderRadius="lg"
overflow="hidden"
p={6}
bg="white"
boxShadow="md"
>
<Image src="./images/cat1.jpeg" alt="Sample Image" />
<Box mt={4} textAlign="center">
<Text fontWeight="bold" fontSize="xl">
サンプルカード
</Text>
<Text mt={2} color="gray.600">
Chakra UI を使って簡単なレイアウトを作成してみる。
</Text>
<HStack spacing={8} justifyContent="center" p={4} mt={4}>
<VStack spacing={2} align="center">
<Text fontWeight="bold" fontSize="md" color="teal.500">
サンプル1
</Text>
<Text fontSize="sm" color="gray.600">
説明テキスト1
</Text>
</VStack>
<VStack spacing={2} align="center">
<Text fontWeight="bold" fontSize="md" color="teal.500">
サンプル2
</Text>
<Text fontSize="sm" color="gray.600">
説明テキスト2
</Text>
</VStack>
</HStack>
<Button colorScheme="teal" mt={6} leftIcon={<FaCat />}>
ボタン
</Button>
</Box>
</Box>
);
};
いくつか特徴を挙げます
- 豊富なコンポーネント
- ボタン、入力フィールド、モーダル、カードなど、日常的によく使用される基本コンポーネントが多数用意されています
- レイアウトの容易さ
- クラス名を考える必要がなく、レイアウト用のコンポーネント(例:
HStack
,VStack
)を使えば簡単に配置ができます
- クラス名を考える必要がなく、レイアウト用のコンポーネント(例:
- スタイルのショートハンド
-
p={6}
,mt={4}
などの簡潔なスタイル指定が可能です
-
- カスタムテーマ機能
- デフォルトのテーマをベースに、独自の色やフォントを簡単に設定できます
- ブランドカラーやフォントサイズなどを指定したり、コンポーネントのスタイルを上書きすることが可能です
- 参考記事はこちら
※React の UI コンポーネントライブラリは、Chakra UI の他にも Material-UI, React Bootstrap など多く存在しますが、今回は Chakra UI に限定して紹介しました。
実現したいこと: 棒(円)グラフを描きたい
ライブラリ名: recharts
ライブラリ概要
データの視覚化に便利なライブラリです。
例えば、以下のような「男女の年代比率」や「家計簿管理での収支のカテゴリ比率」を簡単に表示できます。
実装例:年代比率の棒グラフ
const data = [
{ name: "〜20代", value: 10 },
{ name: "30代", value: 40 },
{ name: "40代", value: 30 },
{ name: "50代〜", value: 5 },
];
const Component = () => {
return (
<Box p={4} boxShadow="md" mt={6}>
<Heading as={"h3"} className="chart-heading" fontSize={"lg"} mb={3}>
年代比率
</Heading>
<ResponsiveContainer width="100%" height={200}>
{/* 棒グラフを表示するコンポーネント */}
<BarChart data={data}>
{/* グラフ背景の線を表示するグリッド */}
<CartesianGrid strokeDasharray="3 3" />
<XAxis tickLine={false} dataKey="name" />
<YAxis
tickLine={false}
type="number"
tickFormatter={(value) => `${value}%`}
/>
{/* 実際のデータを棒グラフとして描画 */}
<Bar dataKey="value" fill="#DF6160" barSize={30} />
</BarChart>
</ResponsiveContainer>
</Box>
);
};
必要なデータがあれば、棒グラフ (BarChart) を簡単に作成できます。
また、棒グラフだけでなく、円グラフなら PieChart
コンポーネントを使用できます。
実現したいこと: 画像一覧から写真を選択・拡大表示し、次の写真に移動させたい
ライブラリ名: yet-another-react-lightbox
ライブラリ概要
写真の拡大表示に加え、次の写真への移動が必要なため適したライブラリを検討しました。
候補はlightbox-react
とyet-another-react-lightbox
の2つでしたが、ダウンロード数と更新頻度の比較から後者を選択しました。
機能説明
- 画像をクリックすると、モーダルとして拡大表示されます
- モーダル内では矢印ボタンで次の画像に移動可能
- 閉じるボタンで元の画面に戻ります
※公式サンプルでは、ボタンでモーダルを開く例の記述がありましたが、
この記事では画像クリックでモーダルを開くように実装しています。
実装例
// 表示する画像の配列
const images = [
"cat1.jpeg",
"cat2.jpeg",
"cat3.jpeg",
"cat4.jpeg",
"cat5.jpeg",
"cat6.jpeg",
];
const Component = () => {
const [isOpen, setIsOpen] = useState(false); // Lightboxの表示状態
const [currentIndex, setCurrentIndex] = useState(0); // 現在表示している画像のインデックス
// 画像クリック時の処理
const handleClick = (index) => {
setCurrentIndex(index);
setIsOpen(true);
};
return (
<Box p={4} mt={50} mb={150}>
{/* 画像一覧のグリッド表示 */}
<SimpleGrid columns={2} spacing={4}>
{images.map((src, index) => (
<Image
key={index}
src={`./images/${src}`}
alt={`image-${index}`}
cursor="pointer"
onClick={() => handleClick(index)}
borderRadius="md"
boxShadow="md"
/>
))}
</SimpleGrid>
{/* Lightbox モーダル */}
<Lightbox
open={isOpen} // モーダルの開閉状態
index={currentIndex} // 現在表示している画像インデックス
close={() => setIsOpen(false)}
slides={images.map((image) => ({
src: `./images/${image}`,
alt: "image",
}))}
/>
</Box>
);
};
実現したいこと: 画面のスクロールに応じた要素の表示制御
ライブラリ名: react-intersection-observer
ライブラリ概要
フォーム登録ページでは、「登録ボタン」を固定フッターとして画面下部に表示していました。
しかし、ページの最下部までスクロールすると、最下部の要素が登録ボタンに隠れてしまう問題が発生。
そこで、画面のスクロール位置に応じて、最下部の登録ボタンが表示されたタイミングで固定フッターの登録ボタンを非表示にするよう調整しました。
機能説明
- 最初は固定フッターの「登録ボタン1」が表示されています
- 画面下部の「登録ボタン2」が表示されたタイミングで固定フッター(登録ボタン1)が非表示になり、下部の要素が隠れないようになります
実際例:コード
const Component = ({ className }) => {
// ref: 監視対象の要素参照
// inView: 監視対象が画面内に入っているかどうかの判定フラグ
const [ref, inView] = useInView({
threshold: 0.1, // 要素の10%以上が表示されたときに検知
});
return (
<div className={className}>
<div className="content">
<div className="section">セクション 1</div>
<div className="section">セクション 2</div>
<div className="section">セクション 3</div>
<div className="section">セクション 4</div>
{/* 監視されているボタン */}
{/* refを与えた要素がウインドウ内に現れるとinViewがtrueになる */}
{!inView && <div className="fixed-button">固定の登録ボタン</div>}
{/* 監視対象のボタン */}
<button ref={ref} className="button">
登録
</button>
<div className="section">フッター</div>
</div>
</div>
);
};
実現したいこと: 画像をカルーセル表示したい
ライブラリ名: embla-carousel-react
ライブラリ概要
画像をカルーセル形式で表示するために使用したライブラリです。
カルーセルは、限られたスペースで多くの画像を見せたい場合などに有効ですね。
ユーザーはボタンや画像のサムネイルをクリックすることで、
スライドを切り替えることができます。
また、画像の枚数を(2/10など)表示したり、自動で画像が切り替わるような設定も可能です。
実際のコード例(スタイルは省略)
// 表示する画像リスト
const images = [
"cat1.jpeg",
"cat2.jpeg",
"cat3.jpeg",
"cat4.jpeg",
"cat5.jpeg",
"cat6.jpeg",
];
const Component = ({ className }) => {
// emblaRef: スライダーの DOM 要素に関連付ける参照 (ref)。
// emblaApi: スライダー操作用の API オブジェクト。スライドの移動、状態管理に使用する
const [emblaRef, emblaApi] = useEmblaCarousel({ loop: true }); // スライダーの無限ループを有効にする
// 前のスライドへ移動
const onPrevButtonClick = useCallback(() => {
if (!emblaApi) return;
emblaApi.scrollPrev();
}, [emblaApi]);
// 次のスライドへ移動
const onNextButtonClick = useCallback(() => {
if (!emblaApi) return;
emblaApi.scrollNext();
}, [emblaApi]);
return (
<div className={className}>
<div className="slider">Slider</div>
{/* スライダー本体 */}
<div className="embla" ref={emblaRef} style={{ overflow: "hidden" }}>
<div className="embla__container" style={{ display: "flex" }}>
{images.map((src, index) => (
<div
className="embla__slide"
key={index}
style={{ flex: "0 0 100%" }}
>
<img
src={`./images/${src}`}
alt={`Slide ${index + 1}`}
style={{ width: "100%", height: "auto" }}
/>
</div>
))}
</div>
</div>
{/* スライド操作ボタン */}
<div className="embla__controls">
<div className="embla__buttons">
<button onClick={onPrevButtonClick}>Prev</button>
<button onClick={onNextButtonClick}>Next</button>
</div>
</div>
</div>
);
};
さいごに
この記事では5つの React ライブラリを紹介しました。
本当はもっと多くのライブラリを紹介する予定だったのですが、
調べたり整理するのに予想以上に時間がかかってしまい、紹介しきれませんでした。
また機会があれば、別の記事で他のライブラリも紹介したいと思います。
この記事がきっかけで、新たに使い始めるライブラリが見つかれば嬉しいです!
明日は、yuki さんの記事です。
よろしくお願いします!
参考