Learning React(4. React 상태 다루기)

min seung moon·2021년 7월 29일
0

Learning React

목록 보기
4/15

1. 상태 다루기

  • 동적으로 데이터를 활용하기 위하여 데이터를 저장하는 것이 상태(State)이며 props 처럼 부모에게 전달 받는 것이 아닌 보존을 한다

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/babel-standalone@6.15.0/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 함수를 사용해 1,000밀리초(1초)마다 어떤 카운터 코드를 호출할 것이다
    • componentDidMount
      • 이 메소드는 컴포넌트가 렌더링(또는 마운트)된 후에 실행
    • setState
      • 이 메소드는 state 객체의 값을 갱신할 수 있게 해준다

-1. 초기 상태(state) 값 설정

  • strikes state 변수 선언
<!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/babel-standalone@6.15.0/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. 타이머 가동과 상태 설정

  • 타이머를 시작시키고 strikes 속성 값을 증가시킬 차례다
  • setInterval 함수를 사용해 strikes 속성을 매초마다 100씩 증가 시켜준다
  • 실행은 렌더링 직후에 실행되어야 하기에 componentDidMount 메소드를 활용한다
<!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/babel-standalone@6.15.0/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/babel-standalone@6.15.0/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/babel-standalone@6.15.0/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. 배열 다루기

  • 항상 수작업으로 컴포넌트를 지정하는 것은 쉽지 않은 일이다

  • 그렇기에 배열이나 그와 같은 계열(Iterator 등)을 활용하면 좋다
<!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/babel-standalone@6.15.0/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>


profile
아직까지는 코린이!

0개의 댓글

관련 채용 정보