TIL

241210 TIL

GoJay 2024. 12. 11. 01:01
  • 할 일 관리 서비스 만들기
    • createBrowserRouter로 라우팅을 하면 loader라는 속성을 제공한다. 해당 속성을 사용하면 페이지가 라우팅 되는 시점에 곧바로 loader에 등록해 둔 메서드가 실행돼서 서버의 데이터를 받아올 수 있다. 데이터는 컴포넌트에서 useLoaderData 훅을 사용해 받아올 수 있다.
    • useEffect의 의존성 배열로 빈 배열을 넘겨서 처음 컴포넌트가 렌더링 될 시 서버 데이터를 패치할 수도 있지만, 그렇게 되면 useEffect 실행 전에 한 번, useEffect 실행 후 서버 데이터로 상태를 변경한 이후에 또 한 번, 이렇게 총 두 번 렌더링이 발생한다. 하지만 loaderuseLoaderData 훅을 사용하면 라우팅 시점에 페이지의 컴포넌트를 렌더링하기 전에 데이터를 먼저 서버에서 받아오고, 서버 요청 처리가 끝나면 받아온 데이터를 바로 사용할 수 있기 때문에 렌더링이 한 번만 일어난다. 마치 컴포넌트에 Props로 데이터를 내려준 것과 비슷하게 동작한다.
    • 사용자 이벤트에 따른 데이터 요청이라면 useEffect를 사용해야겠지만, 페이지에 처음 라우팅되는 시점에 데이터를 받아오는 건 loaderuseLoaderData를 사용하는 게 훨씬 유리하다. 잘 활용하자.
    • 전역으로 관리하는 Context를 제공해줄 Provider 컴포넌트를 만들었다면 해당 위치에서 useLoaderData로 서버 데이터를 미리 받아오고, 감싸진 하위 컴포넌트들에는 Context로 데이터를 제공해 줄 수 있다.
    • 공통 컴포넌트더라도 어디서 사용하든 필수적으로 사용해야 하는 데이터라면 Props가 아니라 직접 컴포넌트 내부에서 데이터를 받아오는 것도 나쁘지 않은 것 같다. 해당 컴포넌트가 특정 컨텍스트에 의존된다는 단점이 있고, 또 상위 컴포넌트에서 직관적으로 '여기에 어떤 데이터가 뿌려지겠다'라는 게 표현되지 않는다는 단점이 있지만, 그래도 필수적인 데이터를 하위 컴포넌트에서 다루면 코드가 좀 더 깔끔해지고 관리가 편하다는 장점이 있다고 생각한다.
    • 라우팅 경로에 따라 위치할 컴포넌트를 표시할 때 react-router-domOutlet을 사용하면 된다. createBrowserRouter에서 children을 사용한 경우 자식 요소에 경로에 따라 다른 컴포넌트를 보여줄 수 있으며, '다른 컴포넌트'의 위계를 표현할 때 Outlet을 사용한다.
    • Outlet은 자체적으로 context를 만들 수 있고, 위치할 컴포넌트들 중 상위에서 Props를 받고 싶은 위치에서 useOutletContext를 사용해 데이터를 받아올 수 있다. useOutletContextreact-router-dom에서 제공되는 훅이다.
    • 클라이언트와 서버의 상태를 언제 어떻게 동기화할지가 고민이다. 일단은 클라이언트에서도 상태를 계속 추적하면서 관리하고, 변경될 시 즉각 서버에 요청을 보내 동기화하는 방식으로 구현했는데, 몇 가지 의문이 남아있긴 하다. 즉각 동기화를 하는 거면 클라이언트에서 굳이 상태를 들고 관리를 같이 해줘야 하는 건지(필요할 때마다 서버에서 전부 요청하면 되는 게 아닌지), 즉각 동기화가 아니라 어느 정도 쌓아뒀다가 동기화 요청을 보내서 요청 수를 줄이는 게 좋은지, 등등.
    • 경험이 부족하니 뭐가 맞는지 모르겠다. 이것 저것 자료들 더 찾아보면서 공부해 봐야겠다.
  • 모던 리액트 딥다이브
    • 상태란 어떠한 의미를 지닌 값이며, 애플리케이션의 시나리오에 따라 지속적으로 변경될 수 있는 값을 의미한다.
    • 클라이언트가 무거워지면서 관리해야 하는 상태가 많고 복잡해졌다. 상태를 어디에 저장할지, 접근 범위를 어디로 할지, 상태 변화에 따른 리렌더링은 어떻게 제어할지 등 상태를 잘 관리하는 것은 어렵지만 꼭 해야만 하는 미션이 됐다.
    • 리액트는 데이터를 단방향으로 바인딩한다는 특성이 있고(부모에서 자식으로만 props 전달이 가능하다), 이러한 특징과 잘 어울리는 상태 관리 패턴이 Flux 패턴이다. Flux의 Action은 단방향으로만 동작하여 상태를 Dispatch 하고 관리한다.
    • 리덕스(Redux)는 Flux의 컨셉을 차용하면서도 데이터의 흐름을 모델, 뷰, 업데이트 세 가지로 분류하고, 데이터 흐름을 단방향으로 강제해 애플리케이션 상태를 안정적으로 관리하려고 노력한 도구이다. 꽤 긴 기간 상태 관리의 표준 라이브러리처럼 많이 사용되었다.
    • Context API는 엄밀히 말하면 '상태 관리'가 아니라 '상태 주입'을 위한 도구이다. 상위 컴포넌트에서 관리되는 상태를 하위 컴포넌트에 전달할 때 Props Drilling이 발생할 수 있다는 문제가 있기 때문에, 상위 컴포넌트의 상태를 효과적으로 하위에 내려주는 것이 Context API의 목적이었다.
    • React Query와 SWR은 http 요청에 특화된 상태관리 라이브러리다. http 요청을 통해 받아온 상태 데이터들을 캐싱해주고, 데이터 사용이 필요한 시점에 API 요청을 다시 날리는 게 아니라 캐싱된 데이터를 사용할 수 있게 해 준다.
    • 함수형 컴포넌트 진영에서 훅이라는 패러다임이 등장함에 따라, 훅을 사용해서 상태를 가져올 수 있는 다양한 라이브러리들이 등장했다. Recoil, Jotai, Zustand, Valtio 등 다양하다. 훅에 기반한 상태 관리 도구들은 전역 상태 관리 패러다임(Redux의 Store)에서 벗어나 원하는 만큼의 상태를 지역적으로 관리하는 데 유용하다.
    • useState의 등장으로 컴포넌트마다 관리돼야 하는 지역적인 상태를 쉽게 정의하고 관리할 수 있게 됐다. 특별히, 커스텀 훅까지 함께 사용하면 여러 곳에서 사용되는 동일한 상태의 인터페이스를 미리 정의해 두고 가져다 쓸 수 있게 돼서 편리하다.
    • 지역 상태는 전역 상태와 달리 독립적이라는 장점이 있지만, 한편으론 지역 상태라는 것이 단점이 되기도 한다. 경우에 따라선 여러 컴포넌트에서 각자에게 필요한 지역 상태를 많이 만들수록 상태를 동기화하는 게 어렵고, 다양한 상태가 파편화될 수 있다는 단점도 존재한다.
    • 두 개 이상의 컴포넌트에서 같은 상태를 참조하도록 하는 가장 단순한 방법은 두 컴포넌트의 공통 조상 컴포넌트에 상태를 정의하고 Props로 값을 내려주는 것이다. 그러나 이러한 방식은 컴포넌트의 깊이가 깊어질수록 Prop을 너무 많이 전달해야 하고, 유지보수도 어렵다는 큰 단점이 있다.
    • 상태를 관리한다는 것은 useStateuseReducer 등으로 생성한 지역 변수가 좀 더 전역적으로 공유될 수 있게 하는 것, 상태의 변경 시 해당 상태를 참조하는 컴포넌트를 성공적으로 리렌더링 해주는 것, 그리고 이 과정을 좀 더 수월하게 할 수 있도록 해주는 것을 의미한다. 여러 상태 관리 도구들이 풀고 싶은 문제도 결국은 어떻게 하면 이 과정들을 더 효과적이고 안정적으로 할 수 있을지에 대한 부분이다.

'TIL' 카테고리의 다른 글

241216 TIL  (0) 2024.12.17
241212 TIL  (0) 2024.12.13
241209 TIL  (0) 2024.12.10
241208 TIL  (1) 2024.12.09
241207 TIL  (2) 2024.12.08