0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Reactで曜日選択の切り替え動作を実装

Last updated at Posted at 2024-09-30

はじめに

時間割アプリの開発にあたって、曜日選択機能を実装しました。
その際に記述したコードとその解説をしていきます。

機能の詳細

  • 完成時の画面表示スクリーンショット 2024-09-30 11.31.00.png
  • 実装する機能
    1.初期状態は先頭のliタグを黄色表示
    2.liタグをクリックすると黄色くなり、すでに黄色いliタグは青に戻る
  • 最終的なコード
WeekSelect.jsx
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タグの中に曜日名が格納されている状態

WeekSelect.jsx
      <WeekList>
          <WeekItem>
            {day}
          </WeekItem>
      </WeekList>

初期状態の表示

useStateの初期値を配列の0番目にしておくことで、先頭のliタグ(全)を指定。
また、WeekItem(liタグ)にpropsとしてselectedを渡す。
結果スタイル部分で三項演算子を用いて「選択状態なら黄色、出なければ青」を表示できる。
初期状態indexは配列の0番目を表しているため、先頭のliタグが選択状態になり黄色く表示される。

WeekSelect.jsx
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に基づいて変化した状態が再レンダリングによって反映される。

WeekSelect.jsx
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を受け取るようにしている。

さいごに

もし言葉不足や誤解を生む表現、誤った描写があれば教えていただけると助かります。
また、別のもっと適切な方法があればぜひ教えていただきたいです。

時間割アプリで使用した他の機能はこちら

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?