今回は、いよいよ株アプリの画面作成に入りました。
これまでは、
・どんなアプリを作るのか
・どんな機能が必要なのか
・どんなデータを持つのか
・データがどう流れるのか
といった設計を中心に進めてきました。
今回から、実際にNext.js / Reactを使って画面を作っていきます。
今回実装したのは、大きく2つ。
「3カラムレイアウト」と「タブ切り替え」です。
動画はこちらです。
今回使用したスライド資料
動画内で使用したスライド資料はこちらです。
※今回の実装内容やコードの考え方をスライド形式でまとめています。
今回実装したもの
今回は、
検索条件|銘柄一覧|銘柄詳細
という3つのエリアを持つ画面を作りました。
さらに、銘柄詳細の中では、
割安性|財務安定性|成長性|株主還元性|ストーリー
をタブで切り替えられるようにしています。
最終的な完成イメージはこんな感じです。
(まだここまでできているわけではありません。)
※画像をクリックすると大きく表示できます。
PDFでも今回の実装内容として 「Next.jsで3カラム画面」 「タブ切り替えを作成」 と整理しています。
CSS Gridで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 → 各部品の配置
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()で1件ずつ取り出す
↓
ボタンに変換する
という感じです。
以前map()を勉強したときよりも、 実際にアプリの画面を作りながら使ったことで、 かなりイメージしやすくなりました。
useStateで選択中のタブを管理する
次はタブの切り替えです。
Reactには、
「今どのタブが選ばれているのか」
を覚えてもらう必要があります。
そこで使うのがuseStateです。
const [activeTab, setActiveTab]
= useState<TabName>("value");
今回はactiveTabに、 現在選択されているタブを保存しています。
そしてタブをクリックしたときに、
onClick={() => setActiveTab(tab.id)}
を実行します。
するとactiveTabの値がクリックしたタブに変わります。
※画像をクリックすると大きく表示できます。
例えば「成長性」をクリックすると、
タブをクリック
↓
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 Gridによる3カラムレイアウト
・配列のmap()を使ったボタン作成
・useStateを使ったアクティブタブの状態管理
・クリックイベントによる内容とレイアウト(色)の切り替え
です。
これは今回のスライドでも最後にまとめています。
ReactやNext.jsを単体で勉強しているときは、
「これ何に使うんだろう?」
と思うこともありました。
でも実際にアプリを作ってみると、
「ここでuseStateを使うのか」
「こういう場面でmap()が便利なのか」
と、少しずつ知識がつながってきました。

コメント