

왼쪽상단에 있는 파랑 연필이모지를 클릭하면 TODO를 입력할 수 있는 공간을 만들 수 있다.

해당 공간에서 입력하면 입력이 된 것을 경고창을 통해서 사용자가 확인할 수 있도록 해주었다. 여기에 더해서 TODO를 입력하기 위해서 들어온 공간이지만, 입력하기 싫어졌다면 왼쪽상단에 있는 빨강 연필이모지를 클릭하면 본래의 화면으로 돌아갈 수 있다.

Edwin의 할일 목록에 내용이 추가된 것을 볼 수 있고, 완료이모지를 클릭한 "리액트 공부하기(1)"는 Edwin의 완료 목록으로 해당 아이템이 이동한 것을 볼 수 있다. 마찬가지로, 휴지통 이모지를 클릭하면 아이템을 삭제할 수 있다.
웹페이지를 만들어야 하니 공간배치에 대해서 한 번 정리할 필요가 있어 보였다.
- EDWIN 벨로그 : CSS #1 display:flex
- EDWIN 벨로그 : CSS #2 display:grid 작성중...
- EDWIN 벨로그 : CSS #3 position
REACT - HOOK 시리즈
- EDWIN 벨로그 : HOOK - useCotext
- EDWIN 벨로그 : HOOK - useReducer
- EDWIN 벨로그 : Hook : useMemo, React.Memo, useCallBack
REACT - 기타 시리즈
EDWIN 벨로그 : 폴더구조 및 리액트 코딩컨벤션
그런데 위의 경우는 적합한 내용은 아니었던 것 같다.EDWIN 벨로그 : Function 모듈화
보통 이 경우는 커스텀훅을 만드는 것 같은데 이는 추후에EDWIN 벨로그 : 의미있는 컴포넌트 분리(1)
EDWIN 벨로그 : CSS in JS
EDWIN 벨로그 : Rendering-batching, 렌더링 최적화
REACT - Redux
ID를 설정하는 부분이었다. map을 통해서 화면에 무언가를 뿌릴 경우, 유니크한 key가 있어야 한다는 점이었다. TODO 리스트를 배운대로 배열의 길이+1을 해주었더니, 아래와 같은 문제가 발생되었다.
중복되는 ID가 발생되었고, 콘솔창에 경고와 함께 화면이 동작하지 않게 되었다. 여기에서 고유한 ID를 부여하는 것이 얼마나 중요한 지에 대해서 고민할 수 있게 되었다. 그래서 찾은 방법은 Date.now() 를 사용하는 것이다. Date 객체에서 .now() 매서드는 1970년 1월 1일 00시 00분 00밀리세컨드 초로부터 현재시간을 뺀 시간을 13자리의 숫자로(1677467847171) 변환해 준다. 밀리세컨드 초 단위에서 해당 숫자는 매번 증가되기에 유니크한 숫자를 얻기에 충분히 유용할 것이다.
styled-components를 통해서 CSS IN JS를 활용하는 부분에 대한 이점이었다. props를 통해서 특정한 정보들을 받아서 유기적인 CSS 스타일을 적용할 수 있다는 점이다. 이점은 본문이 담고있는 설정된 블리언 데이터(true, false)의 상황에 따라서 CSS을 제어할 수 있다는 점이다.
${props =>
props.open &&
css`
background: #ff6b6b;
&:hover {
background: #ff8787;
}
&:active {
background: #fa5252;
}
`}
위의 코드는 상단에 있는 이미지에서 파랑 연필이모지가 빨강이모지로 변경되는 것을 설정한 내용에 해당된다. 또한 &를 이용하면 재미있는 효과를 만들어 낼 수 있는데 아래와 같다.
background: #75B2EF;
&:hover {
background: #C2D8EF;
}
&:active {
background: #1481EF;
}
본래시, 마우스를 가져다 놓았을 때(&:hover), 마우스를 클릭 했을 때(&:active)를 간편하게 설정할 수 있다. 이를 몰랐을 때에는 onMouseover(), onMouseout()을 통해서 설정했던 기억이 난다. 물론 일주일이라는 시간에 배운 것은 무수히 많지만, 가장 기억 남는 두 가지만을 적어 보았다.
리액트와 뷰에서 제공하는 특별한 가성비 좋은 이벤트라고 설명하면 좋지 않을까? 본래 DOM이라는 것은 웹페이지를 구성하는 가장 기본적인 내용이다. DOM-tree 라고 설명하면 되지 않을까?
화면은 위에서 말하는 노드 하나가 변경되었을 때 "리렌더링"을 통해서 화면을 갱신한다. 그런데 노드 하나가 변경될 때마다 화면 전부가 새롭게 "리렌더링"된다면, 그것은 분명 값비싼 비용을 요구할 것이다. 이런 부분 때문에 리액트와 뷰는 "Virtual DOM"라는 것을 제공하고 있다.
마지막 DOM과 변경된 DOM 사이에서 발생된 차이점을 발견하고 일괄처리된 결과를 실제 DOM에서 찾아서 해당 부분만 변경해주는 것이 "Virtual DOM"이 동작하는 원리이다. 만약 5개의 노드가 변경되었을 때 기존의 경우라면 5번의 "리렌더링"이 발생되며 5번의 새롭게 화면을 그려야 하는 비싼 비용을 부담해야 한다. 그러나 "Virtual DOM"은 이 5개가 단 번에 발생되었다면, 이를 5번의 과정이 아니라 1번 만 수행할 뿐만 아니라, 노드 전체를 새롭게 "리렌더링"하는 것이 아니라, 변경된 부분만 처리한다.
props는 상위컴포넌트에서 하위컴포넌트에게 정보를 내려줄 대 사용하는 개념이다.
<TodoLists todoitem={todoitem} setTodoitem={setTodoitem} deleteTodo={deleteTodo} DoneTodo={DoneTodo}></TodoLists>
위에서 언급한 내용이 상위컴포넌트에서 하위컴포넌트로 전달한 props객체이다. 상위컴포넌트에서 선언된 변수들을 하위컴포넌트로 내려줄 수 있다.
하위 컴포넌트에서는 이를 props 객체로 받아서 사용할 수 있게 된다. 그리고 이를 구조분해할당을 하면 쉽게 객체 내의 정보를 꺼내서 사용할 수 있다.
function TodoLists({todoitem,setTodoitem, deleteTodo, DoneTodo}) {
return ( ... )
}
이런 식으로 리액트는 상위컴포넌트와 하위컴포넌트 사이를 유기적으로 동작하게 만들어 낸다. 그런데 이러한 방식은 다소 불편하다. 왜냐하면 props Drilling이 발생될 수 있기 때문이다. 이런 불편함 때문에 useContext(EDWIN벨로그) 라는 HOOK이 등장하기도 하였다 props로 정보를 전달하는 것이 아니라, 전역에서 이를 관리하는 것이다.
위에서 언급한 체계를 상태관리라고 부른다. props를 통해서 리액트는 다양한 자료형을 내려줄 수 있는데 객체로된 데이터, 함수 전부 전달이 가능하며 하위컴포넌트에서의 동작을 통해서 상위컴포넌트의 상태라고 불리는 정보를 변경할 수 있다.
이러한 상태관리의 리액트 내장 기능이 존재하는데 바로 useState(), useContext(), useReducer()를 통해서 제어할 수 있다. 그러나 이 3가지는 분명 가볍지만, 제한이 있기 때문에, 외부 라이브러리인 Redux가 도입되기도 하였다. 이를 통해서 복잡한 과정을 체계적으로 구현했다. 대표적인 useContext()와 Redux의 차이에 대해서는 별도로 정리를 이어갈 계획이다.
부트캠프에 참여한지 3주차를 넘어 4주차로 나아가고 있는 시간이다. 분명한 성장이 있었고, 몰입 100시간은 엄청난 것 같다. 무언가 기술을 습득한다는 즐거움이 이런 것일까한다. 그리고 그 즐거움에는 끝이 없다는 것이다.
대표적인 것은 Redux를 시작하며, 중앙관리소를 생성하는 부분에서부터 발생된다.
config > configStore.js
- import {
createStore} from "redux";- const store =
createStore(rootReducer);
리덕스 4.2 버전 이후의 상황에서는 createStore 는 권장되지 않기에 취소선이 그어져있지만, 현재 사용할 수는 있는 상태이다. 그러나 리덕스 팀에서는 @reduxjs/toolkit의 사용을 권장하고 있다.
// 터미널을 통해서 라이브러리를 추가로 설치해주고
yarn add @reduxjs/toolkit -D
// 중앙저장소를 생성할 때 createStore가 아니라 configureStore를 사용하는 것이다.
import { configureStore } from ‘@reduxjs/toolkit’
물론 현재적 상황에서 취소선 자체를 삭제할 수도 있다.
import { legacy_createStore as createStore } from "redux";
const store = createStore(rootReducer);
legacy_createStore를 통해서 사용하면 취소선이 없어진다. 그리고 이름을 변경(as) 해서 createStore를 하단에서 사용할 수 있다. 그러나 미래적 상황에서 리덕스 팀의 권고는 훗날의 서비스 종료를 의미한다고 볼 수 있지 않을까? 아니면 더 이상의 지원이 없기에 상위호환은 어려워질 수도 있을 것이고 말이다. 이런 식으로 공부를 다했다는 긴장을 없애주는 직군이 개발자 직군인 것 같다. 공부하기를 좋아하는 필자에게 이러한 부분은 충분히 매력적이다.
리덕스를 복습한 내용을 EDWIN-github에 기록해 두었다. 오늘 라우팅을 공부하며, 간단한 리덕스 복습을 2번 정도 참고없이 진행해보자.
Author. EDWIN
date. 23/03/05