본문 바로가기

MINIBEEF/REACT

#7 React 졸업하기(A to Z)


0. React 짱짱맨

 React는 페이스북(facebook)에서 제공하는 프런트엔드 라이브러리이다. JSX가 기본이 되며, 컴포넌트 기반의 개발을 도와준다. 사실 React가 없

 

더라도 우리는 HTML, CSS, JS등 이미 잘 알려진 도구를 활용해 웹페이지를 만들 수 있다. 하지만 사람들이 왜 그토록 React에 열광하는 것일까? 그 

 

이유는 React의 특징과 이것이 없을 때와 있을 때 편의성을 비교해보면 쉽게 알아차릴 수 있다.

 

 React는 앞서 말했듯이 컴포넌트라는 것을 이용해 UI를 만들어 나간다. UI가 큰 덩어리 라고 가정하면, 컴포넌트는 이 큰 덩어리를 이루고 있는 작은

 

덩어리들이라고 생각하면 쉬울 것 같다. 즉, 우리가 웹 사이트를 볼 때 만약 그것이 React로 짜여있다면 내비게이션 바, 로그인 버튼, 게시물, 글 목록

 

등등 하나의 기능을 맡고 있는 작은 덩어리들이 컴포넌트가 된다는 것이다. 그렇다면 프런트엔드를 이런 식으로 만들면 좋은 점은 무엇일까?

 

1) 가독성의 향상과 유지보수

 개발자가 React를 썼을 때 가장 먼저 느낄 수 있는 장점은 바로 "가독성의 향상"이 아닌가 싶다. React가 아닌 프론트엔드 라이브러리들(Vue.js 등

 

등)도 사실 가독성을 높이는 장치가 설계되어있지만 개인적으로는 React의 가독성은 이중 가장 우수하다고 생각한다. 왜냐하면 React 코드를 짤때

 

나 오류를 고치기 위해 내가 짠 코드를 다시 볼 때, UI가 마치 레고 블록처럼 긴밀하게 연결되어있기 때문에 코드를 따라가다가 놓칠 일이 없다.

 

예를 들어 내가 만든 사이트에서 내비게이션 바에 어떤 문제가 생겨서 이를 고쳐야 한다고 생각해보자.

 

 

 만약 이 내비게이션 바가 메인 화면, 글 목록, 로그인 화면 등 모든 곳에서 사용되며 각각의 HTML 코드에 내비게이션 바의 코드를 복사 붙여 넣기 해

 

놓았다면? 아마 우리는 모든 페이지 HTML 소스를 들어가 일일이 고치고 테스트를 해야 할 것이다. 또한 그 기다란 HTML 코드 속에서 내가 원하는

 

(고치고자 하는) 코드가 어디에 있는지 찾아야 하며, 내가 코드를 수정하더라도 이것이 다른 요소들에 간섭이 없도록 해야 한다(내비게이션 바 옆에

 

있던 버튼이 갑자기 사라진다.. 이런 거) 하지만 React로 짜여진 코드였다면 그냥 NavigationBar.js 소스를 찾아서 필요한 부분만 쓱싹 고쳐주면 나

 

머지는 리액트가 알아서 해준다. 원래부터 내비게이션 바는 그저 레고 블록의 일부분인 것처럼 큰 덩어리에 맞추어져 있었기 때문이다.

 

 

 사실 React의 강점은 너무너무 많지만 내가 가장 마음에 드는 부분이 이것이다. SI 업체던 아니면 일반 개발하는 회사던 게임을 만드는 회사던 간에

 

어떤 서비스(여기서는 웹을 이야기 하지만 게임, 어플 등도 똑같다)를 만들면 사실 이를 개발하는 시간보다 서비스의 삶을 연장시키는 작업 즉, 유지

 

보수를 하는 기간이 더 길것이며 실제로 최근에는 많은 사람들이 개발보다 유지보수비용(cost)이 훨씬 많이 소모된다는 의견을 내고있다. 이에 따

 

라 개발의 패러다임이 한번 개발하고 내버려 두는 것이 아닌 유지보수를 염두하는 방향으로 바뀌고 있기 때문에 React를 포함해 개발이 끝난 뒤 생명

 

주기(life-time)의 고증을 풀어낸 플랫폼들이 각광을 받는 것이 아닌가 싶다. 기업에서도 이제는 효율적으로 짜는 사람도 중요하지만 가독성 있게 짜

 

는 사람이 굉장히 중요하다는 걸 인지하는 추세이다.

 

2) 압도적인 랜더링 성능 

 내가 React를 처음 접하고 놀랐던 점은 가독성 뿐만이 아니다. React는 여러 프론트엔드 플랫폼 중에서 랜더링 성능이 뛰어나다고 평가받고 있는

 

데, 이는 서비스를 배포하는 방식에서 나온다. 우리가 React 어플리케이션을 디자인하고 개발할 때 간혹 가다 디버깅 명목으로 브라우저에 개발된

 

소스를 돌려보는데, 이 때는 랜더링 성능이 굉장히 안 좋다. 이는 React 내부적으로 랜더링 하는 과정에서 다양한 컴포넌트를 찾아가는 과정과 state

 

나 props를 적절히 적용하는 과정 등 복잡한 일이 일어나기 때문인데, 서비스를 다 만들고 이를 실제 사용자에게 배포한다면 갑자기 랜더링 속도가

 

빨라진다(디버깅할 때와 실제 서비스할 때 속도가 다르다는 것). 이런 차이는 React의 Build 때문이다. 개발자가 서비스 개발을 마치고 유저들에게

 

배포할 때 보통 프런트엔드 같은 경우 소스를 그대로 배포한다(HTML, JS, CSS를 생각해보자) 한데, React는 조금 다른 방식을 따른다. 개발을 마치

 

면, Build라는 과정을 거치고 이때 불필요한 랜더링을 싹-다 없애준다. 심지어 JS 코드는 공백도 다 지워버린다. 그렇기 때문에 실제 배포할 때에는

 

node_module이니 컴포넌트이니 하는 용량이 크고 랜더링을 느리게 하는 요소들은 완전히 배제하고 사용자들이 쾌적한 환경에서 서비스를 이용할

 

수 있도록 배포 시스템을 설계한 것이다. 앞선 1번에서 이야기한 "가독성"은 개발자를 위한 배려였지만 여기서 알아본 "랜더링" 측면은 느린 걸 싫어

 

하는 소비자들의 입장도 어느 정도 반영한 것으로 볼 수 있다. 

 

3) props와 state

 props와 state는 HTML의 Attribute와 같은 역할을 한다. 컴포넌트의 속성을 전달하고자 할 때 사용하는데, 처음에 React를 배울 때에는 왜 굳이

 

두 개를 나누어놨을까 하는 의문이 들었지만 곰곰이 생각해보니 props와 state를 분리한 것이 React가 흥할 수 있었던 이유 중 하나가 되기 충분하

 

다고 생각했다. 우선 props는 컴포넌트에서 자식 컴포넌트로 데이터를 전달하는 것을 도와준다. props는 말 그대로 읽기 전용 데이터와 같다. 자식

 

컴포넌트에서 전달받은 props를 변경이 불가능하고 props를 전달해준 최상위 부모 컴포넌트만 props를 변경할 수 있다. 즉, Java에서 접근 제어와

 

비슷한 개념이 도입된 것이다. 이로써 비록 프런트엔드 UI 개발이지만 마치 객체지향적으로 코드를 작성하는 느낌이 났고, 이를 잘 활용하면 성능은

 

물론 이를 사용하지 않았을 때는 만들 수 없는 애플리케이션들을 쭉쭉 뽑아낼 수 있다. state는 동적인 데이터를 다룰 때 사용하는데 이는 사용자에게

 

보이지 않는 부분이다. 우리가 서비스를 개발하다 보면 사용자에게는 보여서 안 되는 부분이 분명히 있다. 데이터베이스의 쿼리 라던가 다른 유저, 서

 

버와 관련된 데이터는 철저히 은닉해야 하지만 이를 만족하기 위해서 우리는 지금까지 빙빙 돌아서 코드를 썼다. 하지만 state를 활용하면 더 이상 이

 

럴 필요가 없다는 것.


1. 컴포넌트 만들어 보기

 이제 실제로 React 애플리케이션을 만들어보자. 첫걸음은 바로 아무 컴포넌트를 만들어 보는 것이다. 앞서 서론에서 설명했듯이 React의 시작과 끝

 

은 컴포넌트로 이루어지기 때문에 이는 첫걸음이지만 가장 중요한 부분이다. 컴포넌트를 만드는 방식에는 두 가지가 있는데 바로 함수형클래스형

 

이다. 나는 클래스(class) 타입을 쓸 것인데, 사실 둘의 차이는 잘 모르고 이고잉(egoing) 선생님이 시켰다. 생활코딩 만세

 

 위 코드는 클래스형으로 작성한 간단한 컴포넌트이다. 우선 클래스(class)라는 이름처럼 class를 하나 선언해주고 여기에는 Component를 상속해

 

줘야하는데 이는 위의 import 문을 참고하도록 하자. class 안에서는 render()라는 함수가 보이는데 이는 실제로 페이지에서 이 컴포넌트가 보여줄

 

부분이다(랜더링). 이 render() 함수는 호출될 때 마다 랜더링을 하게 되는데 랜더링이 적다는 React를 잘 살리기 위해서는 코딩하는 과정에서 이

 

render()가 적은 수로 불리도록 하는게 중요하다. render() 함수 외에도 constructor()라던가 다른 함수들이 많은데 이는 필요할 때마다 공식 문서

 

를 찾아보는 편이 더 좋다. 그렇게 중요한건 아니다.

 

 

 render() 내부에서는 return()의 내부에 HTML 코드가 들어가게 된다. 이 때 들어가는 코드들은 그냥 HTML이 아니라 props나 state 등으로 편의

 

에 따라 동적으로 생성될 수도 있으며  return()은 단 하나의 태그만 리턴할 수 있기 때문에 내부는 root가 하나인 DOM을 만들어야 한다.


2. props 사용

 props는 개발에서 많이들 사용되는 용어인 프로퍼티(properties)의 줄임말이다. props는 React에서는 사용자가 컴포넌트에 전달해서 보관하길 원

 

하는 데이터 즉, 컴포넌트 내에서 데이터가 보관되면, 이 데이터는 수정되지 않고 보존되어야 하는 법칙이 성립된다. 만약 props의 값을 변경하고자

 

할때에는 컴포넌트 내부가 아닌, 부모 컴포넌트에서 이에 대한 부분이 변경되어야 한다.

 

 

 아까 전 코드에서 props가 이용된 부분만 때어온 것이다. 여기서 보면 tbody 내부에는 우리가 흔히 아는 HTML의 형태가 아닌데, 이는 JSX의 문법

 

이다. 간단하게 요약 설명 해보자면, 해당 컴포넌트로 넘어온 props들 중에 articles를 뽑아와 tbody 내부에 랜더링 하겠다는 뜻이다. App.js를 보자

 

 

 위 코드는 App.js에서 Articles 컴포넌트에 props를 넘겨주는 부분만 캡쳐한 것인데, 첫번째 for문에서 articles를 가공한 뒤 Arti라는 이름

 

의 컴포넌트의 Attribute처럼 그 값을 넘겨준 것을 볼 수 있다. 여기서 articles는 글 목록인데, 글 목록이나 유저 리스트처럼 동적으로 변할

 

수 있는 사항들을 props로 전달하여 조금 더 유동적으로 랜더링할 수 있다는 것이다.


3. state의 사용

 state도 props와 별 다를게 없지만 다른 점은 유저로부터 데이터를 은닉할 수 있다는 것이다. 선언은 다음과 같이 constructor에 하면 되고, 예시의

 

경우는 contents가 글 목록에 들어갈 글들인데, 이들을 state로 설정해서 유저에게 랜더링 할 부분만 랜더링해서 보여준다. 이거는 야매로 만든 코드

 

지만 실제 코드였다면 실제 데이터베이스에서 받아오는 유저들의 JSON 데이터 정도가 될 수 있겠다.


4. Event 사용

기본적으로 state와 props의 변경은 render()의 호출을 일으킨다. 가장 기본적인 형태의 이벤트(상황에 따라 정적으로 컴포넌트를 render)는 메인

 

컴포넌트 상단의 조건문에 mode에 따른 분기(ex : welcome, read)를 만들고 매 액션마다 props(혹은 state)를 수동으로 바꾸는 것이다. 이와같은

 

방식은 매우 원시적이며 우리가 하고자 하는 Event 와는 거리가 멀다. 그렇다면 이를 사용자 액션에 따라 동적으로 만들고자 한다면 어떻게 해야할

 

까? 바로 Java Script를 이용하면 된다.

 

PreventDefault

onclick의 경우 우리가 알고있는 JS형태로 사용하면 안된다. React Application은 JSX를 기반으로 하기 때문이다.

 

JSX에서 onclick은 c를 대문자로 해서 onClick과 같이 사용하고 이를 태그의 Attribute에 부여한다.

 

 

실제로 위와같은 형태로 작성하면 링크를 클릭했을 때 정상적으로 alert가 띄워지지만 a태그의 기본적인 동작 즉, 페이지가 reload되는 기

 

때문에 alert를 닫았을 때 페이지를 다시 렌더링한다(render의 호출) 이와같은 형태로 썼을 때 리액트의 장점(랜더링의 최소화하여 클라

 

이언트의 리소스 부하를 줄이는)을 깨뜨리기 까닭에 올바르게 사용한다면 다음과 같다.

 

 

JSX에서 Event에 대한 Anonymous-Function은 첫번째 인자로 Event Instance가 올 수 있다. 이 instance의 속성  preventDefault라는 것이 있

 

는데 이는 본인을 호출하는 태그(caller)의 기본적인 기능을 방지한다. (이 경우 a태그가 페이지를 reload하는 기능)

 

Event로 State(Props) 바꾸기

서두에서 Event의 프로세스가 State나 Props를 수정하며 이루어진다고 했다. 간단하게 생각해서 위의 예제(onClick)에서 State 를 바꾸는 행위를

 

한다면 이벤트를 만들어내는 것은 굉장히 쉬운 일이다. 하지만 여기서 고려해야 할 것이 두가지 있다. 첫 번째는 해당 Anonymous-Function에

 

State를 Binding해야 한다는 것. 아래 코드를 보자

 

 

일차원적으로 생각하면 이와 같은 코드를 작성했을 때 mode라는 state가 hello로 바뀌어야 하지만 실제로는 그렇지 않다. 그 이유는 onClick에

 

서 this라는 본인 참조 객체가 누구를 가르키는지 모르기 때문이다.

 

그런 이유로 리액트를 실행하면 undefined 한 객체를 참조했다 라는 오류를 뿜어낸다. 매우 슬픈 일이다. 이러한 문제는 this를 bind 해주면 된다.

 

bind는 해당 객체를 서브 루틴에 매핑해주는 과정이라고 생각하면 된다.

 

 

function의 마지막에 bind(this)라고 명시하며 binding 해주었다. 이렇게 하면 모든 문제가 해결된 듯 하지만 이 행위에 두가지 문제가 있다고 했었

 

다. 나머지 하나를 해결해야 한다. 위와 같이 bindng을 해줘봤자 state를 바꿔도 react에서는 state가 바뀐지 모른다. 즉, 런타임에 변경되는 state

 

에 대한 대응이 되지 않은 것. 이는 리액트 공식 문서에서 알려주는 방법대로 하면 된다..-> setState({...})

 

 

 

'MINIBEEF > REACT' 카테고리의 다른 글

#6 Create 구현(~form)  (0) 2020.03.17
#5 Event  (0) 2020.03.17
#4 props와 state  (0) 2020.02.24
#3 앱 빌드  (0) 2020.02.24
#2 리액트 앱의 기본 구조  (0) 2020.02.24