はじめに
時間割アプリの開発にあたって、曜日選択機能を実装しました。
その際に記述したコードとその解説をしていきます。
機能の詳細
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
を受け取るようにしている。
さいごに
もし言葉不足や誤解を生む表現、誤った描写があれば教えていただけると助かります。
また、別のもっと適切な方法があればぜひ教えていただきたいです。
時間割アプリで使用した他の機能はこちら