React入門

React入門」の前回はReactのstateについて解説を行いました。

今回はReactのイベントについて解説を行なっていきます。

追記(2020/4/19)
解説にfunctionコンポーネントでの利用方法を追加しました。

functionコンポーネントでの利用方法

イベントはJSX内にonClickやonChangeといったイベントハンドラで設定でき、イベントハンドラには関数オブジェクトを引き渡すことができます。

const MyComponent = () => {
  return (
    <div>
      <input type="button" value="入力" onClick={() => console.log('click')}/>
    </div>
  )
}

関数オブジェクトの引数では通常のJavaScriptと同様にイベントオブジェクトを受け取ることができます。

const MyComponent = () => {
  return (
    <div>
      <input type="text" defaultValue="" onChange={e => console.log(e.target.value)}/>
    </div>
  )
}

イベントオブジェクトはコールバック関数としてJSX外で定義することも可能です。

const MyComponent = () => {
  // コールバック関数
  const handleInput= (e) => {
    // イベント発生時に実行したい処理
    console.log(e.target.value)
  }
 
  return (
    <div>
      <input type="button" defaultValue="" onClick={handleInput}/>
    </div>
  )
}

以下は入力欄にテキストを入力しておき、入力ボタンをクリックすると「入力値:」の横に入力内容が反映される簡単なサンプルです。

//コンポーネントの作成
const MyComponent = () => {
  const [myText,changeMyText] = useState("")
  const [tmpText,changeTmpText] = useState("")

  const handleInput = (e) => {
    changeTmpText(e.target.value)
  }
  const setMyText = () =>{
    changeMyText(tmpText)
    changeTmpText("")
  }
 
  return (
    <div>
      <p>入力値:{myText}</p>
      <input type="text" value={tmpText} onChange={handleInput} />
      <input type="button" value="入力" onClick={setMyText}/>
    </div>
  )
}

useStateを利用して入力中の文字列の状態を「tmpText」と入力ボタンを押されたタイミングの文字列を「myText」と定義しておき、入力欄でchangeイベントが発生した際に実行されるコールバック関数handleInputと入力ボタン押下時に実行されるコールバック関数setMyTextを定義しておき、それぞれJSX内でイベントハンドラとして登録しています。

コールバック関数時にuseCallbackなどを利用すれパフォーマンスに関する処理を最適化することができるでしょう。

Classコンポーネントでの利用方法

以下は入力欄にテキストを入力しておき、入力ボタンをクリックすると「入力値:」の横に入力内容が反映される簡単なサンプルです。

//コンポーネントの作成
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      myText : null
    };
  }
  //テキストの設定
  setMyText(){
      this.setState({
        myText : this.refs.myText.value
      });
      this.refs.myText.value='';
  }
  render() {
    return (
      <div>
        <p>入力値:{this.state.myText}</p>
        <input type="text" ref="myText"/>
        <input type="button" value="入力" onClick={this.setMyText.bind(this)}/>
      </div>
    )
  }
};
 //コンポーネントの描画
ReactDOM.render(
  <MyComponent />,
  document.getElementById('app')
);

それでは、各パートについて順番に解説していきましょう。

まず、イベントはJSX内で指定を行います。

今回は以下のようにボタンに対してonClick属性を利用してイベントを設定しています。
最近のJavaScriptフレームワークではこのようにViewなどのHTMLに直接イベントを記述するのが一般的です。

イベントにはメソッド名の後ろにbind(this)を追加して指定しておきます。これはメソッド内でコンポーネント内にアクセスするために必要な記述です。

入力値:{this.state.myText}
<input type="text" ref="myText">
<input type="button" value="入力" onClick={this.setMyText.bind(this)}>

ref属性による参照

入力要素に指定されているref属性は後ほど入力フィールドの値を参照するための属性です。
Reactではクリック以外のイベントも基本的にはJSX内でonKeyupやonMouseoverと言った感じにonXxxで指定していくことができます。

クリックされた後はsetMyTextメソッドが実行されており、state.myTextに入力内容が反映され再描画処理が発生します。

setMyText(){
  this.setState({
    myText : this.refs.myText.value
  });
  this.refs.myText.value='';
}

JSX内のbind(this)を削除

constructor内で以下のように設定しておけばJSX内のbind(this)は省略可能です。

constructor(props) {
  super(props);
  this.state = {
    myText : null
  };
  this.setMyText = this.setMyText.bind(this);
}

JSX内にbind(this)を記述すると、描画のたびに関数を生成しますのでこちらの記述のほうがスマートです。

それでは、次回はReactのライフサイクルについて解説を行います。