React

React #3 Class Component - data 변화 인식

Sila 2022. 4. 13. 17:04

React에서 데이터가 변하면 렌더링도 바뀌어야한다.

 

그런데 데이터는 객체로 전달이 된다.

 

이 객체의 변화를 컴퓨터가 인식하도록 할 수 있어야 렌더링을 바꿀 수 있는데,

 

이 글에서는 이에 대해 몇 가지 예시를 들어 공부해보도록 한다.

 

다음과 같이 html을 작성해보자.

 

<!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>Document</title>
    <script crossorigin src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
    <div id="root"></div>
    <script type="text/babel">
        class Login extends React.Component{
            render() {
                return (
                    <button onClick={alert('clicked!')}>press this</button>
                )
            }
        }

        class App extends React.Component{
            render() {
                return (
                    <div>
                        <Login/>
                    </div>
                )
            }
        }

        ReactDOM.render(
            <App/>,
            document.querySelector('#root')
        )
    </script>
</body>
</html>

 

<App/>안에 <Login/> component를 넣고 그 안에 button element을 넣었다.

 

button element에는 click시 발동하는 알람을 세팅해두었다.

 

그런데 이 html을 브라우저에서 열어보면 클릭을 안했는데도 불러오자마자 알람이 뜨는 것을 알 수 있다.

 

이는 브라우저가 html을 그리는 과정에서 함수가 실행되기 때문이다.

 

이를 해결하려면 새 함수를 만들어서 해당하는 함수를 감싸버리는 방법이 있다.

 

함수를 선언만 된 상태로 바꿔준다고 생각하면 된다.

 

다음과 같이 <Login/> 컴포넌트를 수정해보자.

 

class Login extends React.Component{
   render() {
      return (
         <button onClick { () => { alert('clicked') } } >
            press this!
         </button>
      )
   }
}

 

이렇게 alert를 익명함수 안에 넣어주면 버튼을 클릭할 때만 실행되도록 해줄 수 있다.

 

이제 Login 컴포넌트에 변수를 하나 선언해주자. 선언되는 위치에 주의할 것.

 

class Login extends React.Component{
   state = {
      name: 'lsj'
   }
   
   render() {
      return ( 
         <button onClick { () => { alert('clicked') } } >
            press this!
         </button>
      )
   }
}

 

컴포넌트의 코드블럭 안에 state라는 변수를 선언해줄 수 있다. 

 

변수 이름은 반드시 state로 사용해야 한다. 다른 변수는 먹히지 않는다.

 

이 state라는 변수를 render의 안으로 가져오는데, 이대로가 아니라 데이터를 추가해서 가져오고 싶다.

 

이를 위해 spread 연산자를 활용해 객체의 값을 복사해온다.

 

class Login extends React.Component{
   state = {
      name: 'lsj'
   }
   
   render() {
      const obj = {
         ...this.state,
         switch: !this.state.switch
      }
         
      return ( 
         <button onClick { () => { alert('clicked') } } >
            press this!
         </button>
      )
   }
}

 

우선 state의 값을 가져온 후, 거기에 switch라는 key와 value를 추가해주었다.

 

이를 이용해 클릭시마다 값이 바뀌는 버튼을 만들 수 있다.

 

switch를 클릭시 true/false가 변하도록 , 그리고 그 값에 따라 버튼의 텍스트가 달라지도록 해보자.

 

JS라면 조건문을 사용하면 되지만 여기선 if문이 없다.

 

그 대용으로 삼항연산자를 사용한다.

 

class Login extends React.Component{
   state = {
      name: 'lsj'
   }
   
   render() {
      const obj = {
         ...this.state,
         switch: !this.state.switch
      }
         
      return ( 
         <button onClick { () => { this.setState(obj) } } >
            {this.state.switch ? 'off' : 'on'}
         </button>
      )
   }
}

주목해야 할 것은 화살표 함수 안의 this.setState( ) 함수인데, 이는 state라는 변수를 바꿔주는 함수이다.

 

그렇기 때문에 반드시 변수 명은 state여야 한 것이다.

 

이제 버튼을 클릭하면 > setState 함수가 발동해 obj의 값을 바꾸고,

 

이에 따라 true/false값이 변하면서 'off', 'on' 이 번갈아 버튼의 텍스트로 렌더링된다.

 

 

비슷한 예시로 숫자를 카운트하는 기능을 구현해보자.

 

<!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>Document</title>
    <script crossorigin src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
    <div id="root"></div>
    <script type="text/babel">
        class Counter extends React.Component{
        
           state = {
              number : 0
           }
        
           incre = (index) => {
              const increase = {
                 ...this.state,
                 number: this.state.number + index
              }
              this.setState(increase)
           }
        
           decre = (index) => {
              const decrease = {
                 ...this.state,
                 number: this.state.number - index
              }
              this.setState(decrease)
           }
           
           render() {
              return (
                 <div>
                    <h3>{this.state.number}</h3>
                    <button onClick = { () => {this.incre(1)} }>+</button>
                    <button onClick = { () => {this.decre(1)} }>-</button>
                 </div>
              )
           }
        }

        class App extends React.Component{
            render() {
                return(
                    <div>
                        <Counter/>
                    </div>
                )
            }
        }

        ReactDOM.render(
            <App/>,
            document.querySelector('#root')
        )
    </script>
</body>
</html>

 

'React' 카테고리의 다른 글

#6 Styling  (0) 2022.04.22
#5 Webpack  (0) 2022.04.22
#4 tictectoe 게임 만들기  (0) 2022.04.17
React #2 Class Component  (0) 2022.04.13
React #1 Intro  (0) 2022.04.12