TIL
241201 TIL
GoJay
2024. 12. 2. 14:52
- 할 일 관리 서비스 준비
- Task 목록을 칸반 보드 형태로 관리해 주는 서비스를 만들어보려고 준비 중이다. 해당 프로젝트 시작 전 몇 가지 사항에 대해 알아보는 시간을 가졌다.
- Context API 사용:
- Context를 사용해 상태를 관리하는 다양한 패턴이 있다.
Provider
를 별도로 만들고, 매개 변수로Context.Provider
내부에 들어가야 하는 컴포넌트들을 받아, Context 생성, 정의, 데이터 제공 등을 전담하는 함수를 만들어 사용하면 깔끔하게 상태를 관리할 수 있다. useContext
로 컨텍스트를 바로 받아와 사용하기보단, 별도의 커스텀 훅으로 래핑 해서 사용하면 타입 좁히기나 예외 처리 등 좀 더 안전하게 컨텍스트를 사용할 수 있다. useMyContext와 같은 식으로 컨텍스트 사용 방식을 바꿔보자.- 전역으로 제공할 값을 관리하는
Provider
함수에서 외부로 공개할 값과 로직 함수를 다양한 방식으로 관리하는 패턴들이 있는 것 같다.useCallback
또는useMemo
등을 사용해서 불필요한 값의 재생성을 막는 처리를 해주기도 하고, 상태 업데이트 함수의 로직 처리 등을 함수로 래핑해 반환해주기도 한다. 아래와 같은 형식이다(출처: 다른 사람들이 안 알려주는 리액트에서 Context API 잘 쓰는 방법)
function CounterProvider({ children }) { const [counter, setCounter] = useState(1); const actions = useMemo( () => ({ increase() { setCounter((prev) => prev + 1); }, decrease() { setCounter((prev) => prev - 1); } }), [] ); const value = useMemo(() => [counter, actions], [counter, actions]); return ( <CounterContext.Provider value={value}>{children}</CounterContext.Provider> ); }
- 위 출처의 글에선
useRedcuer
의dispatch
를 쓰는 것보다 업데이트 함수가 포함된 객체를 바로 선언하는 것을 선호한다고 작성되어 있는데, 정확히 이해가 되진 않는다. 일단 내가 고민해 본 결론은useReducer
를 사용하는 이유가 무거운 상태 처리 로직을 컴포넌트 외부로 분리하는 것이고, 그를 위해 상태 업데이트에 단순 로직 처리뿐 아니라 매번action
객체의 타입을 정의하고 값을 전달하는 과정 및 해당 과정을 정의하는 코드가 필요하기 때문에, 별도 추가 코드 없이 상태 처리 로직을 메인 컴포넌트에서 뗄 수 있는 방법이라 그런 게 아닐까라는 생각이 들었다. 그냥 혼자 생각해 본 내용이고, 정답은 잘 모르겠다.
- Context를 사용해 상태를 관리하는 다양한 패턴이 있다.
rem
,em
등 CSS 사이즈 표현 단위:- 반응형으로 웹 페이지를 처리할 땐 요소 간 크기의 비율을 유지하기 위해 사이즈 단위를
px
,pt
,cm
등 고정형으로 쓰는 게 아니라em
,rem
,vh
,vw
등을 보통 사용한다. em
과rem
은 둘 다font-size
를 기준으로 값을 계산한다. 예를 들어,font-size
가10px
이면1em
또는1rem
이10px
이 된다.em
은 현재 사이즈가 사용되는 요소의font-size
가 기준으로 적용된다. 만약에 요소의font-size
가 정해져 있지 않으면 가장 가까운 상위 요소의font-size
가 기준이 된다.rem
은root
에 있는font-size
가 기준이 된다. DOM의 최상단 루트에는html
태그가 있으며, 별도 설정을 해주지 않으면 기본값이font-size: 16px
로 고정되어 있기 때문에 해당 값이 기준이 된다.- 프로젝트 전체에서 고정된 기준을 사용하는 것이 좋기 때문에 특별한 상황이 아니면
rem
을 단위로 많이 사용한다. - 이외에도 뷰포트 사이즈에 따라 크기를 조절하기 위해
vh
와vw
도 종종 사용한다.vh
는 Viewport Height의 줄임말이고,vw
는 Viewport Width의 줄임말이다.
- 반응형으로 웹 페이지를 처리할 땐 요소 간 크기의 비율을 유지하기 위해 사이즈 단위를
- CSS Nesting:
- 과거에는 SCSS, SASS 등 전처리기를 써야 사용이 가능했지만, 최근엔 CSS 표준에 포함되어 기본으로 사용이 가능하다.
- CSS Nesting은
&
,>
등의 문법을 사용해 하나의 선택자로 생성한 CSS 정의 내에서 해당 요소의 자식 관계에 있는 요소들의 스타일링을 정의할 수 있게 해 준다. 대략 아래와 같은 식으로 사용된다. div { & .outer-box { background-color: red; > .inner-box { background-color: blue; } } }
- CSS Nesting을 적절하게 사용하면 요소들의 CSS 위계 구조를 좀 더 명확하게 파악할 수 있기 때문에 유용하다. 이번 프로젝트에서는 일관된 규칙을 적용해 CSS Nesting을 구현해 볼 예정이다.
- 별도의 CSS 전처리기를 사용해보지 않는 건, 아직은 그 필요성을 크게 느끼진 못해서이다. 너무 급하게 기술을 도입하기 보단, 이 기술이 어떤 배경에서 왜 나왔는지를 충분히 이해하기 위해 어느 정도 규모가 있는 프로젝트에서 먼저 도구의 도움 없이 직접 구현을 해볼 예정이다.
- Flux 패턴
- 패턴에 대해선 아직 생소하지만, 그래도 React 애플리케이션에서 많이 사용되는 것 같은 Flux 패턴을 공부해서 최대한 프로젝트에 적용해보려고 한다.
- Flux 패턴의 컨셉은 '데이터를 단방향으로만 바인딩해서 변경 흐름을 잘 추적할 수 있게 하자'는 것이다(그렇게 이해했지만 아닐 수도 있다).
- Flux 패턴은 Action --> Dispatch --> Store --> View 로의 데이터 흐름을 갖도록 하는 구조를 의미한다. 만약에 사용자가 클라이언트에서 인터랙션을 통해 Store에 등록된 상태를 바꿔줘야 하는 상황이 올 경우, 직접 Store에 접근해 상태를 바꾸지 않고(그렇게 할 경우 양방향 데이터 바인딩 방식이 된다), 대신 새로운 Action 객체를 생성해 Dispatch를 거쳐서 Store로 가게 만든다.
- 결국, 데이터의 흐름은 Dispatch를 거쳐서 Store에 가야지만 값을 변경할 수 있는 단방향 흐름이 된다.
- Flux 패턴은 상태 관리 라이브러리인 Redux가 채택한 패턴이라고 한다.
- 일단은 Action 객체를 생성하고, 해당 정보로 Dispatch 함수를 거쳐서 Store에 있는 상태를 수정하고, 상태가 변경되면 View가 업데이트된다는 것이 이미 사용해 본
useReducer
의 상태 관리 방식과 유사하다는 느낌이 들어서, 일단 그 정도로 이해를 해두긴 했다. action
과dispatch
는 실제로useReducer
의 콜백으로 전달되는reducer
함수의 인자 또는useReducer
가 반환하는 함수이고, 그 역할도 비슷하기 때문에, 그 정도 이해가 적절할 수 있을 것 같다. 다만,store
라는 개념을reducer
함수와 일치시키는 것은 약간의 비약이 있는 것 같다(Redux와useReducer
는 다르다. 차이 중store
의 유무가 있다고 하는 것 같은데, 이 부분에 대해 좀 더 공부해 봐야겠다.- 아직 '상태 관리'라는 것에 대한 배경 지식이 부족해서 정확한 이해를 하기 어렵다. 하지만, 이런저런 자료 찾아가면서 하나씩 확인해 보고 점차 지식을 넓혀가야겠다.
- Context API 사용:
- 이외에도 미리 알아둬야 할 배경 지식이 너무나도 많은데, 하나씩 차근차근 알아가야겠다. 너무 불안해하지 말자 아직 공부 시작한 지 얼마 안 됐으니 모르는 게 당연하다.
- Task 목록을 칸반 보드 형태로 관리해 주는 서비스를 만들어보려고 준비 중이다. 해당 프로젝트 시작 전 몇 가지 사항에 대해 알아보는 시간을 가졌다.