【備忘録】Reactで状態管理を実施する(React useState)

### useStateのサンプル

成果物の完成
![スクリーンショット 2022-05-26 14.35.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/13e5272a-ca9b-43d1-1872-1bd4f8258820.png)

```javascript: App.tsx
import { useState } from 'react';

function App() {
  // emailは変数名、setEmailはイベント発火時の関数
  const [userID, setUserID] = useState('');
  const [password, setPassword] = useState('');
  // 文字が打たれる度にコールされる。
  console.log(userID + password);
  return (
    <div>
      <h1>ユーザログイン画面</h1>
      <form>
        <div>
          <label>
            ユーザID:
            {/* 発火時の内容を指定 */}
            <input
              name="userID"
              onChange={(e) => setUserID(e.target.value)}
            />
          </label>
        </div>
        <div>
          <label>
            パスワード：
            {/* 発火時の内容を指定 */}
            <input
              name="password"
              type="password"
              onChange={(e) => setPassword(e.target.value)}
            />
          </label>
        </div>
        <button type="submit">Submit</button>
      </form>
    </div>
  );
}

export default App;
```


### サンプル2

成果物の完成イメージ
![スクリーンショット 2022-05-26 15.04.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/6d3084f5-9e14-ded5-66d1-73517296a276.png)

```javascript: App.js
import React from 'react';

import ResourceList from './ResourceList';

class App extends React.Component {
  state = {
    resourceName: 'posts'
  }

//   リソース名を変更する
  render() {
    return (
      <>
        <button onClick={() => this.setState({ resourceName: 'posts' })}>Posts</button>
        <button onClick={() => this.setState({ resourceName: 'todos' })}>Todos</button>
        <ResourceList resourceName={this.state.resourceName}/>
      </>
    )
  }
}
export default App;
```

```javascript: ResourceList.js
import React from 'react';
import axios from 'axios';

const baseUrl = "https://jsonplaceholder.typicode.com"

class ResourceList extends React.Component {
  state = {
    resources: [],
  }

  async componentDidMount() {
    const response = await axios.get(`${baseUrl}/${this.props.resourceName}`);
    console.log('response: '+ response)
   this.setState({ resources: response.data });
  }

  async componentDidUpdate(prevProps) {
    if(prevProps.resourceName !== this.props.resourceName) {
      const response = await axios.get(`${baseUrl}/${this.props.resourceName}`);
      console.log('response: '+ response)
      this.setState({ resources: response.data });
    }
  }

  render() {
    return (
      <>
      <ul>
        <>
        {this.state.resources.map(result => (
        <>
        <li>【タイトル】{result.title}</li>
           【本文】{result.body}
        </>
        ))}
      </>
      </ul>
      </>
    )
  }
}

export default ResourceList;
```

### Todo一覧
成果物イメージ
![スクリーンショット 2022-05-26 15.58.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/585e4f5d-cdb6-db96-ab53-2c934fc5db82.png)
```javascript:App.tsx
import React, { FC, useState, ChangeEvent} from 'react';
import './App.css';
import Todo from './components/Todo';
import { ITask } from './ITask';

const App: FC = () => {
  // タスクの設定
  const [task, setTask] = useState<string>("")
  // タスクの説明
  const [description, setDescription] = useState<string>("")
  // TODOの一覧
  const [todoList, setTodoList] = useState<ITask[]>([])

  // 
  const handleChange = (event: ChangeEvent<HTMLInputElement>): void => {
    if (event.target.name === "todo") {
      console.log("event.target.name: task")
      setTask(event.target.value)
    } else{
      console.log("event.target.name: description")
      setDescription(event.target.value)
    } 
  }

  // タスクの追加
  const addTask = (): void => {
    const newTask = { taskName: task, description: description}
    setTodoList([...todoList, newTask])
    setTask("") //元の値に戻す
    setDescription("") //元の値に戻す
  }

  // 完了タスク
  const completeTask = (taskNameToDelete: string): void => {
    setTodoList(todoList.filter((task) => {
      return task.taskName !== taskNameToDelete
    }))
  }

  return (
    <div className="App">
      <div className="header">
        <h1>TodoList</h1>
        <div className="inputContainer">
          <input type="text" placeholder="Todo..." onChange={handleChange} name="todo" value={task} />
          <input type="text" placeholder="概要" onChange={handleChange} name="description" value={description} />
        </div>
        <button onClick={addTask}>Todoの追加</button>
      </div>
      <div className="todoList">
        {todoList.map((task: ITask, index: number) => {
          return <Todo key={index} task={task} completeTask={completeTask}/>
        })}
      </div>
    </div>
  );
}

export default App;

```

```typescript: Todo.tsx
import React from 'react'
import { ITask } from '../ITask'

// Props
interface Props {
    task: ITask;
    completeTask(taskNameToDelete: string): void;
}

const Todo = ( {task, completeTask}: Props ) => {
    return (
        <div className="task">
            <div className="content">
                <span>{task.taskName} </span>
                <span>{task.description} </span>
            <button onClick={() => {completeTask(task.taskName)}}> 削除 </button>
            </div>
        </div>
    )
}

export default Todo
```

```typescript: ITask.tsx
export interface ITask {
    taskName: string;
    description: string;
}
```