Learning React(5.Reactイベント)

95348 ワード

1.活動


01.開始前準備

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>React!</title>
  <!-- 리액트 라이브러리와 리액트가 DOM에 대한 작업할 때 필요한 다양한 기능을 추가 -->
  <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
  <!-- 바벨, 자바스크립트 컴파일러의 참조 -->
  <script src="https://unpkg.com/[email protected]/babel.min.js"></script>
  <style>
    #container {
      padding: 50px;
      background-color: #EEE;
    }
  </style>
</head>

<body>
  <div id="container"></div>

  <script type="text/babel">
    var destination = document.querySelector("#container");
  </script>
</body>

</html>

02.UI実装

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>React!</title>
  <!-- 리액트 라이브러리와 리액트가 DOM에 대한 작업할 때 필요한 다양한 기능을 추가 -->
  <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
  <!-- 바벨, 자바스크립트 컴파일러의 참조 -->
  <script src="https://unpkg.com/[email protected]/babel.min.js"></script>
  <style>
    #container {
      padding: 50px;
      background-color: #EEE;
    }
  </style>
</head>

<body>
  <div id="container"></div>

  <script type="text/babel">
    class Counter extends React.Component {
      render() {
        var textStyle = {
          fontSize : 78,
          fontFmail : 'sans-serif',
          color : '#333',
          fontWeight : 'bold'
        };

        return(
          <div style={textStyle}>
            {this.props.display}
          </div>
        )
      }
    }

    class CounterParent extends React.Component {
      constructor(props) {
        super(props);

        this.state = {
          count : 0
        };
      }

      render() {
        var backgroundStyle = {
          padding : 50,
          backgroundColor : '#FFC53A',
          width : 250,
          height : 100,
          borderRadius : 10,
          textAlign : 'center'
        };

        var buttonStyle = {
          fontSize : '1em',
          width : 30,
          height : 30,
          fontFmail : 'sans-serif',
          color : '#333',
          fontWeight : 'bold',
          lineHeight : '3px'
        };

        return (
          <div style={backgroundStyle}>
            <Counter display={this.state.count} />
            <button style={buttonStyle}>+</button>
          </div>
        );
      }
    }

    ReactDOM.render(
      <div>
        <CounterParent/>
      </div>,
      document.querySelector("#container")
    )
  </script>
</body>

</html>

03.キー機能実現


登録
  • クリックイベントリスナー
  • 毎回
  • をクリックします.state.count属性値の増加を実現するハンドル
  • <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>React!</title>
      <!-- 리액트 라이브러리와 리액트가 DOM에 대한 작업할 때 필요한 다양한 기능을 추가 -->
      <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
      <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
      <!-- 바벨, 자바스크립트 컴파일러의 참조 -->
      <script src="https://unpkg.com/[email protected]/babel.min.js"></script>
      <style>
        #container {
          padding: 50px;
          background-color: #EEE;
        }
      </style>
    </head>
    
    <body>
      <div id="container"></div>
    
      <script type="text/babel">
        class Counter extends React.Component {
          render() {
            var textStyle = {
              fontSize : 78,
              fontFmail : 'sans-serif',
              color : '#333',
              fontWeight : 'bold'
            };
    
            return(
              <div style={textStyle}>
                {this.props.display}
              </div>
            )
          }
        }
    
        class CounterParent extends React.Component {
          constructor(props) {
            super(props);
    
            this.state = {
              count : 0
            };
    
            this.increas = this.increas.bind(this);
          }
    
          increas(e) {
            this.setState({
              count : this.state.count + 1
            })
          }
    
          render() {
            var backgroundStyle = {
              padding : 50,
              backgroundColor : '#FFC53A',
              width : 250,
              height : 100,
              borderRadius : 10,
              textAlign : 'center'
            };
    
            var buttonStyle = {
              fontSize : '1em',
              width : 30,
              height : 30,
              fontFmail : 'sans-serif',
              color : '#333',
              fontWeight : 'bold',
              lineHeight : '3px'
            };
    
            return (
              <div style={backgroundStyle}>
                <Counter display={this.state.count} />
                <button onClick={this.increas} style={buttonStyle}>+</button>
              </div>
            );
          }
        }
    
        ReactDOM.render(
          <div>
            <CounterParent/>
          </div>,
          document.querySelector("#container")
        )
      </script>
    </body>
    
    </html>


    04.合成イベント

  • MouseEventやKeyboardEventなどのネイティブイベントは受け入れず、ブラウザのネイティブイベントを常にパラメータのSyntheticEventタイプとしてパッケージします.
  • システムイベントを持っていても、DOMで正常に動作します.
    https://ko.reactjs.org/docs/events.html
  • -1.システムイベントのプロパティ

  • boolean bubbles
  • boolean cancelable
  • DOMEventTarget currentTarget
  • boolean defaultPrevented
  • number eventPhase
  • boolean isTrusted
  • DOMEvent nativeEvent
  • void preventDefault()
  • boolean isDefaultPrevented()
  • void stopPropagation()
  • boolean isPropagationStopped()
  • DOMEventTarget target
  • number timeStamp
  • string type
  • -2.マウスシステムイベントのプロパティ

  • boolean altKey
  • number button
  • number buttons
  • number clientX
  • number clientY
  • boolean ctrlKey
  • boolean getModifierState(key)
  • booelan metaKey
  • number pageX
  • number pageY
  • DOMEventTarget relatedTarget
  • number screenX
  • number screenY
  • boolean shiftKey
  • -3.キーボード・システムのイベント・プロパティ

  • boolean altKey
  • number charCode
  • boolean ctrlKey
  • boolean getModifierState(key)
  • string key
  • number keyCode
  • string locale
  • number location
  • boolean metaKey
  • boolean repeat
  • boolean shiftKey
  • number whitch
  • 05.アクティブ属性の利用

  • 以前のタスクでは、追加のshiftキーを押しながらプラスボタンをクリックすると、カウンタは10インクリメンタルにイベント
  • を追加します.
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>React!</title>
      <!-- 리액트 라이브러리와 리액트가 DOM에 대한 작업할 때 필요한 다양한 기능을 추가 -->
      <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
      <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
      <!-- 바벨, 자바스크립트 컴파일러의 참조 -->
      <script src="https://unpkg.com/[email protected]/babel.min.js"></script>
      <style>
        #container {
          padding: 50px;
          background-color: #EEE;
        }
      </style>
    </head>
    
    <body>
      <div id="container"></div>
    
      <script type="text/babel">
        class Counter extends React.Component {
          render() {
            var textStyle = {
              fontSize : 78,
              fontFmail : 'sans-serif',
              color : '#333',
              fontWeight : 'bold'
            };
    
            return(
              <div style={textStyle}>
                {this.props.display}
              </div>
            )
          }
        }
    
        class CounterParent extends React.Component {
          constructor(props) {
            super(props);
    
            this.state = {
              count : 0
            };
    
            this.increas = this.increas.bind(this);
          }
    
          increas(e) {
            var currentCount = this.state.count;
    
            currentCount = (e.shiftKey)? currentCount+=10 : currentCount+=1;
    
            this.setState({
              count : currentCount
            })
          }
    
          render() {
            var backgroundStyle = {
              padding : 50,
              backgroundColor : '#FFC53A',
              width : 250,
              height : 100,
              borderRadius : 10,
              textAlign : 'center'
            };
    
            var buttonStyle = {
              fontSize : '1em',
              width : 30,
              height : 30,
              fontFmail : 'sans-serif',
              color : '#333',
              fontWeight : 'bold',
              lineHeight : '3px'
            };
    
            return (
              <div style={backgroundStyle}>
                <Counter display={this.state.count} />
                <button onClick={this.increas} style={buttonStyle}>+</button>
              </div>
            );
          }
        }
    
        ReactDOM.render(
          <div>
            <CounterParent/>
          </div>,
          document.querySelector("#container")
        )
      </script>
    </body>
    
    </html>


    06.その他のイベント処理方法


    -1.構成部品のイベントを直接更新することはできません。


    1.イベントを構成部品に直接渡す

  • 要素はDOMセグメントを囲むパッケージであるため、要素は直接イベントをパブリッシュすることはできない
  • .
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>React!</title>
      <!-- 리액트 라이브러리와 리액트가 DOM에 대한 작업할 때 필요한 다양한 기능을 추가 -->
      <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
      <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
      <!-- 바벨, 자바스크립트 컴파일러의 참조 -->
      <script src="https://unpkg.com/[email protected]/babel.min.js"></script>
      <style>
        #container {
          padding: 50px;
          background-color: #EEE;
        }
      </style>
    </head>
    
    <body>
      <div id="container"></div>
    
      <script type="text/babel">
        class Counter extends React.Component {
          render() {
            var textStyle = {
              fontSize : 78,
              fontFmail : 'sans-serif',
              color : '#333',
              fontWeight : 'bold'
            };
    
            return(
              <div style={textStyle}>
                {this.props.display}
              </div>
            )
          }
        }
    
        class PlusButton extends React.Component {
          render () {
            var buttonStyle = {
              fontSize : '1em',
              width : 30,
              height : 30,
              fontFmail : 'sans-serif',
              color : '#333',
              fontWeight : 'bold',
              lineHeight : '3px'
            };
            
            return(
              <button style={buttonStyle}> + </button>
            )
          }
        }
    
        class CounterParent extends React.Component {
          constructor(props) {
            super(props);
    
            this.state = {
              count : 0
            };
    
            this.increas = this.increas.bind(this);
          }
    
          increas(e) {
            var currentCount = this.state.count;
            currentCount = (e.shiftKey)? currentCount+=10 : currentCount+=1;
    
            this.setState({
              count : currentCount
            })
          }
    
          render() {
            var backgroundStyle = {
              padding : 50,
              backgroundColor : '#FFC53A',
              width : 250,
              height : 100,
              borderRadius : 10,
              textAlign : 'center'
            };
    
            return (
              <div style={backgroundStyle}>
                <Counter display={this.state.count} />
                <PlusButton onClick={this.increas}/>
              </div>
            );
          }
        }
    
    
    
        ReactDOM.render(
          <div>
            <CounterParent/>
          </div>,
          document.querySelector("#container")
        )
      </script>
    </body>
    
    </html>



    2.イベント属性を構成部品のDOM要素に渡す

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>React!</title>
      <!-- 리액트 라이브러리와 리액트가 DOM에 대한 작업할 때 필요한 다양한 기능을 추가 -->
      <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
      <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
      <!-- 바벨, 자바스크립트 컴파일러의 참조 -->
      <script src="https://unpkg.com/[email protected]/babel.min.js"></script>
      <style>
        #container {
          padding: 50px;
          background-color: #EEE;
        }
      </style>
    </head>
    
    <body>
      <div id="container"></div>
    
      <script type="text/babel">
        class Counter extends React.Component {
          render() {
            var textStyle = {
              fontSize : 78,
              fontFmail : 'sans-serif',
              color : '#333',
              fontWeight : 'bold'
            };
    
            return(
              <div style={textStyle}>
                {this.props.display}
              </div>
            )
          }
        }
    
        class PlusButton extends React.Component {
          render () {
            var buttonStyle = {
              fontSize : '1em',
              width : 30,
              height : 30,
              fontFmail : 'sans-serif',
              color : '#333',
              fontWeight : 'bold',
              lineHeight : '3px'
            };
            
            return(
              <button onClick={this.props.clickHandler} style={buttonStyle}> + </button>
            )
          }
        }
    
        class CounterParent extends React.Component {
          constructor(props) {
            super(props);
    
            this.state = {
              count : 0
            };
    
            this.increas = this.increas.bind(this);
          }
    
          increas(e) {
            var currentCount = this.state.count;
            currentCount = (e.shiftKey)? currentCount+=10 : currentCount+=1;
    
            this.setState({
              count : currentCount
            })
          }
    
          render() {
            var backgroundStyle = {
              padding : 50,
              backgroundColor : '#FFC53A',
              width : 250,
              height : 100,
              borderRadius : 10,
              textAlign : 'center'
            };
    
            return (
              <div style={backgroundStyle}>
                <Counter display={this.state.count} />
                <PlusButton clickHandler={this.increas}/>
              </div>
            );
          }
        }
    
    
    
        ReactDOM.render(
          <div>
            <CounterParent/>
          </div>,
          document.querySelector("#container")
        )
      </script>
    </body>
    
    </html>



    07.イベントハンドラ内部のthis

    function doSomething(e) {
    	console.log(this); // button element
    }
    
    var btn = document.querySelector("button");
    btn.addEventListener('click', doSomething, false);
  • イベントハンドラ内部のthisはイベントを生成する要素を参照するが、反応中はイベントを生成する要素の参照
  • ではない.
  • この値は役に立たないが、定義されていないだけで、bindメソッドを使用して明確に指定された理由は
  • である.
    this.increas = this.increas.bind(this);
  • ここでincreasイベントハンドルのthisは、イベントをトリガーする要素
  • ではなくcounterParent要素を参照する.
  • は、構造関数においてthisの値を素子にバインドするための
  • である.

    08.反応中のイベント処理...一体どうして。


    -1.ブラウザの互換性

  • は現在のブラウザ間で一貫して動作する機能の1つであるが、以前のブラウザ環境に戻ると返済が急激に悪化する
  • .
  • この問題を解決するために、リアクターはすべてのホストイベントをSyntheticEventタイプのオブジェクトとしてパッケージし、互換性のない環境でも同じ方法でイベント
  • を処理できるようにする.

    -2.パフォーマンスの向上


    複雑なUIを持つアプリケーションでは、アクティブなハンドルを作成するほど、アプリケーションがより多くのメモリを占有します.
  • という問題を手動で処理するのは難しくないが、つまらないことになるかもしれないし、不可能なこともあるし、このような面倒で損をしないかもしれないので、反応器は賢明に処理した.
  • リアクターは、DOM ELLIMENT上の
  • にイベントハンドルを直接付着させない
  • は、文書の上部を使用するイベントハンドラ
  • に応答する.
  • イベントハンドラは、すべてのイベントをポーリングし、イベント発生時に適切な各ハンドラ
  • を呼び出す.
  • イベント処理コード
  • を直接最適化する必要はありません.