[CN] React에 손가락 담가보기

곽재훈·2024년 5월 22일
6
post-thumbnail

여는 글

이 글을 리액트를 시작하는 스터디원분들을 위한 글입니다.

React에 대한 기본적인 이해가 충분하다면 바로 오은님의 가이드 글로 넘어가셔도 무방합니다.

만약 Javascript를 막 마치고 오셔서 리액트를 왜 써야하는지 잘 모르시겠다면, 여기서부터 시작하시면 됩니다.

React 시작하기

1. React를 왜 쓸까요

리액트를 사용하는 이유는 리액트가 현재 가장 유명한 프론트엔드 라이브러리 중에서 하나이기 때문일 겁니다. 다만, 이제 막 자바스크립트를 마치고 나온 저희들에게는 그 필요성이 쉽사리 공감되지 않는 부분도 있을 겁니다. 그래서 오늘 저희의 눈높이에 맞춰서 리액트와의 만남을 가져볼까 합니다.

이렇게 귀여운 카운터 앱을 만들었는데요, Click!이라는 버튼을 누르면 화면에 표시된 COUNT의 숫자가 증가하는 앱입니다.
여기에 귀여운 자바스크립트 코드를 준비했습니다. 한 번 같이 볼까요?

아래 나온 코드는 우리가 항상 작성하던 방법으로 카운터 앱을 만드는 코드입니다.

우리가 평소에 만들던 방식처럼 한 번 코드의 흐름을 따라가보죠.

먼저 HTML로 카운터 앱의 뼈대를 만들어줍니다.

<h1>MY COUNTER</h1>
<p id="counter">COUNT : 0</p>
<button id="btn">Click!</button>

그 다음 카운트의 현재 숫자를 담아줄 변수를 생성해줍니다.
변수는 계속 증가할 예정이기 때문에 let으로 선언해줍니다.

let count = 0;

그리고 counter와 btn이라는 변수에 DOM Element를 조작하기 위해서 불러와줍니다.

const counter = document.querySelector("#counter");
const btn = document.querySelector("#btn");

화면의 숫자를 증가시키기 위해서 count를 증가시키는 함수를 만들어줍니다.

function increaseCount() {
  count = count + 1;
}

화면의 숫자를 증가시킨다고 해도 화면에 그걸 반영해주지 않으면 count의 숫자가 증가해도 화면에는 반영되지 않겠죠? 그러니 화면에 숫자를 반영할 수 있도록 counter에 담긴 텍스트를 변경해주는 updateCount() 라는 함수를 선언해줍니다.

function updateCount() {
  counter.innerHTML = "COUNT : " + count;
}

마지막으로 버튼을 눌렀을 때, 미리 만들어 둔 함수들이 실행될 수 있도록 btn에 addEventListener를 추가하여 click이벤트가 발생할 때마다 increaseCount()와 updateCount()를 실행하도록 만들어주면 귀엽디 귀여운 카운터 앱이 완성됩니다!

btn.addEventListener("click", () => {
  increaseCount();
  updateCount();
});

아마도 대략 이런 형태가 되겠군요!

2. React 이야기 한다면서 갑자기 카운터는 왜...?

조금만 더 기다려 보십쇼.

우리가 방금 한 작업을 돌아볼까요?

  1. HTML 태그로 앱의 구조를 작성하고,
  2. 현재 숫자를 저장할 변수를 count라는 이름으로 만들고,
  3. counterbtn이라는 이름으로 변수를 만들어서 HTML 요소들을 선택하고,
  4. btn을 누르면 이벤트가 작동하게 하는데,
  5. 먼저 count에 담긴 값이 1 증가하고,
  6. 그걸 counter라는 변수에 담긴 HTML 요소에 넣어서 화면에 보여준다.

자 카운터 앱 하나를 하기 위해서 생각보다 필요한 작업이 많습니다.

우리가 이 작업을 HTML과 일반 Javascript가 아니라 React에서 한다면 절반 정도로 작업을 줄일 수 있는데요. 어떻게 그게 가능한 지 한 번 살펴봅시다.

3. React의 생김새

위에 있던 카운터 앱을 React로 만들기 위해서는 이렇게 작성하면 됩니다. 벌써 뭔가 가벼워진 것 같지 않나요? 물론 아직은 감이 잡히지 않으실 수도 있어요. 차근차근 하나씩 살펴봅시다.

리액트를 한 구절로 정의하라고 한다면 함수형 컴포넌트 라고 할 수 있지 않을까 싶습니다. 즉, 리액트의 핵심은 함수 입니다.

React에서 App() 처럼 되어있는 코드를 컴포넌트 라고 부르는데요. 컴포넌트는 크게 두 부분으로 나누어져 있습니다.

코드의 가장 하단부를 보시면 return 부분에 익숙한 코드들이 보이실 거에요. 네 맞습니다! 우리가 매일 보던 HTML 태그들이에요! 이제 우리는 HTML을 사용할 때 document.querySelector() 를 사용하지 않고 이렇게 직접 HTML 태그를 사용할 수 있습니다.

컴포넌트 는 다른 React 엘리먼트나 혹은 HTML 태그들을 return합니다.

윗부분은 보통 비즈니스 로직을 처리하기 위한 Javascript 코드들이 모여있습니다. 우리에게 익숙하지 않은 useState() 라는 친구도 있는데요, 이 친구는 조금 이따가 만나보죠.

리액트에서 또 하나의 장점을 뽑아보라면 바로 HTML에 직접 JS 문법을 사용할 수 있다는 점이 아닐까 싶습니다. 혹시 템플릿 문자열 기억하시나요? ${ 템플릿 문자열 } 이런 식으로 작성해서 문자열과 함께 JS의 문법을 사용할 수 있도록 해주는 기능이었는데, React에서도 마찬가지로 중괄호 { } 안에 JS 문법을 바로 사용할 수 있습니다.

그럼 이번에는 기존에 JS만으로 작성했던 코드와 현재 React에서 작성한 코드를 비교해봅시다!

코드에서 붉게 표시된 부분 을 살펴보시면 기존 JS에서는 필요했지만, React에서는 더 이상 필요하지 않아서 삭제된 코드들이 있습니다.

const counter = document.querySelector("#counter");
const btn = document.querySelector("#btn");

React에서는 return 부분에서 HTML 태그들을 직접 다루고 있죠? 기존에는 JS에서 HTML파일에 있는 태그들을 선택해서 가져와야 했지만 React에서는 그럴 필요가 없기에 위의 코드들은 더 이상 필요하지 않습니다.

function updateCount() {
  counter.innerHTML = "COUNT : " + count;
}

이 코드는 변수 count 에 담겨있는 숫자가 변경될 때, 화면에 표시되는 counter 의 숫자를 업데이트해주기 위한 코드입니다. 기존에는 이 코드가 없다면 변수인 count의 값이 증가하더라도 화면이 업데이트되지 않기 때문에 꼭 필요한 기능이었죠. 그런데 왜 React로 오면서 삭제된 것일까요?

그것은 React가 우리와 한 가지 약속을 했기 때문입니다.

React로 넘어오면서 React는 우리에게 한 가지 약속을 했습니다. 앱 내에서 변수에 저장된 값이 변경되거나 어떤 변경사항이 생길 때마다 우리가 직접 값을 화면에 업데이트 하는 게 아니라, React가 우리를 대신하여 화면을 자동으로 다시 렌더링 해주겠다는 약속입니다.

즉, 우리는 더 이상 값이 변경될 때마다 우리가 직접 화면을 조작할 필요가 없어진 것이죠. 다만, React가 우리를 도와주는 만큼 우리도 React와 한 가지 약속을 했습니다. 변경사항이 생길 때마다 우리가 직접 화면을 업데이트 하지는 않지만, 적어도 React에게 변경사항이 생겼다는 사실 을 알려주기로 한 것이죠. React가 항상 화면을 다시 그리는 것이 아니라 필요할 때에만 화면을 다시 그릴 수 있도록 말이죠.

그 첫 번째 약속이 바로 useState() 입니다.

4. React와의 약속. useState()

약속의 내용을 조금 더 구체적으로 살펴볼까요?

비약을 조금 더해서 이야기하자면, useState() 라는 함수는 우리가 React에서 변수를 대신해서 사용하기 위한 기능이라고 할 수 있습니다.

useState() 함수는 변수의 초기값 을 인자로 받아서 두 개의 요소가 담긴 배열을 반환합니다.

배열에 담긴 첫 번째 요소는 변수에 설정한 초기값 그 자체 이고, 두 번째 요소는 변수의 값을 바꿀 수 있는 함수 입니다.

우리는 이걸 state 라고 부르는데요, 이 state 라는 것은 기존에 사용하던 const 나 let같은 변수와 생김새만 다를 뿐 역할은 유사합니다.

값을 사용하고 싶을 때는 배열의 첫 번째 요소를 읽어오고, 값을 변경하고 싶을 때는 배열의 두 번째 요소를 읽어와서 함수로써 실행하면 되거든요. 그런데 왜 그냥 변수 를 사용하면 되는 것을 이렇게 구태여 복잡하게 state 라는 별도의 기능을 만든 것일까요?

그 이유는 state 의 값이 변경될 때마다 React가 화면을 다시 렌더링하기로 했다는 React와 우리 사이의 약속 때문입니다. React에게 화면을 다시 렌더링해줘야 한다는 사실을 알려주기 위해서 우리도 조금 번거롭지만 state 라는 별도의 변수를 만들어서 React와 소통하고 있다고 생각하시면 좋을 것 같습니다.

그런데 우리는 매번 count[0] 이나 count[1] 처럼 배열의 요소를 꺼내서 사용하는 게 점점 불편해졌고, 이를 편하게 사용하기 위해서 배열의 값을 받아올 때부터 각각의 변수에 할당하여 아래처럼 사용하게 되었습니다. 이렇게 하면 state 의 값이 담기는 count 와, 그 count 의 값을 변경하는 함수인 setCount 가 각각의 변수에 할당되어 더 사용하기가 용이해지는 것이죠.

const _count = useState(0);
const count = _count[0];
const setCount = _count[1];

----------------------------

const [count, setCount] = useState(0);

물론 이 글은 비유와 비약이 포함되어 있기에 리액트에 대한 개념서로는 충분하지 않으나, React를 왜 사용해야 할 지 고민이 되신다면 도움이 되시지 않을까 생각해봅니다.

5. 이후에 생각해 볼 것들

React와 우리의 약속은 useState() 외에도 많은 것들이 존재합니다.
밑의 그림들을 참고해서 앞으로 무엇이 필요할 지 한 번 고민해보면 좋을 것 같습니다.



profile
개발하고 싶은 국문과 머시기

5개의 댓글

comment-user-thumbnail
2024년 5월 22일

어떻게 다시 쓰실수가 있죠...???

답글 달기
comment-user-thumbnail
2024년 5월 23일

똑 ! 똑 ! 복습하고 갑니다

답글 달기
comment-user-thumbnail
2024년 5월 24일

너무 대단해요 짱짱

답글 달기
comment-user-thumbnail
2024년 6월 4일

왜 리액트가 필요한지에 대해 잘 보여주는 글인 것 같습니다

읽다보니 코드 내 오타를 발견했어요!

const _count = useState(0);
const count = count[0]; // ⛑️_count 가 맞는 것 같습니다
const setCount = count[1]; // ⛑️_count 가 맞는 것 같습니다

1개의 답글