LoginSignup
tiiti
@tiiti

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

Reactでテキストボックスに入力した文字を表示させたいです。

Reactでテキストボックスに入力した文字を表示させたいです。

reactで初歩的なtodoアプリを実装しています。
youtubeなどを見ながらなんとなく実装はできたのですが、
動画に無い方法で任意の値を任意の場所に出力させようとしているのですが基礎的な書き方が分からず質問させていただきました。

発生している問題・エラー

テキストボックス内で入力したタスクを任意の場所に表示させる事ができません。
react内での値の受け渡し、表示のさせ方をなかなか理解できないです。

import { useState, useRef } from "react";
import "./App.css";
// import TodoList from "./TodoList";
import { v4 as uuidv4 } from "uuid";

function App() {
  const [todos, setTodos] = useState([]);
  const todoNameRef = useRef();

  const h1 = "Todoリスト";

  // タスクを追加する関数
  const handleAddTodo = () => {
    const task = todoNameRef.current.value;
    console.log(todoNameRef.current.value);
    setTodos((beforeTasks) => {
      console.log(task);
      return [...beforeTasks, { key: uuidv4(), task: task, completed: false }];
    });
    todoNameRef.current.value = null;
  };

  return (
    <div>
      <h1>{h1}</h1>
      <label>
        <input type="radio" />
        すべて
      </label>
      <label>
        <input type="radio" />
        作業中
      </label>
      <label>
        <input type="radio" />
        完了
      </label>
      <div>{setTodos}</div>
      {/* <TodoList todos={todos} /> */}
      <h2>新規タスクの追加</h2>
      <input type="text" ref={todoNameRef}></input>
      <button onClick={handleAddTodo}>追加</button>
    </div>
  );
}

export default App;

自分で試したこと

関数setTodosの戻り値に表示させたい値を設定しているので、
タスクを表示させたい場所でsetTodosを実行しています。
他にもタスクを表示させる関数を記述してみたり、todoNameRef.current.valueを
どうにか使えないか試行錯誤しているのですが、コンソール上には入力した値を表示できても、HTML上に表示することが出来ません。
自身でも調べてみましたが、なかなか理解に及ばず
基礎的な質問となり大変恐縮ですが、ご教授いただけますと幸いです。

0

2Answer

useState と onChange で出来そうですね

import { useState } from "react";

function Example() {
  const [text, setText] = useState("");

  return (
    <div>
      <div>
        <input type="text" value={text} onChange={(event) => setText(event.target.value)}></input>
      </div>
      <div>
        {text}
      </div>
    </div>
  );
}

export default Example;

image.png

1

Comments

  1. @tiiti

    Questioner
    ご回答ありがとうございます!
    また、ご丁寧にURLも添付してくださりありがとうございます!!

要するにこれがしたいんだと思います.

<div>{todos}</div>

ただしtodosは整形されていない配列なので綺麗に出ないと思います.
通常はmapしながらliにして表示します.

setTodosには確かにコールバックを渡せますが,そこで返した値がsetTodosから返ってくるわけではありません.
Reactではstateは非同期に更新されるため,todoを直接書き換えたり,すぐに(=Reactによるstateの更新を待たずに)更新後のstateを表示させる設計はしないでください.
また,refをstateの代用とする行為は,ライフサイクルを乱しやすいので避けるべきです.

1

Comments

  1. 現在テキストボックスに入力している値を表示したいなら,その値を保持するためのstateを作ってください.
    詳細は省きますが,ReactはsetStateをするまで描画を更新しませんので,これを前提に設計すると良いです.
  2. @tiiti

    Questioner
    ご丁寧にありがとうございます!
    実用的な意見もくださりためになります。
    いただいた回答を参考に設計してみます!

Your answer might help someone💌