はじめに
時間割アプリの開発にあたって、曜日選択機能を実装しました。
その際に記述したコードとその解説をしていきます。
機能の詳細
import styled from "styled-components";
import { useState } from "react";
// Styled components
const WeekList = styled.ul`
width: 500px;
display: flex;
justify-content: space-between;
align-items: center;
margin: 0 auto 30px auto;
`;
const WeekItem = styled.li`
width: 50px;
height: 50px;
color: #fff;
font-size: 24px;
font-weight: bold;
border-radius: 2px;
display: flex;
flex-direction: column;
text-align: center;
justify-content: center;
background-color: ${(props) => (props.selected ? "#F6D534" : "#2c65c7")};
cursor: pointer;
transition: background-color 0.3s ease;
&:hover {
background-color: ${(props) => (props.selected ? "#F6D534" : "#4169e1")};
}
`;
// Main component logic
export const WeekSelect = () => {
const [selectedIndex, setSelectedIndex] = useState(0);
const weekDays = ["全", "火", "木", "金", "土", "日"]; // 曜日データ
const handleClick = (index) => {
setSelectedIndex(index); // クリック時にインデックスを更新
};
return (
<>
<WeekList>
{weekDays.map((day, index) => (
<WeekItem
key={index}
selected={selectedIndex === index} // propsとしてselectedを渡す
onClick={() => handleClick(index)} // クリックイベントハンドラ
>
{day}
</WeekItem>
))}
</WeekList>
</>
);
};
解説
マークアップの構造
ulタグ内にliタグがあり、liタグの中に曜日名が格納されている状態
<WeekList>
<WeekItem>
{day}
</WeekItem>
</WeekList>
初期状態の表示
useStateの初期値を配列の0番目にしておくことで、先頭のliタグ(全)を指定。
また、WeekItem(liタグ)にpropsとしてselectedを渡す。
結果スタイル部分で三項演算子を用いて「選択状態なら黄色、出なければ青」を表示できる。
初期状態indexは配列の0番目を表しているため、先頭のliタグが選択状態になり黄色く表示される。
const WeekItem = styled.li`
// 省略
background-color: ${(props) => (props.selected ? "#F6D534" : "#2c65c7")};
`
export const WeekSelect = () => {
const [selectedIndex, setSelectedIndex] = useState(0);
const weekDays = ["全", "火", "木", "金", "土", "日"]; // 曜日データ
const handleClick = (index) => {
setSelectedIndex(index); // クリック時にインデックスを更新
};
return (
<>
<WeekList>
{weekDays.map((day, index) => (
<WeekItem
key={index}
selected={selectedIndex === index} // propsとしてselectedを渡す
onClick={() => handleClick(index)} // クリックイベントハンドラ
>
{day}
</WeekItem>
))}
</WeekList>
</>
);
};
クリックイベント
onClick関数を用いる。
handleClick関数のindexを引数に渡したいので、アロー関数の形をとる。
handleClick関数はクリックしたときに更新関数にindexを渡すことで状態を更新する。
結果クリックした時にindexを取得し、selectedに基づいて変化した状態が再レンダリングによって反映される。
export const WeekSelect = () => {
const [selectedIndex, setSelectedIndex] = useState(0);
const weekDays = ["全", "火", "木", "金", "土", "日"]; // 曜日データ
const handleClick = (index) => {
setSelectedIndex(index); // クリック時にインデックスを更新
};
return (
<>
<WeekList>
{weekDays.map((day, index) => (
<WeekItem
key={index}
selected={selectedIndex === index} // propsとしてselectedを渡す
onClick={() => handleClick(index)} // クリックイベントハンドラ
>
{day}
</WeekItem>
))}
</WeekList>
</>
);
};
備考
map関数で配列の各要素に対してループを行う。
{day}はループ内での現在の要素を表しておりindexはその要素が何番目かを表している。
また、liタグに直接propsを渡すと、意図しない属性がそのままDOMに出力されてしまうことがある。
そのため、liタグをWeekItemとして新しくstyledコンポーネントにし、selectedという名前でpropsを受け取るようにしている。
さいごに
もし言葉不足や誤解を生む表現、誤った描写があれば教えていただけると助かります。
また、別のもっと適切な方法があればぜひ教えていただきたいです。
時間割アプリで使用した他の機能はこちら
