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][L2] テキストボックスの内容を保持する

Last updated at Posted at 2024-12-25

実施条件

[React][L1] Stateを用いてコンテンツ(li)を出力するを理解していること

環境

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 [incompleteTodos, setIncompleteTodos] = useState([
    "TODOです1",
    "TODOです2",
  ]);
  const [completeTodos, setCompleteTodos] = useState([
    "TODOでした1",
    "TODOでした2",
  ]);

  return (
    <>
      <div className="input-area">
        <input placeholder="TODOを入力"></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);

  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>
    </>
  );
};

解説

目的

  • inputタグ(テキストボックス)に入力された内容を、todoTextに入力(保持)する

コーディング

  1. inputタグ(テキストボックス)に入力された内容を保持するState(todoText)を用意する
    初期値は""

    Todo.jsx
    export const Todo = () => {
    
    + const [todoText, setTodoText] = useState("");
      const [incompleteTodos, setIncompleteTodos] = useState([
        "TODOです1",
        "TODOです2",
      ]);
      const [completeTodos, setCompleteTodos] = useState([
        "TODOでした1",
        "TODOでした2",
      ]);
    
  2. inputタグ(テキストボックス)に入力されたvalueState(todoText)と同期する
    課題: todoTextの初期値は""なので、更新できない

    Todo.jsx
      return (
        <>
          <div className="input-area">
    -       <input placeholder="TODOを入力"></input>
    +       <input placeholder="TODOを入力" value={todoText}></input>
            <button>追加</button>
          </div>
    
  3. inputタグ(テキストボックス)に入力されたvalueが変化したことを検知できるようにする
    onChangeイベントを設定する

    Todo.jsx
      return (
        <>
          <div className="input-area">
    -       <input placeholder="TODOを入力"></input>
    +       <input placeholder="TODOを入力" value={todoText} onChange={}></input>
            <button>追加</button>
          </div>
    
  4. onChangeイベントが発火した時に、todoTextを更新する関数(setTodoText)が動くように実装する
    event.target.valueについては、Tips参照

    Todo.jsx
    + const onChangeTodoText = (event) => setTodoText(event.target.value);
    
      return (
        <>
          <div className="input-area">
    -       <input placeholder="TODOを入力"></input>
    +       <input placeholder="TODOを入力" value={todoText} onChange={onChangeTodoText}>
    

処理

  1. イベントonChangeが発火する
  2. 関数onChangeTodoTextが起動する
  3. 更新関数setTodoTextの引数にevent.target.valueが入る
  4. State todoTextevent.target.valueが入り、更新される
  5. inputタグ(テキストボックス)に入力されたvalueState(todoText)に保持される

Tips

event.target.value

フォーム要素(例: <input><textarea>)の値を取得するためによく使用されるプロパティです。eventはイベントオブジェクトであり、targetはイベントが発生した要素を指します。その中のvalueプロパティが、フォーム要素に入力された現在の値を表します。

ここでは、event.target.valueを使用する関数onChangeTodoTextがセットされた<input>でイベントが発生した場合、<input>内のvalueを取得する。

イメージ

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?