본문 바로가기
PROGRAM/Script Language

[React 배워보기] 5. React의 State 개념 더 알아보기 / state의 특징과 활용 / stateful component와 stateless component

by ojava 2021. 2. 16.
반응형

뒤늦은 React 배워보기 시리즈
옛날옛적에 배워놓고 필기는 잘하면서 복습을 2년 뒤에 하는 게으르면서도 부지런한 느낌의 블로그 포스팅

간단 예제 페이지를 만들고, Component에 데이터를 전달하는 props의 특징과 사용방법을 알아봤다면 이제 또 다른 데이터 형태인 state 개념을 더 자세히 알아보고 이를 이용한 추가 실습을 해보려고 한다.

이 개념을 제대로 알아두면 페이지의 데이터를 변경할 수 있으므로 데이터 통신이 가능한, 그러니까 우리가 원하는 웹사이트 구현에 좀 더 가까워질 수 있다.

 

이전 포스팅을 안보셨다면 짠 ojava.tistory.com/182

 

[React 배워보기] 4. React를 이용한 간단 예제 페이지 만들기 / Component에 값 전달하기 / props 특징 및

뒤늦은 React 배워보기 시리즈 사실은 내가 배워놓고 복습하는 블로그 포스팅 React 개발을 위한 기초적인 개념 작성 이후, 간단 예제 페이지 만드는 과정을 공개한다. 아주 대환장 파티이므로 의

ojava.tistory.com

 

 

[React 배워보기] 5. React의 State 개념 더 알아보기 
state의 특징과 활용 / stateful component와 stateless component

 

 


Card를 이용한 state 응용 실습

 

앞에서는 bootstrap을 이용해서 예제를 구성해봤다면, 이번에는 응용 예제를 다뤄본다.

state 값 변경에 대해 테스트하기 위해서 카드 모양을 구성하고, 원하는 색상으로 바꾸는 실습을 진행해본다.
카드 구조는 색상이 나오는 square 부분과 무슨 색인지 표시해주는 label 영역으로 구성된다. 그리고 이를 Card라는 부모 컴포넌트에서 부르는 형태로 아래와 같이 만들었다.

 

카드 구조에 맞춰서 구조 생성
Card.js
Card 컴포넌트에서 호출하는 Card.css로 기본적인 디자인을 구성
Square.js
Label.js

 

위와 같이 구성하고, 앞에서 만든 App.js에 끼워넣어보자.
아니면 새로운 App.js를 구성해서 Card 태그만 넣어도 무방하다.

 

App.js

그럼 위와 같은 결과물을 만날 수 있다.

기본적인 Card 구조는 만들었으니, 이제 색상과 색상명을 보여주는 부분을 변경하는 예제를 시작해보자.

 


STATE : 자체 데이터 포함 컴포넌트

 

state를 이용해서 색상 바꾸기를 진행하기 전, state의 특징에 대해 우선 알아두고 가자.

  • 우선 state는 생성자(constructor)에서 초기화한다.
  • 또한 state에 입력된 값은 직접 변경할 수 없고 setter를 통해 변경 가능하다. (setState)
  • state를 변경하면 변경된 값을 갱신하기 위해서 뷰가 자동으로 갱신된다. (re-render)
  • 상태를 변경하기 위해서는 class component여야 한다. 

 

또한 state값을 변경/업데이트 할 때의 주의사항!

값을 변경할 때는 setter인 setState로만 업데이트 해야 한다. 그렇게 하지 않고 state값에 직접 접근하여 값을 수정하게 되면 값을 갱신하는 단계인 re-render 되지 않으므로 변경된 내용이 적용되지 않는다.

뭐든 불가능한 것은 없으니 state 값을 바꾸고 this.forceUpdate() 로 강제 re-render도 가능하지만 비효율적이다.

 

생성자를 통한 state 초기화

 

App.js에서 Card 호출하는 부분에서 색상값을 props로 전달하는 부분

 

생성자 생략한 state값 초기화 방법

 

 

그럼 이제 state 값 초기화와 값을 변경하기 위한 방법에 대해 알아봤으니, 실제로 값을 변경해보자.

최초에 선언해둔 Card 옆에 눌러주세요 라는 버튼을 만들어서, 버튼을 누르면 카드 색상과 명칭이 바뀌도록 해보자.

 

색상 변경을 위한 버튼 생성내용

button을 만들고 클릭하게 되는 경우 호출될 onclick 함수에 수행되어야 할 내용을 선언한다.

function () {
	this.setState( state: { color: "#00A744" } )
}

위의 function 내용이 화살표 함수로 간략화되어서 입력되었다.
왜 위와 같이 화살표 함수로 선언해야 하는지는 이 포스팅 마지막즈음에 다시 언급되지만, 반드시 화살표 함수로 선언하거나 별도 함수로 선언한 내용으로 호출해줘야 한다.

내용을 살펴보면 setState 함수를 이용해서 state 값을 바꾼다.
state는 object 방식이므로 변경 시에도 object 방식으로 값을 지정해줘야 한다.

 

버튼을 클릭하게 되면 아래와 같이 색상이 변경된다.

위 Card 구조를 보면 다들 아시겠지만, 부모 컴포넌트에서 받아온 props를 이용해서 square 영역의 색상값과 label 영역의 텍스트값을 세팅하고 있다.

 

 

반응형

 


STATEFUL VS. STATELESS

: 상태 있는 컴포넌트와 상태없는 컴포넌트

 

바로 앞 포스팅에서 props와 state를 설명하면서 상태값이 없는 컴포넌트(stateless component)와 상태값이 없다는 것이 무엇을 의미하는 지 미리 썼었다.

  • 자기 자신이 데이터를 가지고 있지 않다.
  • 외부에서 데이터 (props) 를 받아서 처리하는 것
  • 대부분의 사이트 자체가 DB 등으로부터 (외부로부터) 데이터를 가져와서 처리
  • 입력값 = 출력값

 

이런 특징을 고려했을 때, 컴포넌트를 만들 때 고려해야 할 화면별 특징에 대해 아래와 같이 정리해본다.

구분 함수형 컴포넌트 (Functional Component) 클래스형 컴포넌트 (Class Component)
상태 (state) 상태값이 없는 경우에 적합
간략한 화면 구성으로 성능 향상 가능
상태를 포함해야 할 때 적합
State의 생명주기 (life-cycle) API 사용 가능
속성 (props) 부모 컨테이너에서 전달받은 값 사용 가능 부모 컨테이너에서 전달받은 값 사용 가능
추가로 default값이나 propType 등 지정 가능

 

클래스 컴포넌트에서 state 값을 사용하지 않을 수는 있어도, 만약 state값을 사용해야 하는 경우는 반드시 클래스 컴포넌트로 선언해야 한다. 그래서 클래스 컴포넌트(class component)는 stateful component라고 불리기도 한다.

반면 state를 사용하지 않는 functional component는 stateless component로 불리기도 한다.

state도 사용하지 않고 값 변화에 따른 re-rendering 및 state life-cycle 관리도 하지 않기 때문에 더 가벼운 함수형 컴포넌트(functional component)의 경우, 코드도 간결해지고 데이터도 받아와서 사용하는 단순화된 형태이므로 stateful component보다 성능 향상을 기대할 수 있다.

 

 


추가로 알아두면 좋은 것들

 

1) CSS 스타일 적용 방식

첫 예제 만들 때, 기본적인 inline style 지정했을 때 오류가 났었다.
React에서 CSS 스타일을 지정하기 위해서는 크게 세 가지 방식이 있다.

  1. 기존 inline 스타일은 style 속성에 {{ margin: 0 auto, width: 100% }} 처럼 대괄호 2개로 묶어서 지정
    여러 개의 스타일은 세미콜론이 아닌 콤마로 구분한다.
  2. 백틱 (`) 을 사용해서 css 스타일을 바로 지정할 수도 있다.
    https://www.styled-components.com/ 참고
  3. 스타일을 객체로 지정하거나 변수로 지정하기도 해서 className의 값으로 지정한다.

 

2) React의 이벤트 처리 방식

Synthetic Event

  • 리액트는 DOM 이벤트를 한 번 더 감싸서 React만의 방식으로 처리
  • 다른 브라우저에서도 동일한 속성을 사용하기 위한 방식
  • 기존 HTML의 onclick => onClick 으로 아주 약간 바꿔서 사용됨

 

3) 함수 선언 방식

위 Card 색상 바꾸기를 위한 눌러주세요 버튼에 추가했던 onClick 함수 선언방식을 보면 function을 생략하고 화살표 함수로 정의해두었다.
기존에 선언하던 방식대로 선언한다고 하면 아래와 같이 선언할 수 있는데 아래와 같이 선언하면 scope 문제로 에러가 날 수 있다고 한다.

<button onClick={
	function () {
		this.setState… // 이런 식으로 선언하면 scope 문제로 에러가 남

 

만약 위처럼 바로 선언하는 방식이 아니라 이벤트 함수를 별도 정의하려고 한다면?

기존에는 function 펑션명 () { ... } 이런 형태로 선언했겠지만, function은 생략하고 펑션명 () 만 쓴다.

 

호출할 때도 주의할 점! 괄호를 습관적으로 붙일 수도 있는데, 호출시에는 펑션명만 사용한다.

 

그리고 이벤트 함수를 별도 정의하는 경우도, 아래와 같이 화살표 함수로 정의하는 것을 권고한다.

 

또한 일반 함수로 정의하는 경우에는 this 를 인식하지 못함.
함수 내부의 this를 찾기 때문에 원하는 내용을 찾아오지 못하므로 아래와 같은 에러를 만날 수 있음

일반 함수에서의 this.setState 호출 시 에러, this를 참조하지 못한다.



굳이 일반 함수로 지정한 내용에서 클래스 단위의 this를 써야하면 바인딩을 해줘야 한다.

클래스 컴포넌트에서 선언하는 생성자(constructor)에서 일반 함수에서 참조할 this에 대해서 바인딩 처리를 진행해주면, this.setState 형태로 값을 변경할 수 있어진다. 

class listenerChecker extends React.Component {
	constructor(props) {
    	super(props);
        
        this.state = {
        	listener: 0
        };
        
        this.addCount = this.addCount.bind(this);
    }
    
    addCount(e) {
    	this.setState({
        	listener: this.state.listener + 1
        });
    }
    
    .
    .
    .

 

 

뒤늦게 작성한 React 배워보기 시리즈가 어느덧 기초 단계가 끝나간다.
React에서 State 개념은 중요하므로 특징에 대해 잘 알아두면 좋고, state 사용여부에 따라 컴포넌트 생성 방식을 결정하는 것이 향후 성능면에서도 차이를 줄 수 있으니 초기 설계단계에서도 잘 정하는 것이 좋겠다.

물론 언제나 리팩터링 하면 그만이지만, 처음부터 잘 만들어두면 깔끔하니까!

 

다음 내용은 컴포넌트의 생명주기 life-cycle과 실제 데이터 통신에 대한 내용을 다뤄볼 예정이다.

 

반응형