Learning React(4.React状態)

76434 ワード

1.処理状態

  • データを動的に利用するために、propsのように親に渡すのではなく、状態(State)にデータを格納する.
  • 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");
    
        class LightningCounter extends React.Component {
          render() {
            return (
              <h1>Hello!</h1>
            )
          }
        }
    
        class LightningCounterDisplay extends React.Component {
          render() {
            var divStyle = {
              width : 250
              , textAlign : "center"
              , backgroundColor : "black"
              , padding : 40
              , fontFamily : "sans-serif"
              , color : "#999"
              , borderRadius : 10
            };
    
            return (
              <div style={divStyle}>
                  <LightningCounter />
              </div>
            )
          }
        }
        
        ReactDOM.render(
          <LightningCounterDisplay />
          , destination
        );
      </script>
    </body>
    
    </html>

    02.カウンタを開く

  • setInterval関数を使用して、1000ミリ秒(1秒)ごとにカウンタコードを呼び出します.
  • componentDidMount
  • この方法は、構成部品をレンダリング(またはマウント)した後、
  • を実行します.
  • setState
  • メソッドではstateオブジェクトの値
  • を更新できます.

    -1.初期状態値の設定

  • 打撃状態変数宣言
  • <!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");
    
        class LightningCounter extends React.Component {
          constructor(props) {
            super(props);
    
            this.state = {
              strikes : 0
            };
          }
          render() {
            return (
              <h1>{this.state.strikes}</h1>
            )
          }
        }
    
        class LightningCounterDisplay extends React.Component {
          render() {
            var divStyle = {
              width : 250
              , textAlign : "center"
              , backgroundColor : "black"
              , padding : 40
              , fontFamily : "sans-serif"
              , color : "#999"
              , borderRadius : 10
            };
    
            return (
              <div style={divStyle}>
                  <LightningCounter />
              </div>
            )
          }
        }
        
        ReactDOM.render(
          <LightningCounterDisplay />
          , destination
        );
      </script>
    </body>
    
    </html>


    -2、タイマー起動と状態設定

  • タイマを起動し、キー属性値
  • を増加する番になる.
  • setInterval関数を使用すると、1秒あたり100打撃属性
  • が増加します.
  • の動作はレンダリング後に実行する必要があるので、コンポーネントDidMountメソッド
  • を使用します.
    <!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");
    
        class LightningCounter extends React.Component {
          constructor(props) {
            super(props);
    
            this.state = {
              strikes : 0
            };
    
            // timerTick 함수는 추가됐지만 그 콘텐츠에 컴포넌트의 컨텍스트가 유지되지는 않는다
            // 그렇기에 일단은 timerTick함수를 컴포넌트에 명시적으로 바인딩 시켜준다
            this.timerTick = this.timerTick.bind(this);
          }
    
          timerTick() {
            this.setState({
              strikes : this.state.strikes + 100
            });
            /*
            리액트는 성능상의 이유로 연속된 상태 갱신 작업들을 모아서 한꺼번에 처리한다
            따라서 this.state에 저장된 원래 값이 실시간으로 동기화되지 못할 수도 있다
            이를 보완하기 위해 setState 메소드는 prevState 인자를 통해 만약 prevState를 사용한다면 다음과 같은 코드가 된다
            this.setState((prevState) => {
              return {
                strikes : prevState.strikes + 100;
              }
            })
            */
          }
    
          componentDidMount() {
            setInterval(this.timerTick, 1000);
          }
    
          render() {
            return (
              <h1>{this.state.strikes}</h1>
            )
          }
        }
    
        class LightningCounterDisplay extends React.Component {
          render() {
            var divStyle = {
              width : 250
              , textAlign : "center"
              , backgroundColor : "black"
              , padding : 40
              , fontFamily : "sans-serif"
              , color : "#999"
              , borderRadius : 10
            };
    
            return (
              <div style={divStyle}>
                  <LightningCounter />
              </div>
            )
          }
        }
        
        ReactDOM.render(
          <LightningCounterDisplay />
          , destination
        );
      </script>
    </body>
    
    </html>



    2.データからUIへ


    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");
    
        class Circle extends React.Component {
          render() {
            var circleStyle = {
              padding : 10
              , margin : 20
              , display : "inline-block"
              , backgroundColor : this.props.bgColor
              , borderRadius : "50%"
              , width : 100
              , height : 100
              ,
            };
    
            return (
              <div style={circleStyle} />
            );
          }
        }
        
        ReactDOM.render(
          <div>
            <Circle bgColor="#F9C240" />
          </div>
          , destination
        );
      </script>
    </body>
    
    </html>

    02.JSX-2はどこでも利用可能

  • 変数に代入して素子をインスタンス化することもできるし、戻り素子の関数
  • を作成することもできる.
    <!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");
    
        class Circle extends React.Component {
          render() {
            var circleStyle = {
              padding : 10
              , margin : 20
              , display : "inline-block"
              , backgroundColor : this.props.bgColor
              , borderRadius : "50%"
              , width : 100
              , height : 100
              ,
            };
    
            return (
              <div style={circleStyle} />
            );
          }
        }
    
        var theCorcle = <Circle bgColor="#F9C240" />
    
        function showCircle() {
          var colors = ["#393E41", "#E94F37", "#1C89BF", "#A1D363"];
          var ran = Math.floor(Math.random() * colors.length);
    
          // 무작위로 선택된 컬러의 Circle을 리턴
          return <Circle bgColor={colors[ran]} />
        }
        
        ReactDOM.render(
          <div>
            {theCorcle}
            {showCircle()}
          </div>
          , destination
        );
      </script>
    </body>
    
    </html>


    03.処理配列

  • 常に部品を手動で指定するのは容易ではありません

  • したがって、
  • は、配列またはその同類(奇形器等)
  • を用いることが好ましい.
    <!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");
    
        class Circle extends React.Component {
          render() {
            var circleStyle = {
              padding : 10
              , margin : 20
              , display : "inline-block"
              , backgroundColor : this.props.bgColor
              , borderRadius : "50%"
              , width : 100
              , height : 100
              ,
            };
    
            return (
              <div style={circleStyle} />
            );
          }
        }
    
        var theCorcle = <Circle bgColor="#F9C240" />
    
        function showCircles() {
          var colors = ["#393E41", "#E94F37", "#1C89BF", "#A1D363"
                        ,"#85FFC7", "#297373", "#FF8552", "#A40E4C"];
          var renderData = [];
    
          for(var i = 0; i < colors.length; i++) {
            renderData.push(<Circle key={i} bgColor={colors[i]}/>)
          }
          
          return renderData;
        }
        
        ReactDOM.render(
          <div>
            {showCircles()}
          </div>
          , destination
        );
      </script>
    </body>
    
    </html>