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][L3] テキストボックスの内容を出力する

Posted at

実施条件

[React][L2] テキストボックスの内容を保持するを理解していること

環境

MacBook Pro (2.3 GHz 8コアIntel Core i9)
macOS 14.0(23A344)
Homebrew 4.3.8
gh 2.52.0

ソースコードの前に

フォルダ構成

folda_structure
├── package.json
├── public/
│   └── index.html
├── src/
│   ├── index.jsx
│   ├── Todo.jsx
│   └── styles.css
│  

index.html

index.html
<!DOCTYPE html>
<html lang="en">
  <head> </head>

  <body>
    <div id="root"></div>
  </body>
</html>

index.jsx

index.jsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";

import { Todo } from "./Todo";

const rootElement = document.getElementById("root");
const root = createRoot(rootElement);

root.render(
  <StrictMode>
    <Todo />
  </StrictMode>
);

ソースコード

Todo.jsx(旧)

Todo.jsx
import { useState } from "react";
import "./styles.css";

export const Todo = () => {

  const [todoText, setTodoText] = useState("");
  const [incompleteTodos, setIncompleteTodos] = useState([
    "TODOです1",
    "TODOです2",
  ]);
  const [completeTodos, setCompleteTodos] = useState([
    "TODOでした1",
    "TODOでした2",
  ]);

  const onChangeTodoText = (event) => setTodoText(event.target.value);

  return (
    <>
      <div className="input-area">
        <input placeholder="TODOを入力"></input>
        <input placeholder="TODOを入力" value={todoText} onChange={onChangeTodoText}></input>
        <button>追加</button>
      </div>
      <div className="incomplete-area">
        <p className="title">未完了のTODO</p>
        <ul>
          {incompleteTodos.map((todo) => {
            return (
              <li key={todo}>
                <div className="list-row">
                  <p>{todo}</p>
                  <button>完了</button>
                  <button>削除</button>
                </div>
              </li>
            );
          })}
        </ul>
      </div>
      <div className="complete-area">
        <p className="title">完了のTODO</p>
        <ul>
          {completeTodos.map((todo) => {
            return (
              <li>
                <div className="list-row">
                  <p>{todo}</p>
                  <button>戻す</button>
                </div>
              </li>
            );
          })}
        </ul>
      </div>
    </>
  );
};

Todo.jsx

Todo.jsx
import { useState } from "react";
import "./styles.css";

export const Todo = () => {

  const [todoText, setTodoText] = useState("");
  const [incompleteTodos, setIncompleteTodos] = useState([
    "TODOです1",
    "TODOです2",
  ]);
  const [completeTodos, setCompleteTodos] = useState([
    "TODOでした1",
    "TODOでした2",
  ]);

  const onChangeTodoText = (event) => setTodoText(event.target.value);

+ const onClickAdd = () => {
+   if (todoText === "") {
+     return;
+   } else {
+     const newTodos = [...incompleteTodos, todoText];
+     setIncompleteTodos(newTodos);
+     setTodoText("");
+   }
+ };

  return (
    <>
      <div className="input-area">
        <input placeholder="TODOを入力"></input>
        <input placeholder="TODOを入力" value={todoText} onChange={onChangeTodoText}></input>
-       <button>追加</button>
+       <button onClick={onClickAdd}>追加</button>
      </div>
      <div className="incomplete-area">
        <p className="title">未完了のTODO</p>
        <ul>
          {incompleteTodos.map((todo) => {
            return (
              <li key={todo}>
                <div className="list-row">
                  <p>{todo}</p>
                  <button>完了</button>
                  <button>削除</button>
                </div>
              </li>
            );
          })}
        </ul>
      </div>
      <div className="complete-area">
        <p className="title">完了のTODO</p>
        <ul>
          {completeTodos.map((todo) => {
            return (
              <li>
                <div className="list-row">
                  <p>{todo}</p>
                  <button>戻す</button>
                </div>
              </li>
            );
          })}
        </ul>
      </div>
    </>
  );
};

解説

目的

  • buttonタグ(追加)を押下した時に、最新のtodoTextを、配列incompleteTodosに追加する

コーディング

  1. buttonタグ(追加)を押下した際に発火する、onClickイベントを設定する

    Todo.jsx
    -       <button>追加</button>
    +       <button onClick={onClickAdd}>追加</button>
    
  2. onClickイベントで呼び出される関数をonClickAddとして設定する

    Todo.jsx
    + const onClickAdd = () => {
    + };
    
  3. onClickAddにて、スプレッド構文を用いて、最新のtodoTextの値を、配列incompleteTodosに追加して、newTodosとして定義する

    Todo.jsx
      const onClickAdd = () => {
    +     const newTodos = [...incompleteTodos, todoText];
      };
    
  4. newTodosを配列incompleteTodosの更新関数であるsetIncompleteTodosに引数として渡す
    = 配列incompleteTodosを更新する

    Todo.jsx
      const onClickAdd = () => {
          const newTodos = [...incompleteTodos, todoText];
    +     setIncompleteTodos(newTodos);
      }; 
    
  5. テキストボックスを""に戻す

    Todo.jsx
      const onClickAdd = () => {
          const newTodos = [...incompleteTodos, todoText];
          setIncompleteTodos(newTodos);
    +     setTodoText("");
      };
    
  6. 値を入力していなくても、空文字で追加ができてしまうため、ifで条件分岐する

    Todo.jsx
      const onClickAdd = () => {
    +   if (todoText === "") {
    +     return;
    +   } else {
          const newTodos = [...incompleteTodos, todoText];
          setIncompleteTodos(newTodos);
          setTodoText("");
    +   }
      };
    

処理

  1. buttonタグ(追加)を押下した際に、onClickAddが起動する
  2. todoTextに保持された値が、配列incompleteTodosに追加され、newTodosに格納される
  3. newTodosを引数として、setIncompleteTodosで配列incompleteTodosを更新する
  4. 配列incompleteTodosmapメソッドで、レンダリングされる

イメージ

Todo.jsx(旧)

image.png

Todo.jsx

image.png

参考リンク

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?