前回の続きです
前回までで、左側にリスト、右側に詳細情報の閲覧・編集画面を配置する様に表示領域ごとにコンポーネントを作りました。
今回の記事では、左側のリストの選択に伴って、右側の詳細情報・編集画面利用域に「どのタスクを選択しているのかの情報を伝える」ところまでを構築していこうと思います。
ガイド
全体Index:タスク管理ツールをReact + ASP.Coreで作る - Index
流れ
- TaskOperationMain関数に選択しているタスクのID番号をstateで持つ
- TaskListでTableを選択可能にし、選択中の行の色を変えるとともにTaskOperationMain関数の選択中タスクのIDを格納しているstateの値を変更する
構築
TaskOperationMain.tsx
TaskOperationMain関数に、選択しているタスクのID番号を格納する「selectedId_task」というstateを導入します。
「selectedId_task」とselectedId_taskの値をセットする「setSelectedId_task」関数を「TaskList」コンポーネントに渡し、Listの操作によって「selectedId_task」の変更を行えるようにします。
+ import { useState } from "react";
import { Col, Row } from "react-bootstrap"
import { TaskEdit } from "./TaskEdit"
import { TaskList } from "./TaskList"
export const TaskOperationMain = () => {
+ const [selectedId_task, setSelectedId_task] = useState("");
return (
<div>
<Row>
<Col>
- <TaskList />
+ <TaskList selectedId_task={selectedId_task} setSelectedId_task={setSelectedId_task}/>
</Col>
<Col>
- <TaskEdit id_task="dammy" />
+ <TaskEdit id_task={selectedId_task} />
</Col>
</Row>
</div>
)
}
TaskOperationMain.tsx
TaskOperationMainは以下の様に修正します。
selectedId_taskの値に応じて行の色を変える処理と、各行をクリック可能にしてクリック時に「selectedId_task」関数にその行のタスクのIDを渡す仕様に変更しました。
また、それらの処理を行うためにPropsの設定、関連する参照の呼び出しなどを実施しています。
(※tableをReact-bootstrapのTableに変更していますが、これはついでの処理で必須ではないです)
import { useEffect, useState } from 'react';
+import { Button, Table } from 'react-bootstrap';
interface Task {
id_task: string;
title: string;
is_finish: boolean;
end_date_scheduled: Date;
}
+interface Props {
+ selectedId_task: string;
+ setSelectedId_task: React.Dispatch<React.SetStateAction<string>>;
+}
-export const TaskList = () => {
+export const TaskList = ({selectedId_task, setSelectedId_task}: Props) => {
const [loading, setLoading] = useState(true);
const [tasks, setTasks] = useState<Task[]>();
useEffect(() => {
populateWeatherData();
}, []);
const populateWeatherData = async () => {
const response = await fetch('https://localhost:5001/task');
const data = await response.json();
setTasks(data);
setLoading(false);
};
if(loading) return <div>loading....</div>
return (
<div>
<h1 id="tabelLabel">Task List</h1>
<p>This component demonstrates fetching data from the server.</p>
- <table className="table table-striped" aria-labelledby="tabelLabel">
+ <Table >
<thead>
<tr>
<th>No.</th>
<th>Fin.</th>
<th>Title</th>
<th>Due Date</th>
</tr>
</thead>
<tbody>
{tasks && tasks.map((task, index) => (
- <tr key={task.id_task}>
+ <tr
+ key={task.id_task} onClick={()=>{setSelectedId_task(task.id_task)}}
+ className={ selectedId_task === task.id_task ? "table-info" : ""}
+ >
<td>{index+1}</td>
<td><input type="checkbox" defaultChecked={task.is_finish} disabled /></td>
<td>{task.title}</td>
<td>{task.end_date_scheduled && (new Date(task.end_date_scheduled).toDateString())}</td>
</tr>
))}
</tbody>
- </table>
+ </Table>
</div>
)
}
実行してみる
上記の変更を盛り込んで実行してみると、以下の様な結果になります。
クリックすると切り替わります
今回は以上です。
続きは次回です