タスク管理ツールをReact + ASP.Coreで作る 010詳細画面構築(操作したいタスクのIDを選択する機能を作る)

[前回](https://qiita.com/mosuma/items/58ee9b3012975f7c2495)の続きです


前回までで、左側にリスト、右側に詳細情報の閲覧・編集画面を配置する様に表示領域ごとにコンポーネントを作りました。

今回の記事では、左側のリストの選択に伴って、右側の詳細情報・編集画面利用域に「どのタスクを選択しているのかの情報を伝える」ところまでを構築していこうと思います。

### ガイド
全体Index：[タスク管理ツールをReact + ASP.Coreで作る - Index](https://qiita.com/mosuma/items/88e40dc44e7bff1a54d8)


## 流れ
- 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」の変更を行えるようにします。


```diff_tsx:TaskOperationMain.tsx
+ 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に変更していますが、これはついでの処理で必須ではないです)

```diff_tsx:TaskOperationMain.tsx
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>
    )
}


```

## 実行してみる
上記の変更を盛り込んで実行してみると、以下の様な結果になります。
クリックすると切り替わります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2664470/a9fb07b0-3c64-3ef6-fb56-768dcc1ab93e.png)

今回は以上です。
続きは[次回](https://qiita.com/mosuma/items/0f005e8def0232714185)です