CEOS FE Study 2주차
0. Web 2.0
1. 리액트는 왜 개꿀인가
버튼 클릭 시를 카운트하는 간단한 프로그램을 작성하고자 한다. 이를 Vanilla JS와 React JS로 작성하였을 때를 비교하여 보자.
1.1. Vanila JS
- HTML로 버튼을 만든다.
- HTML의 해당 버튼을 찾기위한 class 혹은 id를 명시한다.
- JS에서 해당 버튼을 찾는다. (getElementById, querySelector)
- 이벤트를 등록한다. (addEventListener)
- 데이터를 업데이트 한다.
- HTML을 업데이트 한다.
HTML -> JavaScript -> HTML
...
<body>
<h1>Total clicks: 0</h1>
<button id="btn">Button</button>
</body>
<script>
const h1 = document.querySelector('h1');
const btn = document.getElementById('btn');
let cnt = 0;
const handleClick = () => {
++cnt;
h1.innerText = `Total clicks: ${cnt}`;
};
btn.addEventListener('click', handleClick);
</script>
...
1.2. React JS
JSX
- JavaScript를 확장한 문법이다.
- HTML에서 사용한 문법과 흡사한 문법을 사용해서 React Element 제작을 돕는다.
Babel
- JSX로 작성한 코드를 브라우저가 이해할 수 있는 형태로 코드를 변환해준다.
React JS
- HTML로 버튼을 만든다.
- 이벤트를 등록한다.
- 데이터를 업데이트 한다.
- rerendering 한다. (useState 사용 시 UI를 업데이트하면 자동으로 rerendering 해준다.)
JavaScript -> HTML
...
let cnt = 0;
const cntUp = () => {
++cnt;
// render()
};
const App = () => (
<div>
<h1>Total clicks: {cnt}</h1>
<button onClick={cntUp}>Button</button>
</div>
);
...
이때 발생하는 문제는 다음과 같다.
- cnt는 갱신되고 있지만 UI가 refresh 되지 않는다. (eventListener는 동작)
- 이것은 UI를 refresh하는 (rerendering) 코드가 없기 때문이다.
useState
- React JS 내에서 변경되는 데이터를 보관(변수X)하고 자동으로 rerendering할 수 있는 방법이다.
- 데이터가 변경될 때마다 컴포넌트를 rerendering하고 UI를 refresh한다.
- set 함수를 통해 state를 변경할 때 컴포넌트 전체가 재생성되지만 오로지 변경된 내용을 부분적으로 rerendering한다. (prev. state를 React JS에서 추적하고 있기 때문)
- 현대의 interactive한 App은 많은 event를 감지하고 처리해야 한다. 이때 React의 장점은 극대화 된다.
...
const App = () => {
const [cnt, setCnt] = React.useState(0);
const onClick = () => {
setCnt((cur) => cur + 1);
};
return (
<div>
<h1>Total clicks: {cnt}</h1>
<button onClick={onClick}>Click me</button>
</div>
);
};
...
2. 컴포넌트 단위 설계
Props
- 부모 컴포넌트로부터 자식 컴포넌트에 데이터를 보낼 수 있게 해주는 방법이다.
- 부모 컴포넌트의 state가 변경될 때 자식 컴포넌트도 refresh된다.
Prop: 컴포넌트를 사용하는 외부자를 위한 데이터
State: 데이터를 만드는 내부자를 위한 데이터
Component
- 리액트는 사용자 정의 태그(컴포넌트)를 만드는 기술로도 이해할 수 있다.
- JS, CSS를 컴포넌트 단위의 모듈로 분할하면 reusability, 유지보수성, 분할정복, 코드 가독성 등을 용이하게 하고, encapsulation, abstraction 등 객체지향 프로그래밍의 장점을 극대화 할 수 있다.
2.1. React로 사고하기
공식문서
Prop: 컴포넌트를 사용하는 외부자를 위한 데이터
State: 데이터를 만드는 내부자를 위한 데이터
https://ko.reactjs.org/docs/thinking-in-react.html
과제 시연
https://react-todo-15th-six.vercel.app/
1단계: UI를 컴포넌트 계층 구조로 나누기
-
모든 컴포넌트(와 하위 컴포넌트)의 주변에 박스를 그리고 그 각각에 이름을 붙인다.
-
하나의 컴포넌트는 한 가지 일을 하는게 이상적이다.
-
컴포넌트를 확인하고 이를 계층구조로 나열한다.
- App
- TodoList
- TodoItem
- TodoInsert
- TodoList
2단계: React로 정적인 버전 만들기
-
props 를 이용해 데이터를 전달해준다.
-
정적 버전을 만들기 위해서는 state를 사용하지 않는다.
-
간단한 예시에서는 보통 하향식으로 만드는 게 쉽지만 프로젝트가 커지면 상향식으로 만들고 테스트를 작성하면서 개발하기가 더 쉽다.
3단계: UI state에 대한 최소한의 (하지만 완전한) 표현 찾아내기
변경 가능한 state의 최소 집합을 생각해보아야 한다. 여기서 핵심은 중복배제원칙이다.
예를 들어 TODO 리스트를 만든다고 하면, TODO 아이템을 저장하는 배열만 유지하고 TODO 아이템의 개수를 표현하는 state를 별도로 만들지 마세요. TODO 갯수를 렌더링해야한다면 TODO 아이템 배열의 길이를 가져오면 됩니다.
- 어떤 것이 state가 되어야 할까?
- 부모로부터 props를 통해 전달되는가? 그러면 확실히 state가 아니다.
- 시간이 지나도 변하지 않는가? 그러면 확실히 state가 아니다.
- 컴포넌트 안의 다른 state나 props를 가지고 계산 가능한가? 그렇다면 state가 아니다.
// App.js
const [todos, setTodos] = useState([
{
id: 1,
text: 'Todo 1',
isDone: false,
},
{
id: 2,
text: '할 일 2',
isDone: true,
},
{
id: 3,
text: 'long input test long input test long input test',
isDone: false,
},
]);
// TodoInsert.js
const [value, setValue] = useState('');
4단계: State가 어디에 있어야 할 지 찾기
- React는 항상 컴포넌트 계층구조를 따라 단방향 데이터 흐름을 따른다.
- 어떤 컴포넌트가 state를 변경하거나 소유할지 찾아야 한다.
- state를 기반으로 렌더링하는 모든 컴포넌트를 찾는다.
- 공통 소유 컴포넌트 (common owner component)를 찾는다. (계층 구조 내에서 특정 state가 있어야 하는 모든 컴포넌트들의 상위에 있는 하나의 컴포넌트).
- 공통 혹은 더 상위에 있는 컴포넌트가 state를 가져야 한다.
3. Key Question
Virtual-DOM은 무엇이고, 이를 사용함으로서 얻는 이점은 무엇인가요?
DOM은 HTML과 자바스크립트를 이어주는 공간으로, 내가 작성한 HTML을 자바스크립트가 이해할 수 있도록 객체(object)로 변환하는 것이다.
브라우저가 HTML을 전달 받으면, 곧 이를 변환(파싱)하고 노드들로 이루어진 DOM 트리를 만든다. 그 후, 외부의 CSS 파일과 각 노드들의 inline 스타일을 파싱하여 스타일을 입힌 Render 트리를 만든다. Render 트리가 만들이지면, 각 노드들이 화면에서 정확히 어디에 나타나야 하는지에 대한 위치가 주어진다. 그 후, paint() 메서드를 호출하면 내가 구현하고 싶었던 화면이 출력된다.
DOM은 해당 과정을 계속 반복한다. 즉, 오타 수정, 문구 제거 혹은 이미지를 첨부하는 사소한 일을 하더라도, DOM은 처음부터 다시 HTML을 파싱하여 DOM 트리를 만들고 CSS를 파싱하여 Render 트리를 만들고, 레이아웃을 입혀 출력한다. 이로인해 발생하는 비효율을 개선하기 위해 Virtual Dom이 제시되었다.
Virtual Dom은 수정사항이 여러 가지 있더라도, 가상 DOM은 한 번만 렌더링을 일으킨다. Virtual DOM은 DOM이 생성되기 전, 이전 상태 값과 수정사항을 비교하여 달라진 부분만 DOM에게 한 번에 전달하여 딱 한 번만 렌더링을 진행하는 기술이다. Reference
Styled-Components 사용 후기 (CSS와 비교)
styled-components는 style이 적용된 Component를 직접 생성하기 때문에, 스타일링을 위한 코드 사용량이 줄어드는 효과가 있습니다. 또 key value의 형태가 아닌 css의 문법을 그대로 사용하기 때문에 기존 css의 사용법보다 가독성도 높습니다. Reference
+) CSS 단위 알잘딱깔센? (현재님 리뷰 코멘트)
WATCHA 개발 지식 — px | em | rem
https://medium.com/watcha/watcha-%EA%B0%9C%EB%B0%9C-%EC%A7%80%EC%8B%9D-px-em-rem-f569c6e76e66
Author And Source
이 문제에 관하여(CEOS FE Study 2주차), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@24siefil/CEOS-FE-Study-2주차저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)