【第6回】3カラムレイアウトとタブ切り替えを実装

おけまるの投資開発室

今回は、いよいよ株アプリの画面作成に入りました。

これまでは、

・どんなアプリを作るのか
・どんな機能が必要なのか
・どんなデータを持つのか
・データがどう流れるのか

といった設計を中心に進めてきました。

今回から、実際にNext.js / Reactを使って画面を作っていきます。

今回実装したのは、大きく2つ。

「3カラムレイアウト」と「タブ切り替え」です。

動画はこちらです。

 


今回使用したスライド資料

動画内で使用したスライド資料はこちらです。

【第6回】おけまるの投資開発室

※今回の実装内容やコードの考え方をスライド形式でまとめています。


今回実装したもの

今回は、

検索条件|銘柄一覧|銘柄詳細

という3つのエリアを持つ画面を作りました。

さらに、銘柄詳細の中では、

割安性|財務安定性|成長性|株主還元性|ストーリー

をタブで切り替えられるようにしています。

最終的な完成イメージはこんな感じです。
(まだここまでできているわけではありません。)

株アプリ完成イメージ

※画像をクリックすると大きく表示できます。

PDFでも今回の実装内容として 「Next.jsで3カラム画面」 「タブ切り替えを作成」 と整理しています。


CSS Gridで3カラムレイアウトを作る

まず、画面を3つのエリアに分けます。

検索・銘柄一覧・詳細の3カラムレイアウト

※画像をクリックすると大きく表示できます。

今回使っているのがCSS Gridです。

.mainLayout {
  display: grid;
  grid-template-columns: 280px 1fr 520px;
  gap: 12px;
}

それぞれ、

280px
→ 検索条件

1fr
→ 銘柄一覧

520px
→ 銘柄詳細

という構成です。

1frは、固定幅を使ったあとに残ったスペースを利用します。

つまり、

280px + 余った幅 + 520px

という形になります。

数字を実際に変更してみると画面の幅も変わるので、

「このCSSが画面のどこに影響しているのか」

がかなり分かりやすくなりました。


コンポーネントを分ける

今回の画面では、大きく、

  • SearchPanel → ①検索
  • StockList → ②銘柄一覧
  • StockDetail → ③詳細

にコンポーネントを分けています。

さらにStockDetail(③詳細)の中には、

  • ValueTab.tsx → 割安性
  • StabilityTab.tsx → 財務安定性
  • GrowthTab.tsx → 成長性
  • ShareholderReturnTab.tsx → 株主還元性
  • StoryTab.tsx → ストーリー

という、それぞれのタブを担当するコンポーネントがあります。

コンポーネント構成

※画像をクリックすると大きく表示できます。

個人的には、

コンポーネント=画面を作るための部品

くらいに考えると分かりやすかったです。


page.tsxは各部品を配置する役割

それぞれのコンポーネントを作っただけでは、画面には並びません。

そこでpage.tsxから、

SearchPanel
StockList
StockDetail

を呼び出して配置しています。

page.tsxからコンポーネントを配置

※画像をクリックすると大きく表示できます。

今回の構成では、

page.tsx → 各部品の配置

StockDetail.tsx → タブの状態管理

各Tab → それぞれの内容

という役割分担になっています。

PDFでもこの役割分担を図にしています。


配列とmap()を使ってタブを作る

タブを5個、一つひとつ書くのではなく、 まずタブの情報を配列にしています。

const tabs = [
  { id: "value", label: "割安性" },
  { id: "stability", label: "財務安定性" },
  { id: "growth", label: "成長性" },
  { id: "shareholderReturn", label: "株主還元性" },
  { id: "story", label: "ストーリー" },
];

そして、map()を使って配列からボタンを作ります。

{tabs.map((tab) => (
  <button key={tab.id}>
    {tab.label}
  </button>
))}

mapを使ったタブ作成

※画像をクリックすると大きく表示できます。

流れとしては、

配列を作る

map()で1件ずつ取り出す

ボタンに変換する

という感じです。

以前map()を勉強したときよりも、 実際にアプリの画面を作りながら使ったことで、 かなりイメージしやすくなりました。


useStateで選択中のタブを管理する

次はタブの切り替えです。

Reactには、

「今どのタブが選ばれているのか」

を覚えてもらう必要があります。

そこで使うのがuseStateです。

const [activeTab, setActiveTab]
  = useState<TabName>("value");

今回はactiveTabに、 現在選択されているタブを保存しています。

そしてタブをクリックしたときに、

onClick={() => setActiveTab(tab.id)}

を実行します。

するとactiveTabの値がクリックしたタブに変わります。

useStateを使ったタブ切り替え

※画像をクリックすると大きく表示できます。

例えば「成長性」をクリックすると、

タブをクリック

setActiveTabを実行

activeTabがgrowthになる

GrowthTabを表示

という流れになります。

今回の開発で、

useState=画面上で変化する状態を覚えておくもの

というイメージが少し分かってきました。


選択中のタブだけCSSを変更する

さらに、

「今どのタブが選択されているのか」

を見た目でも分かるようにしています。

className={
  activeTab === tab.id
    ? styles.activeTab
    : ""
}

activeTabとタブのIDが同じなら、 activeTabというCSSクラスを付けます。

CSS側では、

.tabs button.activeTab {
  color: #ffffff;
  background-color: #2563d9;
}

としています。

選択中のタブのCSS

※画像をクリックすると大きく表示できます。

つまり、

選択されているタブ
→ 青背景+白文字

選択されていないタブ
→ 通常表示

となります。

動画では実際にCSSの色を変更して、 表示が変わることも確認しました。


今回学んだこと

今回学んだのは、

・コンポーネントの役割分担
・CSS Gridによる3カラムレイアウト
・配列のmap()を使ったボタン作成
・useStateを使ったアクティブタブの状態管理
・クリックイベントによる内容とレイアウト(色)の切り替え

です。

これは今回のスライドでも最後にまとめています。

ReactやNext.jsを単体で勉強しているときは、

「これ何に使うんだろう?」

と思うこともありました。

でも実際にアプリを作ってみると、

「ここでuseStateを使うのか」

「こういう場面でmap()が便利なのか」

と、少しずつ知識がつながってきました。

コメント

タイトルとURLをコピーしました