62608


Reactでテキストフォームをリセットする方法をご教示いただけないでしょうか。  
下記は動作デモです。  
[demo](https://codesandbox.io/s/crimson-
moon-22s6f?fontsize=14&hidenavigation=1&theme=dark)

テキストフォームに「ok」を入力し「check」ボタンを押すことで"ok"というアラートが表示されます。  
テキストフォームに「ok」以外を入力し「check」ボタンを押した場合は、"no"というアラートが表示されます。

デモにおいて、「clear」ボタンを押すことで、テキストフォームをクリア（空に）したいです。

## ソースコード

[code]

    import React from "react";
    
    let text = "";
    
    const App = () => {
      const inputValue = e => {
        text = e.target.value;
      };
    
      const check = () => {
        if (text === "ok") {
          alert("ok");
          return;
        }
        alert("no");
      };
      const clear = () => {
        text = "";
      };
    
      return (
        <>
          <input type="text" onChange={inputValue} />
          <p>please type "ok".</p>
          <button onClick={clear}>clear</button>
          <button onClick={check}>check</button>
        </>
      );
    };
    
    export default App;
[/code]

## 試したこと

テキストフォームのvalueをstateとして管理すれば、テキストフォームの中をクリアすることできました。  
[demo2](https://codesandbox.io/s/eager-
euclid-d0s8v?fontsize=14&hidenavigation=1&theme=dark)

しかし上記のデモだとテキストフォームの文字が変わる度にsetStateされ、そのたびにコンポーネントがレンダリングされます。  
できるだけ不要なレンダリングは避けたいです。


CC BY-SA 4.0
2020-01-27T06:27:44.633
62579
2020-01-28T09:47:32.200
2020-01-28T06:34:23.727
35433
35433
question
javascript reactjs
Reactでinput type="text"のvalueをボタンを押すことでリセットしたい。


この場合に一般的な方法は、input要素のDOMオブジェクトを取得して直に操作する方法です。変更箇所にコメントを付けてあります。

[code]

    import React, { useRef } from "react";
    
    let text = "";
    
    const App = () => {
      // input要素のDOMオブジェクトを入れておく用のrefを作成
      const inputRef = useRef();
    
      const inputValue = e => {
        text = e.target.value;
      };
    
      const check = () => {
        if (text === "ok") {
          alert("ok");
          return;
        }
        alert("no");
      };
      const clear = () => {
        text = "";
        // input要素のDOMオブジェクトを操作してテキストエリアをクリアする
        inputRef.current.value = "";
      };
    
      return (
        <>
          {/* input要素にrefを渡すことでDOMオブジェクトを取得する */}
          <input ref={inputRef} type="text" onChange={inputValue} />
          <p>please type "ok".</p>
          <button onClick={clear}>clear</button>
          <button onClick={check}>check</button>
        </>
      );
    };
    
[/code]

stateに頼らずにテキストエリアをクリアしたい場合には、[input要素のDOMオブジェクト](https://developer.mozilla.org/ja/docs/Web/API/HTMLInputElement)を直接操作する必要があります（具体的には、input要素のDOMオブジェクトの`value`プロパティを`""`とする）。

そのために、上記のコードではinput要素のDOMオブジェクトを取得する処理を追加しました。これは、`useRef`を用いてrefオブジェクトを作成し、input要素のref属性でそのrefオブジェクトを渡すことで行なっています。Reactの機能により、こうすることで`App`コンポーネントのレンダリング後に`inputRef.current`にそのinput要素のDOMオブジェクトが入っています。

* * *

なお、このようにDOMオブジェクトを直接操作する行為は、このinput要素が **制御されたコンポーネント** (controlled component)
である場合は行なってはいけません。  
制御されたコンポーネントとは、`value`がstateとして管理されているコンポーネントのことです。この場合はstateを通じてクリアするのが正しい方法です。

今回はinput要素が制御されたコンポーネントではないので、この方法を行なっても構いません。


CC BY-SA 4.0
2020-01-28T09:41:41.870
62608
2020-01-28T09:47:32.200
2020-01-28T09:47:32.200
30079
30079
62579
answer