2023 JavaScript Rising Stars
Risingstars
Zustand, 작고 빠르며 확장 가능한 상태 관리 솔루션으로, 간소화된 플럭스 원칙을 기반으로 함. 편리한 훅 기반 API를 가지고 있으며, 불필요한 코드나 리렌더링, 보일러 플레이트가 없음
Next.js 개발 시 자주 마주치는 Hydration 에러 이해하기
Next.js 환경에서 개발을 하다보면 Hydration에러를 종종 만나게 되는데요. 이 에러는 서버에서 생성된 HTML과 클라이언트에서 생성되는 HTML간에 불일치가 발생할때 발생합니다.
가령 useEffect내 API호출을 한다던지, 세션이나 쿠키 같은 요인에 따라 렌더링 컴포넌트가 다를때라던지, 자바스크립트 실행 타이밍이 다를때 이 에러를 접하게 되는데요.
이 Hydration에러는 왜 발생하는 것일까요??
근본적인 원인은 렌더링을 두 번 하기 때문입니다. 서버 사이드 렌더링 후, 클라이언트 사이드에서 추가 렌더링을 하면서 데이터의 불일치가 발생하는 것인데요.
그럼 왜 렌더링을 두 번 할까요? 언뜻 보기엔 두 번 렌더링이 비효율적인것 같아 보이는데요. 두 번 렌더링을 하게 되면 최초 초기 로딩 시 최소한의 정보만을 포함하고 있어 빠르게 렌더링이 가능합니다. 또한 검색엔진은 빠른 렌더링을 중요한 랭킹 요소로 고려하므로 SEO에도 유리 합니다. 초기 렌더링 이후에는 DOM 요소에 속성을 매칭 시키는 작업을 하는데요. 이 이벤트 리스너를 붙이는 작업은 페이지를 다시 그리지 않으므로 추가적인 렌더링 비용이 발생하지 않습니다.
따라서, Hydration은 효율적인 초기 페이지 로딩과 동적 웹 애플리케이션 기능의 균형을 맞추기 위한 과정 입니다. 다만 Hydration 에러는 개발 과정에서 다루기 까다로운 문제중 하나인데요. Next.js 에서도 에러를 줄이기 위한 방안을 지속적으로 모색하고 기술적인 접근을 제공하고 있습니다. 예를 들어 Zustand에서는 과거에 persist미들웨어를 사용할때 Hydration에러가 발생하였는데요 V3부터는 클라이언트 측에서 상태를 다시 로드하도록 하여 서버와 클라이언트 사이의 데이터 불일치 문제를 해결하였습니다.
Hydration 과정과 이로 인해 발생할 수 있는 에러를 제대로 관리하면, 사용자 경험을 향상시키고 웹사이트의 성능을 최적화할 수 있습니다.
2023 JavaScript Rising Stars 리뷰
2023년 JavaScript 생태계의 주요 동향을 조망하는 'JavaScript Rising Stars'가 발표되었습니다.
이 중에서 가장 두각을 나타낸 프로젝트는 React로 구현된 UI 구성요소 모음인 'shadcn/ui'인데요. 이 프로젝트의 특이점은 NPM 패키지 형태로 제공되지 않으며, 사용자가 직접 소스 코드를 복사하여 사용한다는 점입니다. 'shadcn/ui'는 Tailwind CSS와의 호환성, React 서버 구성요소 지원, 우수한 문서화로 인기를 얻었습니다.
다만 Tailwind CSS가 많이 사용되지 않는 우리나라에서는 이 라이브러리가 향후에 인기를 얻을수 있을지는 모르겠네요.
또한, JavaScript 및 TypeScript 애플리케이션용 빠른 올인원 툴킷 'Bun', 새롭게 부상한 CSS-in-JS 라이브러리 'StyleX', 상태 관리 분야에서 'Zustand'가 주목을 받았습니다. 특히 'Zustand'는 기존의 Redux를 대체할 가능성에 대한 기대를 모으고 있는데요.
기존 Redux의 장점인 DevTools를 사용할수 있으면서도 보일러플레이트 코드가 상당히 적어서 대체되는건 아마도 시간문제일것 같습니다.
관심 있으신 분들은 사이트에 직접 방문해서 참고하시는것을 추천드립니다.
https://risingstars.js.org/2023/en#section-all
Zustand v5 릴리즈
2024년 10월 14일자로 Zustand v5가 출시되었습니다. 핵심 변경사항들만 정리해보았습니다.
번들 사이즈가 절반 이상으로 줄었습니다. (1.2kb -> 588b)
As-is (v4)
Minified: 3.1kb
Minified + Gzip 압축: 1.2kb
To-be (v5)
Minified: 1.2kb
Minified + Gzip 압축: 588b
React 최소 요구 버전이 React 18 버전으로 변경되었습니다.
TypeScript 최소 요구 버전이 4.5 버전으로 변경되었습니다.
use-sync-external-store
패키지가 피어 디펜던시로 변경되었습니다.
zustand/traditional
의 createWithEqualityFn
과 useStoreWithEqualityFn
을 사용하고 계셨다면 use-sync-external-store
패키지를 별도로 설치하셔야 합니다.
ES5 지원이 중단되었습니다.
Vite를 사용하시는 분들은 vite.config.ts
파일에서 build.target
옵션을 es2015
이상으로 설정하셨는지 확인해 주세요.
TypeScript 설정도 확인해 주세요. tsconfig.json
파일의 compilerOptions
에서 target
을 ES6
이상으로 설정해야 합니다.
v4 -> v5로 올리시는 분들은 아래 마이그레이션 가이드 링크를 참고해 주세요.
https://github.com/pmndrs/zustand/blob/main/docs/migrations/migrating-to-v5.md
우아콘 2023 유튜브! (feat. 제가 제 발표 공유하기)
안녕하세요, 오랜만입니다! 오늘 드디어 지난 11/15에 개최되었던 우아콘 2023의 영상이 모두 올라왔는데요! 현장에 참여 못하셨던 분, 관심 있었으나 듣지 못한 세션이 있으신 분을 비롯해 관심 있으신 모든 분! 께 추천드립니다 :)
저도 "프론트엔드 상태관리 실전 편 with React Query & Zustand" 이라는 주제로 발표를 진행했는데요! 아래는 제가 발표한 링크이니 프론트엔드 상태관리와 컴포넌트, 그리고 아키텍처에 관심을 가지고 고민하는 여러분들께 살포시 공유드립니다..! 유튜브 링크인데 우아한테크 채널에서 보셔도 좋고 우아콘 2023 사이트에서 보셔도 되니 편하신 곳에서 시청하셔요!
https://youtu.be/nkXIpGjVxWU?si=lw1NthDJWWu2vL2t
(마지막으로.. 새해엔 열심히 글 좀 써보겠습니다..ㅎㅎ)
맛있는 zustand와 재미있는 FE 상태관리
여러분들은 회사, 개인프로젝트로 어떤 상태관리 라이브러리를 사용하고 좋아하시나요?
저는 6개월 동안 프로젝트에서 zustand 라는 Front-End 상태관리 라이브러리를 사용해보았습니다.
여러분들의 경험을 가지고 라이브러리들을 비교하면서 읽어보시면 좋을 것 같습니다.
댓글로 다양한 의견 주시면 감사하겠습니다!!
https://hooninedev.com/240222/
현재 react-query와 zustand를 같이 쓰면서 고민이 있습니다. 현재코드는 useQuery를 통해 데이터를 가져오고 그 데이터를 가공해서 zustand에 넣어놓고 데이터를 수정하거나 추가등의 변화가있을 때 useMutaion onSuccess -> queryClient.invalidateQueries를 통해 자동으로 갱신하게 로직을 작성했어요. 이렇게 작성하면 데이터를 수정하거나 추가등의 변화가있을 때 마다 최신데이터가 갱신되기는 하지만 서버에 재요청을 해야하는 단점이 있어서 useMutaion onSuccess -> queryClient.invalidateQueries를 통해 자동으로 갱신하는 부분을 zustand에 추가로 데이터를 넣어주고 새로고침할때만 useQuery로 데이터를 받아오는 방식으로 변경할려고 해요. 근데 이렇게되면 새로고침하지 않으면 다른사람이 갱신한 데이터는 가지고 있지 못하게 되요. 서버 요청횟수를 줄이는 것보다 최신데이터를 가지고 있는게 더 중요한가요? 제 지인은 유저는 사이트안에서 계속왔다갔다 거릴거라 대부분은 최신데이터를 즉각적으로 갱신시켜줄 필요가 없다고 하고 저도 이 말이 맞는거같은데 다른사람들은 어떻게 생각할지 궁금해서 질문드립니다..
안녕하세요! 휴학 중에 개인 프로젝트 한번 만들어봤습니다! 아직 감이 잘 안 잡히다보니 chatGPT에 꽤나 의존했던 것 같습니다. 폴더 구조와 ssr, csr 사용 부분에서 피드백을 받고자 합니다! 또, containers 폴더 안 create 폴더에 있는 RouteChangeListener.tsx를 사용하여 퀴즈를 만들거나 푸는 도중에 현재 페이지를 벗어나려는 움직임을 감지하면 alert 창이 나오도록 설정하였습니다. 제가 생각해봤을 때 페이지가 이동했다가 다시 돌아오는 부분이 비효율적이라고 생각이 들어서 미들웨어나 다른 방법을 통해 해결할 수 있는지 여쭤보고 싶습니다. 감사합니다! 프로젝트 설명 : 퀴즈를 만들고 풀 수 있는 웹페이지 만들어봤습니다! vercel로 배포하였고, PWA 사용하여 모바일에서도 다운로드 가능하게 했습니다! 웹 앱 둘다 가능하지만 웹으로 봐주시는 것을 권장드립니다~!! 프로젝트 기술 스택: Next.js, react-query, zustand, firebase 테스트 아이디: 123@naver.com 테스트 비밀번호: 123123 GitHub 주소 : https://github.com/kmj0973/donquiz Vercel 배포 주소 : https://donquiz.vercel.app/ 따끔한 피드백 주시면 감사드리겠습니다!! 감사합니다!!
프론트엔드 부트캠프 수강 중인 학생입니다. 현재 팀 프로젝트를 들어가기전에 상태관리 라이브러리를 활용해서 간단한 redux(CRUD), zustand(CRUD)까지 구현 해봤습니다. 질문1) 팀플젝을 장점인 많은 zustand로 하려고 했으나 취업 합격자들, 취업어플 정보들을 봤을때 redux와 recoil이 많더라구요. 그래서 저도 redux, recoil을 한정해서 플젝을 해야할까요? 질문2) zustand로 플젝해도 회사 자격요건에 회사에서 redux를 쓴다던가 redux경험 우대사항이 적혀 있다던가 하면 불이익이 있을까요?
아무거나 쓰셔도 됩니다. 추정컨대 부트캠프 프로젝트의 기술 수준에서 상태 관리 라이브러리에 대한 아주 깊은 이해가 필요한 영역까지 다루시지는 않으시겠죠? 그렇다면 그냥 잘 다루실 수 있는 거 다루시면 됩니다. 혹은 어차피 학습하는 단계니까 일부러라도 낯선 도구를 사용해보시는 것도 좋습니다. (프로젝트 데드라인에 대한 압박이 심하지 않다면 개인적으론 이걸 더 추천합니다.) 물론 지원하는 회사의 job description과 내가 익숙한 기술 일치한다면 당연히 어느 정도 메리트는 있습니다. 그런데 신입 레벨에서 redux냐 zustand냐가 크게 고려될 거 같지는 않습니다. 그보다 크리티컬한 요소가 훨씬 많으니까요. 다만 기술 선택에는 항상 근거가 필요합니다. 그 근거가 부실하면 아래와 같은 다양한 면접 질문에 제대로 답하지 못하게 되겠죠. - 왜 상태 관리 라이브러리를 썼나, 그냥 리액트 기능만으로 짜면 안되나 - 왜 많은 옵션들 중에서 zustand를 선택했냐 - zustand가 팀프로젝트를 진행하는데 장점이 많다고 했는데 어떤 점이 그러한가 - zustand를 좋아한다고 하셨는데 그럼 혹시 이런 이런 기능을 써보셨냐 혹은 zustand의 어떤 어떤 api의 작동 원리에 대해 설명해줄 수 있나
안녕하세요~! 최근에 프론트엔드를 배우게 되어서 여쭤봅니다.. react 를 사용하면서 props drilling 을 겪고, 복잡한 코드가 되어 가는 중입니다. 궁금한 점은 zustand를 전역 상태 관리 도구로 사용하고 있는데 zustand를 어떻게 사용해야 잘 사용하는 것 일까요? 렌더링을 조금 깔끔하게 하고 싶어서 문의드립니다. 상황에 따라 다르겠지만 zustand를 많이 써서 state를 store 형태로 보관해서 사용하는게 좋을까요? 전문가들의 고견 부탁드립니다.(_ _)
글의 항간이 느껴져서 zustand를 잘 사용하는 법보다는 store를 보다 더 잘 쓸 수 있는 방법에 대해서 말씀드리고 싶은데요. react는 한마디로 "중첩 스코프의 세계"라고 말할 수 있습니다. 보통 App이라는 스코프 아래에 Layout이라는 스코프가 있고, 그 스코프 아래에 다시 여러 Component 스코프가 켜켜이 쌓일 겁니다. 이런 중첩 구조에서는 동등한 서열 간의 스코프나 분기되어 서로 다른 곳으로 뻗어나간 스코프 사이에서 어떠한 값을 공유하려면 분기되기 전의 상위 스코프에 그 값이 놓여있어야 합니다. 그래야만 참조가 가능하죠. react의 초기 문서에는 이것을 두고 "끌어올리기"라는 표현을 썼습니다. zustand를 사용한다고 해서 이 구조를 바꿀 수 있는 것은 아닙니다. state 도구의 provider는 늘 App을 감싸는 것이 보통인데, 이는 분기 이전의 스코프가 필요하다는 구조적인 이슈는 바뀌지 않으니 끌어올리기를 극단적으로 맨꼭대기까지 한 결과입니다. 이렇듯 react의 구조를 바꾸지 못하고 편승함에도 store라는 스코프를 사용하는 이유는, 실질적인 구조는 바꾸기 때문입니다. store 이하의 모든 컴포넌트는 실질적으로는 중첩이 아닌 모두 평행 상태가 됩니다. App으로부터 30개 이상의 중첩을 거친 스코프에서나 App 바로 아래의 스코프나 모두 store와 직접 연결할 수 있고, 어느 단계의 스코프에서도 set과 get이 가능하고 그 값을 공유할 수 있습니다. 이로 인해서 각 스코프는 자신이 참조해야 할 값과 그 값을 변경시켜야 할 파이프라인만을 지니는, 자기 성격이 매우 강한 형태가 될 수 있습니다. 따라서 props 의존성이 대폭 줄어들죠. 이를 돌려말하면 의존성을 주입받는 것이 아니라 스코프 자신이 의존성을 결정하는 방식으로 가버린다는 의미입니다. 쉽게 말하면 용도가 뚜렷해서 다른 것으로 확장하거나 전환하기 어려워집니다. 그래서 사용하는 데에 있어 안배가 필요합니다. props 의존성을 가지고 있어야 하지만, 그걸 받아오기 위한 drilling의 정도가 심하다면 store를 사용하되 그 부모 컴포넌트가 값을 참조하여 내려주도록 조정하시고, props 의존성이 없어도 되고 특정 값을 오롯이 사용한다면 store와 직접 연결하도록 만드세요. 만약 store부터로 값을 참조하고, 그 값을 다루어야 하는 이벤트들이 얽혀있다면 state 계층을 분리해서 hook으로 만들어 view로부터 떼어내는 것도 한 방법입니다. store가 코드의 복잡성이나 불가분한 것들을 해결해주는 만능은 아니라는 점에 유의하시면 좋을 것 같습니다.
안녕하세요, 요즘 next 13과 react 18 서버 컴포넌트에 대해서 본격적으로 파고 있는데 궁금한 점들이 여러가지 떠올라서 글 올립니다. 1. data fetching 방식의 변경 우선 기존에는 동적인 data fetching의 경우, getServersideProps를 통해서 페이지의 root에 전달해주고는 방식이 일반적이었는데 서버에서만 돌아가는 서버 컴포넌트가 나오면서 data fetching을 컴포넌트 단위로 할 수 있게되면, 기존에 사용하던 getServersideProps 같은 유틸 함수들은 사라지는건가요? 기존에는 정적 데이터면 getStaticProps, 동적 데이터면 getServersideProps, 유저 상호작용이 필요한 데이터면 client side useEffect를 많이 사용했는데 next 13부터는 이게 뭔가 뒤섞이는 것 같아서 혼란스럽네요. next 13을 위한 data fetching 패턴이나 방법론이 있나요? 2. 기존에 사용하던 상태 관리 프레임워크의 변화 위와 어느정도 연결되는 이야기입니다. 기존에 react-query를 많이 사용했는데 next 13부터 컴포넌트 레벨로 데이터를 요청할 수 있고 또 next 차원에서 요청 중복 제거를 지원하게되면 react-query 처럼 서버 상태관리와 캐싱을 강점으로 내세우는 프레임워크의 역할을 어떻게 되는건가요? 서버 상태를 컴포넌트 레벨에서 가져올 수 있다고 해도, 여전히 전역 상태 관리가 필요할 것 같은데 recoil, redux, zustand 같은 상태 관리 프레임워크도 계속 쓰게되는 것일까요? 계속 쓰게 된다고 하면 서버 컴포넌트와의 호환성은 어떻게 되는건가요? 만약 전역 상태 관리를 써야하는 컴포넌트라면 서버 컴포넌트가 될 수 없는 것인가요? 3. 서버 구성의 변경 다른 곳은 모르겠지만, 저는 next 백엔드를 단순히 요청을 전달하는 용도로만 쓰고 실제로 중요한 로직은 다른 백엔드 서버에서 처리하는 구조를 가지고 있었습니다. 하지만, next 13을 보니 서버 컴포넌트에서 DB 연결을 직접해서 데이터를 가져오는 예시들도 있더군요. 사이드 프로젝트라면 모르겠지만, 실 서비스에서도 서버 컴포넌트 - DB 직접 연결 이라는 구조가 성립할 수 있는건가요? 기존에 데이터를 취합하고 내려주던 백엔드 서버의 역할이 생략되는거라고 생각해도 되는건가요? 4. 왜 다시 20년 전으로 돌아가는거죠 제가 20년 동안 개발한 것은 아니지만, 예전에는 웹페이지를 서버에서 완전히 로드해서 내려주는 형태를 가지고 있었다고 배웠습니다. 그러다가 개개인의 기기가 스펙이 좋아지면서 서버 부하를 줄이고 클라이언트 쪽에서 역할을 분담하는 방식이 떴다고 들었어요. react도 처음에는 이런 프레임워크로 나왔다고 알고 있습니다. 그러다가 next, remix 같은 프레임워크들이 서버사이드 렌더링을 적극적으로 장려하면서 다시 회귀하고 있다고 들었습니다. 최근에는 react 마저 서버 컴포넌트를 발표했잖아요. 왜 이제와서 다시 서버 쪽에서 페이지를 로드하는 방식을 추진하고 있는건가요? 질문을 적고보니 좀 길어졌는데, 서핑을 좀 해봐도 마땅히 도움이되는 글이 별로 없어서 현직자들은 어떻게 생각하시는지 의견을 얻고자 질문 올립니다!
1번은 next.js 13버전 app에 대해서 공식문서(베타)를 보시면 없어짐을 아실 수 있습니다. 사실상 컴포넌트가 렌더링 되는 방식이 12에선 페이지 단위였다면 13에선 컴포넌트 단위로 변경되다보니 getStaticProps -> ISR or SSG, getServersideProps -> SSR로 페이지단위 렌더링 방식이 고정되는걸 서버컴포넌트와 클라이언트 컴포넌트로 컴포넌트 단위로 렌더링되는 방식이 변경되었다고 이해하시는게 더 나을거 같아요. 2번은 next.js13부터는 컴포넌트가 만약 상태라는걸 갖고 싶다면 클라이언트 컴포넌트를 사용하도록 강제화하고 있습니다. 서버컴포넌트에서 상태는 결국 디비라고 보시는게 더 편할거 같고 전역상태관리도 결국 top down이 아닌 bottom up 방식으로 변경되어감으로써 리덕스나 주스탄스 같이 정말 어플리케이션 전반에 걸치 상태라는 것은 이제 안쓰고 그 역할을 리액트쿼리 같은 캐싱기반으로 대체될것으로 전 생각하고 잇습니다. 3번은 아시다 싶이 가능이 한다는 것뿐이니 작은 서비스가 아닌 이상 백엔드 서버와 프론트엔드 서버는 분리되어야 관리도 용이하며 대용량 서비스에도 더 적합하기 때문에 next.js에 직접 디비를 연결할 일은 잘 없을것으로 보입니다. 4번은 아래의 deno 블로그에 올라온 글을 읽어보심이 더 좋을거 같습니다. https://deno.com/blog/the-future-and-past-is-server-side-rendering 제가 아는 지식선에서 설명을 드리자면 CSR에서 문제가 되었던 부분은 결국 프론트엔드에서 만드는 어플리케이션이 커짐에 따라서 한 화면을 이루는 번들 자체가 커져서 문제가 되었것으로 기억합니다. 추가적으로 모든 코드를 클라이언트에 돌리다보니 보안적인 문제도 있는것으로 알고 있습니다. 결국 SSR로 돌아온 것을 맞습니다만 jsp시절보다 낫다하는 면은 jsp시절에서는 클라이언트에서 렌더링하는 것 한벌, 서버에서 렌더링하는 것 한벌 짜야했던 점이 이제는 next.js와서 한벌로 가능해졌다는 점이 있고 위에서 설명드린 것처럼 한화면 모두 SSR인 것이 SSR과 SSG의 혼합 등으로 조금 더 나은 렌더링방식을 가져가는 것으로 보입니다.