この記事はプログラミング学習者がアプリ開発中に躓いた内容を備忘録として記事におこしたものです。内容に不備などあればご指摘頂けると助かります。
0.前提条件
X(旧Twitter)のクローンサイトの制作過程で投稿ページを実装している際に実装した内容をご紹介したいと思います。
1.記事作成の経緯
以前、Ruby on Railsのみを使ってX(旧Twitter)のクローンサイトを作ったのですが、当時はBootstrapやHTMLを駆使して実装しました。
その後にフロントエンド(JavaScriptやReact)を使用するようになったので、別の方法で実装したタブ切り替えの方法をご紹介したいと思います。
以下は前回投稿した記事です。
HTML, Bootstrapを使ったタブの切り替え機能の実装
2.実装概要
- タブの管理をstate変数で行う
- &&を使って条件付きレンダーを実装
- 親コンポーネントで定義したタブの切り替えを管理するstate関数をpropsで子コンポーネントに渡して、onClickイベントでイベントハンドラとして使う
3.実装内容
import React, { useState } from "react";
import styled from "styled-components";
import { TweetTabs } from "../molecules/TweetTabs";
import { RecommendationComponent } from "./RecommendationComponent";
import { FollowComponent } from "./FollowComponent";
import { TweetInput } from "./TweetInput";
import { PostModal } from "./PostModal";
const TweetBox = styled.div`
width: 35%;
color: white;
`;
export const TweetView = ({ showPostModal, closePostModalHandler }) => {
// タブの切り替えを管理するstate変数
const [activeTab, setActiveTab] = useState("recommendation");
// 引数のtabにrecommendation、もしくはfollowを入れることでstate関数によりタブを切り替える
const handleTabClick = (tab) => {
setActiveTab(tab);
};
return (
<TweetBox>
<TweetTabs activeTab={activeTab} onTabClick={handleTabClick} />
<TweetInput />
{activeTab === "recommendation" && <RecommendationComponent />}
{activeTab === "follow" && <FollowComponent />}
<PostModal show={showPostModal} close={closePostModalHandler}></PostModal>
</TweetBox>
);
};
useStateフックを使って、activeTabというstate変数とsetActiveTabというstate関数を設けました。これらの変数と関数を使ってタブの切り替えを管理します。
初期値としてrecommendationを設定しているので、こちらがデフォルトのタブ用の値です。
{activeTab === "recommendation" && < RecommendatiionComponent > }
{activeTab === "follow" && < FollowComponent > }
の行ではstate変数であるactiveTabの値によって表示する内容を切り替えるようにしています。&&の左辺が成立する(true)の時に右辺のコンポーネントのどちらかを表示させます。
また、activeTab変数とhandleTabClickというイベントハンドラ名でタブを切り替える機構をpropsとして子コンポーネントに渡しています。
import React from "react";
import styled from "styled-components";
const Button = styled.button`
width: 50%;
height: 50px;
background-color: black;
border: none;
color: #737373;
font-weight: bold;
&:hover {
background-color: #1b1b1b;
cursor: pointer;
}
// .activeとすることでReactのstate変数によって管理できる。
// :activeにするとクリックした瞬間だけ適用される
&.active {
color: white;
}
`;
export const TweetTabs = ({ activeTab, onTabClick }) => {
return (
<div>
<Button
// 表示のタブの切り替え
onClick={() => onTabClick("recommendation")}
className={activeTab === "recommendation" ? "active" : ""}
>
おすすめ
</Button>
<Button
// 表示のタブの切り替え
onClick={() => onTabClick("follow")}
className={activeTab === "follow" ? "active" : ""}
>
フォロー中
</Button>
</div>
);
};
propsとして親コンポーネントから渡ってきたactiveTab変数とonTabClickイベントハンドラを受け取ります。
activeTab変数と三項演算子を使ってclassNameを管理します。
className={activeTab === "recommendation" ? "active" : ""}
className={activeTab === "follow" ? "active" : ""}
? の左辺が成立する(true)場合はclassNameにactiveが入ります。
Buttonには&.activeとして、activeの場合に文字色が白くなるように設定しています。
細かい話ですが、&:activeではないのでご注意ください。
.activeであればReactのstate変数で管理できますが、:activeの場合事情が変わってしまい、クリックした時だけ当てはまるという実装になってしまいます。
私はこの違いが分かっていなくて、数時間溶かしてしまいました。。。
また、onClick={() => onTabClick("値")}のイベントハンドラでは値を受け取って親コンポーネントで実装したhandleTabClickに渡します。そこではsetActiveTab関数が値を受け取るようになっているので、関数が動く度に表示されるタブが切り替わります。
以上で実装内容の説明を終わります。
前回のBootstrapとHTMLを使った実装よりもシンプルで分かりやすいと個人的には感じます。
最後まで読んで頂きありがとうございます。