3주차는 리액트 입문 주차였으며, ToDoList를 직접구현하는 개인프로젝트 과제가 있었다. 개인 과제를 수행하기 위해 필요한 리액트에 대한 기본 학습과 자바스크립트 메소드에 대해서 공부했다.
공부한 내용
1. DOM
1) DOM(Document Object Model)이란?
브라저를 통해 웹사이트에 들어가면 그 하나하나를 담고 있는 요소들을 elements라고 부르며, 그 elements들을 포함하고 있는 것을 Document라고 한다.
DOM이란 html에 들어있는 요소들을 트리 형태로 표현한 것을 말한다.
2) DOM 조작
api(getDlementById(), querySelector())
등을 통해서 DOM구조 안에 있는 element에 접근해서 원하는 대로 내용, 스타일, 레이아웃등을 수정할 수 있다.
3) 가상 돔이란?
- 실제 돔과 같은 내용을 담고 있는 복사본으로 자바스크립트 객체 형태로 메모리에 저장되어있다. 하지만 실제 돔과 달리 브라우저에 있는 문서에 직접 접근을 할 수 없고, 화면에 보여지는 내용을 직접 수정할 수 없다.
4) 실제 DOM 조작
- 웹 페이지를 수정하고 싶다면 자바스크립트 코드를 짜서 돔의 내용을 수정시킬 수 있다.
- 매번 돔을 조작할 때마다 화면을 새로 그려주는 작업은 비효율적이다.
5) 가상 돔이 필요한 이유
- 비효율적인 DOM 조작을 효율적으로 만들어준다.
6) 리액트는 어떻게 가상돔을 활용하여 실제돔을 조작하는가?
- 리액트는 2개의 가상돔을 가지고 있다.
- 첫번째는 렌더링 이전 (화면 구조를 나타내는 가상돔)
- 두번째는 렌더링 이후에 보이게 될 화면 구조를 나타내는 가상돔이다.
state가 변경될 때마다 화면이 렌더링 된다. 이때 리엑트는 첫번째와 두번째를 비교해서 실제 변경이 일어난 부분을 찾아내고 실제 DOM에 반영시켜준다. Diffing
이라고 부른다.
즉 딱 바뀐 요소들만 실제 브라우저 화면에 적용시켜준다. (= 재조정 reconciliation
)
2. 서버리스
1) 서버리스란?
- 클라우드 컴퓨팅의 모델 중 하나로 사용자가 서버를 직접 관리할 필요가 없는 모델이다.
- 서비리스라고 해서 서버가 없는 것이 아니다!
- 즉 클라우드 컴퓨팅 기법과 기술을 기반으로 애플리케이션을 구축, 실행, 개선을 클라우드 제공업체에 맡긴다.
- 서버리스 모델에도 서버가 존재하지만 일반 애플리케이션 개발에서와는 달리 추상화 되어있다.
- 개발자는 배포를 위해 코드를 컨테이너에 패키징하면 된다.
- 서버리스는 동적으로 서버의 자원을 할당한다.
- 사용자가 없다면 자원을 할당하지 않고 대기하다가 요청이 들어오면 자원을 할당해서 요청을 처리하고 다시 대기상태로 들어가게 된다. → 자원을 효율적으로 사용할 수 있다.
- 대기상태를 제외한 실제 사용 자원에 대해서만 비용 청구가 되므로 경제적이다.
- 기존 클라우드 컴퓨팅 모델에 비해 경제적이고 가용성이 좋은 모델이 서버리스이다.
2) 서버리스의 구분 (FaaS와 Baas)
FaaS와 BaaS의 차이는 직접 백엔드를 구현했는지 아닌지의 차이이다.
3) 서버리스 장점
- 가격
- 실제 사용량에 대해서만 비용이 청구되므로 경제적이다.
- 애플리케이션의 품질에 집중 가능
- 서버에 신경 쓰지 않아도 되므로 사용자는 개발하는 애플리케이션의 품질 향상에 더 집중할 수 있다.
- 높은 가용성과 유연한 확장
- 요청이 들어올때만 실행되고 동적으로 자원을 할당하기 때문에 가용성이 높고 스케일링에 신경쓰지 않아도 된다.
4) 단점
- Cold Start
- 서버가 항시 요청에 대기하고 있는 것이 아니라서 laaS, Paas등의 모델보다 느리다.
- 프로젝트 규모가 커지거나 속도를 요구하는 프로젝트라면 서버리스는 좋은 선택이 아닐 수 있다.
- 클라우드 제공 플랫폼에 종속적
- 서버리스는 애플리케이션 구조 자체를 바꾸기 때문에 다른 플랫폼으로 이전하는 것이 어렵다.
- 사용중인 플랫폼의 가격, 정책 서비스 변경에도 민감하게 반응해야 함을 의미한다.
- 긴 시간을 요하는 작업에 불리
- 서버리스는 단순 작업에는 적합하지만 긴 시간을 요하는 작업(동영상 업로드, 데이터 백업 등)에는 비효율적이다. → 서버리스는 함수가 1회 호출 될 때 사용할 수 있는 메모리 및 시간에 제한이 있기 때문
- 작업이 끝나지 않은채로 해당 시간이 지나면 작업이 끝날때까지 일정 시간마다 계속 함수를 호출하므로 비효율적이다.
2. 리액트 스터디
리액트 Hooks 중 하나인 useState를 이용해서 투두리스트를 구현하기 위해 필요한 개념들에 대해 학습했다.
- 리액트 라이프 사이클
- 리액트 컴포넌트
- React.Fragment
- Props와 State
- 양방향 바인딩
- 리액트 Hooks - useRef, useState
- 리액트 가상돔(Virtual DOM)
- JSX
- SPA, MPA 방식 차이
- 리액트 map 메서드 사용시 key사용
- export, export default, import 차이점
3. 자바스크립트 스터디
투두리스트를 구현하는데 있어서 필요하거나 그 외의 추가적으로 알고 있어야 하는 자바스크립트 개념에 대한 스터디를 진행하였다. 공부를 했음에도 불구하고 적용을 시키거나 응용을 할 때 어려움을 느껴서 개념적으로 제대로 숙지가 안되어있다고 판단되어 다시 공부했다……..!!
- [JavaScript] 생성자 함수
- [JavaScript] 구조분해 할당
- [JavaScript] 전개 연산자
- [JavaScript] 콜백
- [JavaScript] e.target
- [JavaScript] callback 함수
- [JavaScript] 일반 함수
- [JavaScript] 화살표 함수
- [JavaScript] this
- [JavaScript] 동적으로 key 변경시키기
- [JavaScript] 유사배열과 배열의 차이
- [JavaScript] filter
- [JavaScript] map
4. [개인프로젝트] ToDoList
1) 구현한 기능
- [ToDo] 임의의 데이터를 만들어서 리스트로 화면에 렌더링
- [ToDo] 할 일 등록하기
- [ToDo] 할 일 삭제하기
- [ToDo] 할 일 상태(완료, 취소) 체크
2) 해당 기능을 구현하는데 있어서 꼭 알고있어야 하는 개념
- 전개연산자
- map 메서드
- filter 메서드
- 구조 분해 할당
- 리액트 훅(useState, useRef)
- 리액트 라이프사이클
3) 최종 완성
- 많이 부족하지만 일단 기능 구현에 초점을 맞췄다
- 더 열심히 해서 디벨롭 시켜봐야겠다!
5. 배운점, 어려웠던 점
1) useState 돌아가는 원리
- useState에 대해 잘못 이해한 것을 바로잡기 위해서 많은 시간을 할애해서 이해하고자 했다.
- useState로 상태가 업데이트 될 때 setState가 state를 변경시키는 것이라고 잘못 생각하고 있었다. state는 const로 선언되어 있기 떄문에 setState가 값을 변경시키는 것이 아니다. setState 호출 로직 이후 콘솔 로그로 확인해보면 state의 값은 이전과 동일함을 확인할 수 있다. 즉, 변경된 값이 반영되는 것은 다음 컴포넌트 함수가 실행될 때 useState로 가져오는 것이다.
- 즉 setState 함수는 자신과 함께 반환된 변수를 변경시키는 것이 아닌 다음 useState가 반환할 react 모듈의 _value를 변경시키고 컴포넌트를 리렌더링 시키는 역할을 한다.
2) useState 사용시 const를 사용할 수 있는 이유
- useState로 상태가 업데이트 될 때 const로 선언한 state값이 변경되는 것이 아니라 리렌더링이 일어나게 되고 state는 항상 최신 상태 값을 사용하기 때문이다.
- 정리하자면! const를 사용하는 이유는 값의 변화를 react가 아닌 다른 곳에서 관리하고 있기 때문이라고 한다!
3) 전개연산자 - 리액트 불변성 지키기
- 불변성 지키기란 리액트는 화면 리렌더링을 결정할 때 state의 변화를 확인한다. state가 변하면 리렌더링을 수행한다. 배열이나 객체를 새로 생성해서 새로운 참조값을 만들고 상태를 업데이트 하는 행위가 불변성을 지켜주는 것이다.
- 만약 데이터를 수정할 때 불변성을 지켜주니 않고 직접 수정을 한다면 값은 바뀌지만 메모리주소는 변함이 없게 되고, 상태 변경 전 메모리 주소와 상태 변경 후 메모리 주소를 비교해야 하는데 메모리 주소가 그대로인 상태에서 값만 변경돼서 비교를 할 수 없게 되고 값은 변했지만 state가 변했다고 인지하지 못하기 때문에 리렌더링이 일어나지 않는다.
- 배열을 setState할 때 불변성을 지켜주기 위해서 전개 연산자를 활용한다.
- 전개연산자를 활용하면 기존의 값을 복사해서 수정하도록 구현할 수 있고 불변성을 지킬 수 있다.
4) 전개연산자는 값을 바꿀 때만 활용하면 되는 것인가?
- 이전데이터와 바뀐 데이터를 비교해서 진짜 DOM으로 올려주는 과정에서 필요하다. 근데 데이터의 특정 값이 바뀌지 않았거나, 새롭게 등록된 것이 아니라면 굳이 전개연산자를 활용해서 같은 데이터를 복사해서 사용하지 않고 setState 시켜주면 된다.
5) 리액트에서 map 사용시 key props를 넣어주는 이유?
- key는 리액트가 어떤 항목을 변경, 추가, 삭제할 지 식별하는 것을 돕는다. 즉 key는 다른 항목들 사이에서 고유하게 식별할 수 있게 해준다. key를 사용하면 리액트에서 컴포넌트 배열을 랜더링했을 때 각 원소에서 변동이 있는지 식별하기 위해 사용한다. 만약 key가 없다면 리액트 가상돔을 비교하는 과정에서 배열을 순차적으로 비교하면서 변화를 감지해야 한다. 하지만 key가 있으면 이 값을 통해서 변화를 빠르게 알아낼 수 있기 때문에 리액트 성능이 최적화된다.
6) map과 filter 함수
- map과 filter 함수를 개념적으로는 이해를 했는데, 이를 제대로 활용할 줄 몰랐다. 개념이 제대로 잡혀있지 않다고 판단했고 map과 filter 함수의 차이점과 이를 제대로 활용하기 위해서 예제 코드를 작성해보면서 map과 filter 함수가 돌아가는 과정을 제대로 이해하고자 했다. 내가 이해한 바로 filter는 조건에 만족하는 데이터만 뽑아내서 그 순서를 그대로 지켜서 조건에 만족하는 새로운 배열, 객체 형태로 리턴시켜주는 것이고, map 함수는 for문 처럼 여러 가지 값을 뽑아내고자 할 때 사용하면 좋을 것 같다.
7) 해야할 일과 완료 한 일 상태를 확인해서 화면에 렌더링 하는 부분에서 어려움을 겪었다.
- 해야할 일, 완료한 일을 구분시켜서 렌더링 해주는 부분에 filter로 isDone이 true인지 false인지 판별하고 map 함수를 사용하여 데이터들을 리스트를 뿌려주는 자식 컴포넌트로 보내면 해결되는 문제였다.
3주차 리액트 입문을 마치며
처음 투두리스트 개인 과제를 만들어야 할 때는 제공받은 기본 강의만 잘 들으면 해결할 수 있다고 생각했다.
그래서 리액트 라이프사이클, useState 등 기본 개념을 정리 및 학습하고 가장 기본적인 예제인 counter 프로그램도 만들어보았다. 하지만 강의 내용을 토대로 개인 투두리스트를 만드는 것에 있어서 응용시키는 부분에서 어려움이 많았고 스스로도 응용력이 부족하다고 생각했다.
그래서 혼자서 무조건 해결하려고 하기 보다 구글링의 도움을 받아서 문제를 해결할 수 있었다. 특히 내가 작성한 코드가 아닌 구글링을 통해 도움을 받은 코드들은 하나씩 다 뜯어보며 이해하고 싶은 욕심이 생겼다.
코드를 뜯어보며 이해하는 과정에서 자바스크립트 자주 사용되는 메서드, 리액트 라이프 사이클, 리액트 훅 특히 useState 구조, 전개연산자 등등 많은 학습자료를 찾아보며 이해하고자 노력했다.
코드를 뜯어보고 이해하려고 노력함으로써 투두리스트의 구조가 어떻게 진행되고, 어느 기능에서는 무엇을 사용해야 하는지, 어떤 구조로 투두리스트가 구현되는지 큰 흐름을 파악할 수 있었던 시간이었다.
그런 점에서 이해를 할 때 얕고 쉽게 하는 것이 아니라, 좁고 깊게 이해하는 방법을 배웠고 또 모르는 부분에 대해서 이해하기 위해 필요한 다른 개념들까지도 찾아보고 공부하면서 개념들에 대해서는 많이 이해하고 공부할 수 있었던 시간이었다.
무엇보다 알고 있는 것과 모르고 있는 것을 확실하게 파악할 수 있었고 어떻게 보완해야하는지도 스스로 더 탐색할 수 있었다.
아쉬웠던 점
개인적인 공부는 이것저것 많이 구글링도 해보고 찾아봤다고 생각했는데, 오히려 너무 혼자서만 해결하려 하지 않고 막히는 부분들을 적극적으로 팀원분들과 공유하고 기술 매니저님께 적극적으로 물어봤더라면 더 효율적으로 명쾌하게 문제를 해결할 수 있지 않았을까 하는 아쉬움이 들었다. 그래서 내가 모르고 있는 것을 팀원분들, 기술매니저님들과 적극적으로 소통하면서 문제를 해결하고, 나또한 내가 어려웠던 부분이지만 해결한 것들에 대해서 팀원들과 더 소통하고 공유했더라면 서로에게 더 많은 도움이 됐을 것 같다.
참고 자료