블로그

Inje Lee (소플)

프론트엔드 지식 포털 소개 및 리덕스 문서 업데이트

안녕하세요, 소플입니다 😀여러분들에게 도움이 될 만한 몇가지 새소식을 전달드립니다!프론트엔드 지식 포털 소개최근에 제가 프론트엔드 지식 포털 사이트를 만들었습니다.사이트 이름은 FrontOverflow이고 주소는 아래와 같습니다.https://www.frontoverflow.com/사이트를 간단하게 소개하면 'Front-end 계의 StackOverflow' 라고 생각하시면 됩니다.한국어를 기본 언어로 하며, 프론트엔드와 관련된 질문과 답변을 자유롭게 할 수 있습니다.초반에 올라오는 모든 질문들에 대해서는 제가 직접 답변을 달아드릴 예정이니,개발하면서 막히거나 어려운 부분이 있다면 주저하지말고 편하게 질문 올려주세요!(프론트엔드 아키텍처, 컴포넌트 설계 등의 질문도 환영합니다 😀)리덕스 문서 업데이트그리고 최근에 출시한 처음 만난 리덕스 강의와 관련해서,실습 파트를 제외한 모든 강의 내용을 담은 문서를 FrontOverflow에 정리해두었습니다.강의를 수강한 분들은 복습하는 용도로 사용하시면 되고,수강하지 않으신 분들도 개인적으로 리덕스를 학습하는 용도로 사용하시면 분명 도움이 될 겁니다.강의 문서는 아래 링크에서 확인이 가능합니다.🔗 처음 만난 리덕스 강의 문서 보기 모든 수강생 분들의 성장을 응원합니다! 🎉감사합니다.

프론트엔드리액트리덕스프론트엔드ReactReduxFrontend

주니어 프론트엔드 개발자에게 꼭 필요한 역량은?

주니어 프론트엔드 개발자에게 핵심이 되는 기술은 무엇일까요? 오늘날 프론트엔드 개발 프레임워크/라이브러리 중 가장 많이 쓰이는 리액트(React)의 경우에도 막상 ‘제대로’ 쓰는 개발자는 흔하지 않다고들 하죠.현대 웹 개발은 복잡한 요구사항과 여러 플랫폼에서의 동작을 고려해야 해요 때문에 모던 자바스크립트(JavaScript) ES6+ 및 타입스크립트(TypeScript)에 대한 깊이있는 이해는 코드의 유지보수성과 확장성을 높이고 안정적인 웹 앱을 만들 수 있게끔 합니다. 아울러 커스텀 훅(Custom Hook), 재사용성 높은 컴포넌트(Component) 구현 등 리액트를 높은 수준으로 활용할 수 있다면 더 나은 사용자 경험과 개발 생산성을 도모할 수 있어요.더욱이 리덕스(Redux)와 같은 상태 관리 라이브러리 경험이 있다면 애플리케이션의 확장성을 향상시킬 수 있습니다. 덧붙여 FE 개발에서 필수적인 환경을 제공하는 Node.js를 이해하면 빌드 도구, 패키지 매니저, 테스팅 도구 등을 자동화하여 개발 프로세스를 효율화하고 더 높은 품질의 소프트웨어를 개발할 수 있겠죠.이렇듯 프론트엔드 개발자에게 중요한 기술은 여러 가지가 있겠지만, 중요한 건 알고 있는 기술의 가짓수가 아니라 그 깊이와 수준에 달려 있는데요. 다양한 요소들을 그저 사용해 본 수준이 아니라, 원리를 정확하게 이해하고 실무에서 응용할 수 있는지가 주니어 프론트엔드 개발자의 경쟁력으로 여겨지고 있습니다.•••주니어 프론트엔드 개발자에게 꼭 필요한 역량을 갖추고 싶다면?지금 인프런 프리즘 [프로가 되는 프론트엔드 개발자 로드맵 with React]을 통해 학습해보세요. https://www.inflearn.com/roadmaps/716•••인프런 프리즘 브랜드 스토리 읽어보기 >>

프론트엔드리액트React프론트엔드리덕스Redux상태관리TypeScript타입스크립트JavaScript자바스크립트

바다다다

[인프런 워밍업 스터디 클럽 3기 FE] 3주차 발자국

수강강의1: 따라하며 배우는 자바스크립트 A-Z수강강의2: 따라하며 배우는 리액트 A-Z[19버전 반영]Tip: 워밍업 스터디 클럽을 참여하게 되면 [할인쿠폰]으로 강의를 할인 된 가격에 수강할 수 있다! 3주차 강의 수강3주차를 되돌아 보며..이번주 강의는 전반적으로 React와 친해지는(?) 시간을 가지게 된거 같다.React로 실제 화면을 구현해보고 각종 함수와 툴들을 사용해서 개발의 편의성을 높이는 것을 체감할 수 있었다.특히 주어진 미션과제를 수행하면서 React의 동작성, 상태관리에 대해서 더 깊게 알 수 있을 시간이 되었다.사실 이번주는 강의를 많이 듣지 못했다ㅠ 현업과 병행하다 보니 퇴근하고 강의 듣는다는 게 쉬운 일은 아니다. 특히 이번주는 시험검증 기간이라 이슈가 조금 많이 발생해서 야근도 잦고 그랬다... (모든 직장인, 학생 분들 화이팅입니다ㅠ 열심히 살아가봐요!) 그리고... 미션과제도 밀려서 주말에 몰아서 구현을 했다.미션과제를 수행하면서 중간중간 필요한 지식들은 강의를 들으면서 기록하며 학습을 진행했다.Javascript 강의 때와는 다르게 React 는 실습위주 이다보니 강의 내용을 정리한게 많지는 않다. (강의보면서 코딩따라 해보며 기능을 확인하고 미션에 적용하려고 했다)강의 내용을 다시 정리해보며..(주로 개인적으로 새롭게 알게된 것, 다시 기억해야하는 것들 위주로 정리했다)리액트는 프레임워크가 아니라 라이브러리React는 라이브러리, Vue, Angular는 프레임워크왜 라이브러리? 리액트는 전적으로 UI를 렌더링하는 것에 관여하기 때문상태관리, 라우팅, 테스트 등등을 위해 다른 라이브러리가 추가적으로 필요함 (vue, angular는 이런 것들이 이미 포함되어 있음)프레임워크: 어떠한 앱을 만들기위해 필요한 대부분의 것을 가지고 있는 것라이브러리: 어떠한 특정 기능을 모듈화 해놓은 것프레임워크는 라이브러리의 집합리액트 컴포넌트 - Component리액트 앱을 이루는 최소한의 단위, 여러 컴포넌트를 조합하여 하나의 페이지가 완성되는 것클래스형 컴포너트 - class component함수형 컴포넌트 - funcional component브라우저가 그려지는 원리와 가상돔리액트의 주요 특징 중 하나가 가상돔을 사용하는 것이다웹 페이지 빌드 과정 (CRP) - Critical Render Pathbrowser가 서버에서 페이지에 대한 HTML문서를 응답으로 받고, 해당 문서를 읽는다. 그 후 스타일을 입히고 뷰포트에 표시하게 된다DOM tree생성 → Render Tree생성(화면에 표시되는 모든 노드의 콘텐츠 및 스타일 정보를 포함) → Layout(reflow) → Paint(화면에 그리기)화면에서 DOM에 변화가 생기면 Render Tree부터 다시 랜더링 해야한다는 문제점!! → 비효율적→ 가상돔: 실제 DOM을 메모리에 복사해준 것데이터가 바뀌면 가상돔에 랜더링되고 이전에 생긴 가상돔과 비교해서 바뀐 부분만 실제 돔에 적용 시킴. 바뀐 부분을 찾는 과정을 diffing이라고 부르고, 바뀐 부분만 실제 돔에 적용시켜주는 것을 재조정(reconciliation)이라 한다.리액트 구조 살펴보기이름이 수정되면 안되는 파일public/index.html → page템플릿src/index.js → 자바스크립트의 시작점SPA는 어떻게 가능하게 되나?HTML5에서 History API를 사용해서 가능하게 함. (실제 react-dom에서 사용하는 방식)JSXJavascript syntax extension자바스크립트의 확장 문법이다React에서 의무적으로 사용하는 것 XJSX는 babel을 통해 변환된다컴포넌트에 여러 엘리먼트 요소가 있다면 반드시 부모요소 하나로 감싸줘야한다.JSX Keykey는 리액트가 변경, 추가 또는 제거된 항목을 식별하는데 도움이 된다. 요소에 안정적인 ID를 부여하려면 배열 내부의 요소에 키를 제공해야 한다 (key값을 기준으로 바뀐 가상돔을 감지한다)key에는 unique한 값을 넣어주자. index는 비추!React State컴포넌트의 렌더링 결과물에 영향을 주는 데이터를 갖고있는 객체이다. state가 변경되면 컴포넌트는 리랜더링(re-rendering)된다. 또한 state는 컴포넌트 안에서 관리된다.React HooksReactConf 2018에서 발표된 class없이 state를 사용할 수 있는 새로운 기능리액트의 생명주기react hooks를 통해 함수형 컴포넌트에서도 생명주기를 사용할 수 있게 데이터를 가져와서 컴포넌트 시작하자 마자 API호출하고 많은 부분을 사용할 수 있게되었다→ 코드가 간결해짐 (useEffect를 통해 componentDidMount, componentDidUpdate, componentWillUnmount를 다 수행해줌)HOC(higher order component)를 Custom react hooks로 대체해서 너무 많은 wrapper컴포넌트를 줄이게 된다.→ HOC: 화면에서 재사용 가능한 로직만을 분리해서 component를 만들고, 재사용 불가능한 UI와 같은 다른 부분들은 parameter로 받아서 처리하는 방식 (wrapper가 많아지면 데이터의 흐름을 파악하기 어려워짐)State, Propsstate해당 컴포넌트 내부에서 데이터를 전달할 때state는 mutable 변경가능하다state 이 변하면 re-render된다props상속하는 부모컴포넌트에서 자식 컴포넌트로 전달한다읽기전용으로 작년 컴포넌트 입장에서는 변하지 않는다. (변하게 하고자 하면 부모 컴포넌트에서 state를 변겨해줘야한다)구조 분해 할당(Destructuring)배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있게 하는 JS표현식클린코드를 위해 객체, 배열에 대해 구조 분해 할당Redux상태 관리 라이브러리redux데이터는 하나의 방향으로만 흐른다flow: react component에서 어떠한 이벤트가 발생하면 → Action 객체(어떤 작업을 수행할 것인지 description을 담고 있음)를 통해 reducer함수에게 액션을 발생하라고 한다.(dispatch) → reducer함수에서 로직 처리 → store내부 상태 업데이트: redux store state update → 새롭게 업데이트 된 상태를 이용해서 다시 렌더링 → component re-renderingRedux Tookitredux로직을 작성하기 위한 공식 권장 접근 방식 강의 내용을 들으면서 아쉬웠던 점..앞서 언급한 대로 이번주에는 강의보다는 실습 과제에 조금 더 초점을 두었다. 미션을 수행하면서 모르는 부분을 강의에 가서 찾아 듣고 다시 구현하고 하는 식으로 학습을 진행했다.React는 이론 보다는 실제 사용하고 구현해보는게 더 빠르게 성장하는거 같다. 특히 상태관리, 페이지 라우터 등 강의에서도 알려주시지만, 미션과제를 수행하면서 직접 기능을 동작시킬 수 있게 구현하는게 더 깊이 이해할 수 있었던 거 같다.아쉬운점은ㅠ 강의를 많이 못 들었다는거? 수료식까지 아직 시간이 조금 남았으니까 남은 강의도 열심히 들어보겠다.3주차 미션 완료React미션 두 개(포켓몬, 쇼핑몰)를 토요일 벼락치기로 수행했다.간단하다고 생각했는데 React가 아직 익숙하지 않아 중간중간 오류가 많이 발생했었고, 특히 프론트엔드는 화면이 바로 눈에 보이다 보니까 CSS 스타일 적으로 내맘대로 적용되지 않아서 화가났다(?). 그래도 tailwindcss에서 만들어진 component, icon들을 활용해서 미션을 수행완료할 수 있었다.React - Mission3: 포켓몬 도감 앱 만들기Demo: https://pokemon-mission-3.netlify.app/Source Code: https://github.com/rim0703/React-study/tree/react/mission3/React/3-pokemonpokeAPI 라는 오픈소스 API를 제공하는 곳이 있어서 외부API를 호출해서 구현했다API문서가 얼마나 중요한 역할을 하는지 이번 미션에서 깊이 깨달았다.. ㄷㄷ(백엔드 화이팅)(지연로딩 적용) 사용자의 화면 로딩 속도를 고려하면 첫 화면에 20개씩 불러오도록 했고, 스크롤이 하단에 도달하면 추가로 호출하도록 구현했다.(Trick) 시연화면에서 로딩이 출력되는데 사실 화면이 너무 빨리 렌더링 완료돼서 로딩이 보이지 않아 로딩 동글뱅이를 보기 위해 setTimeout으로 1초 지연을 넣었다 ^^;;(검색창) 조금 버그가 있다. 페이지를 영문이 아닌 한글로 만들다보니 검색도 한글로 하도록 했는데 상태를 상위-하위 컴포넌트 간에서 전달하다 보니 조금 어려웠다. 또한 API문서 기본은 영문으로 제공해서 영문과 한글을 매칭시키는 별도의 작업도 필요했다. redux를 사용해서 검색창을 상단 navigation바에 위치해보려고 한다.  React - Mission6: 리덕스를 이용한 쇼핑몰(버거몰) 앱 만들기Demo: https://burger-mall-mission-6.netlify.app/Source Code: https://github.com/rim0703/React-study/tree/react/mission6/React/6-shopping-mall1주차 미션 내용에서 언급했듯이.. JS강의에서 만들었던 메뉴 화면을 그대로 따와서(CSS공부가 아니니까^^) 쇼핑몰과 비슷한 기능들이 있는 버거몰을 만들어보았다.(컴포넌트화) HTML,JS,CSS로 구현된 내용을 React로 옮겼고, 원래 파일 1개씩 정의된 내용을 React Component로 분류하였다.(장바구니-localstorage) DB를 별도로 연동된게 아니여서 localstorage를 활용해서 장바구니를 구현하였다.(Redux) 리덕스 강의 내용에 기반한 프로젝트이지만 Redux강의를 듣고 이해가 잘되지 않아서 우선 기본 방식으로 앱을 구현하였다. Redux공부를 조금 더 하고 리팩토링을 진행할 예정이다. 마지막으로 3주차 회고이제 수료까지 얼마남지 않았는뎅,, 남은 시간동안 강의를 열심히 들어야겠다.너무 빡빡한 일정이었지만 3주차까지 버텨오고 React에 대해 친해질 수 있는 시간이되어서 뿌듯하다.현업에서 Vue를 사용하다 기술 전환을 위해 React를 도입한다고 해서 급하게 스터디에 신청해서 힘들지만 조금만 더 버티면되지 않을까? 직장과 병행하니.. 이게 쉬운일은 아닌거 같다. 모든 직장인들 화이팅입니다!흑흑.. 미션 기능 중에 동작하지 않는게 있어서 수정하고 다시 배포하고 이제 자러간당ㅠㅠ다음주는 더 성장한 내가 되어 있기를!! 모두 완주까지 화이팅입니다~(2025.03.23 새벽 03:26)<끝>

프론트엔드워밍업스터디3기프론트엔드미션JSJavascriptReactRedux회고

강지원

[인프런 워밍업 스터디 클럽 2기 FE] 강지원 3주차 발자국

따라하며 배우는 리액트 A-Z (7~13강) Day 11 (리액트 테스트 경험하기) TDD (Test Driven Development)개발 전 테스트 코드를 먼저 작성하는 방법론 순서테스트 코드를 작성 → 실행 (당연히 실패) → 딱 이 테스트 코드를 통과할 만큼의 코드만 작성 → 성공 → 다른 테스트 코드 작성으로 이동전부를 다 한 다음에 리팩토링 작업을 실행여기서 문제가 된다면 다시 테스트 코드를 확인하고 수정함 TDD의 장점소스 코드에 안정감을 줌디버깅 시간과 개발 시간이 줄어듦시스템 전반적인 설계 향상 (클린 코드가 나올 확률이 높아짐)개발 집중력 향상 (테스트를 하나씩 깨나가면서 개발할 수 있기 때문)  Day 12 (NextJS, 타입스크립트)내용을 복습하면서 원래 알고 있던 것 + 새로 알게 된 내용을 공부하는 방식으로 공부했다.특히 TS의 타입 들을 코드로 정리하면서 어떤 타입이 있었는지 다시 새길 수 있었다. Next.jsReact의 SSR을 쉽게 구현할 수 있게 도와주는 간단한 프레임 워크 특징 Full-StackFile-based RoutingSEO, Image, Font OptimizationServer Side RenderingHybrid Rendering CSR (Client Side Rendering)리액트만으로 프로젝트를 만들면 발생 → 렌더링 하는 주체가 클라이언트 (브라우저) 장점한번 로딩 되면, 빠른 UX 제공서버의 부하가 작음 단점페이지 로딩 시간(TTV)이 김 (FCP가 오래 걸린다고도 함)자바스크립트 활성화가 필수임SEO가 힘듦보안에 취약 (모든 react 라이브러리, js 소스 코드를 다 다운 받아야 하기 때문에)CDN(Content Delivery Network)에 캐시가 안됨 → 이러한 많은 단점들을 해결하기 위해서 나온 것이 SSR SSR (Server Side Rendering렌더링 하는 주체가 서버렌더링 되는 순간 : 요청 시 렌더링 (미리 해두지 않음) 장점페이지 로딩 시간(TTV)이 빠름자바스크립트 활성화 여부가 필요 없음SEO 최적화가 좋음보안이 뛰어남CDN에 캐시가 됨실시간 데이터를 사용!사용자 별 필요한 데이터를 사용함 (요청 시 렌더링 하기 때문에 요청하는 사람에 맞게 데이터 제공이 가능) 단점비교적 느릴 수 있음서버에 과부하가 걸릴 수 있음 (몇 천명의 페이지를 요청 시 마다 계속 만들어야 하기 때문에)CDN에 캐시가 안됨 (요청마다 새로운 페이지를 만들기 때문에) Typescript 타입 : value가 가지고 있는 프로퍼티나 함수를 추론할 수 있는 방법JS의 dynamically type이 야기할 수 있는 runtime error를 해결하기 위해 statically type을 적용 시킨 언어 사용하는 이유Typescript는 JS코드를 단순화하여 더 쉽게 읽고 디버그할 수 있도록 함Typescript는 코드 유형 검사를 통해 JS를 작성할 때 고통스러운 버그를 피할 수 있도록 도와줌  Day 13 (리덕스 학습하기 및 리액트 19) ReduxJS 어플리케이션을 위한 상태 관리 라이브러리 data flowAction간단한 JavaScript 객체수행하는 작업의 유형을 지정하는 'type' 속성이 있으며 선택적으로 redux 저장소에 일부 데이터를 보내는 데 사용되는 'payload' 속성을 가질 수도 있음 Reducer어플리케이션 상태의 변경 사항을 결정하고 업데이트 된 상태를 반환하는 함수store 내부의 상태를 업데이트함 Redux Store어플리케이션의 전체 상태 가지고 있는 객체내부 상태를 변경하는 유일한 방법은 해당 상태에 대한 Action을 전달하는 것 Redux 미들웨어action을 dispatch하고 reducer에 도달하는 순간 사이에서 사전에 지정된 작업을 실행할 수 있게 해주는 중간자 Redux Thunk비동기 작업을 할 때 많이 사용하는 방법Redux Thunk도 리덕스 미들웨어액션 내부에서 다양한 작업을 할 수 있게 해줌 Redux ToolkitRedux 로직을 작성하기 위한 공식 권장 접근 방식Redux 코어를 둘러싸고 있고, Redux 앱을 빌드하는 데 필수적인 패키지와 기능이 포함되어 있음Redux 작업을 단순화하고 일반적인 실수를 방지하며, Redux 앱을 더 쉽게 작성할 수 있도록 도와줌 느낀 점 redux의 기본 사용 법을 처음으로 배우는 것이라 신기하고 어렵게 느껴졌다. 강의를 따라가면서 기초에 집중하려고 노력했는데, 처음 배운 개념을 이용해서 앱을 만드려니 꽤나 막막해서 시간이 많이 걸렸다. 앞으로 더 능숙해지고 싶다. 일주일 회고스터디 중간에 몸이 3일 동안 아팠어서 시간이 많이 없었지만 열심히 달려서 겨우 완주 조건까지 달성했다.매일 새벽까지 과제를 개발한 덕에 JS 과제 5개와 React 과제 3개를 해냈다. 모든 과제를 해내면 신입 역량 이상이라고 하셨었는데 나는 아직 신입 역량 정도였나 보다. 아쉽다.그동안 머릿속에 스터디만 가득한 채로 3주를 보냈는데 막상 끝나려고 하니까 아쉽지만 3주전의 나와 지금의 나를 비교했을 때 많은 성장을 이뤄낸 것 같아서 뿌듯하다.이번에 알게 된 부족한 점들을 바탕으로 앞으로의 공부 계획을 세워나갈 예정이다.정말 의미 있는 시간이었고, 꼭 필요했던 시간이라고 생각한다. 강의 출처강의 주소(React) : https://www.inflearn.com/course/따라하는-리액트/코치님 성함 : John Ahn

ReactNextJSTypescriptRedux프론트엔드인프런스터디3주차

RTK 쿼리는 SSR을 하고 싶어!

서론요즘 RTK 쿼리와 함께 Nextjs에서 SSR을 적용하는데 꽤 시간을 들이고 있습니다. 물론 리액트 쿼리라는 걸출한 패키지가 존재합니다. 그런데 어쩌겠습니까, 저의 마음 속 한 켠에는 이미 RTK 쿼리에 대한 열망이 불타올랐던 겁니다!... 사실은 리덕스로 노는 와중에 찾아볼 게 있어서 문서에 들어갔다가 영업당한 것에 가깝습니다. 이 글을 작성할 동기를 제공한 리덕스 공식 문서에게 크나큰 박수를 보내주시면 감사하겠습니다.그래서 사용하는 김에 SSR까지 적용해보면 어떨까? 라는 생각을 했습니다. 그렇습니다, 여러분. 오늘 글의 주제입니다.RTK 쿼리는 외로워요SSR의 원리는 간단합니다. 클라이언트사이드에서 요청을 보내면 서버사이드에서 원래 클라이언트사이드에서 했어야 할 작업들을 대신 수행해 주는 겁니다. 그리고 그 결과가 적용된 말끔한 HTML을 응답해 줍니다.Nextjs는 이런 작업을 아주 멋지게 처리해 줄 getServerSideProps라는 함수를 제공합니다. 해야 하는 작업을 수행한 후 얻은 데이터를 페이지 컴포넌트의 props로 넣어 주는거죠.이 쯤에서 문제가 생깁니다. 우리는 props가 아닌 RTK 쿼리를 사용해야 하기 때문입니다. getServerSideProps 함수 안에서 RTK 쿼리를 디스패치하는 부분까지는 가능합니다. 그러나 클라이언트사이드의 RTK 쿼리는 서버사이드에서 무슨 일이 생겼는지 알지 못합니다. 서버사이드의 RTK 쿼리 혼자 외롭게 남아있게 되는 겁니다.그럼 어떻게 해야 할까요? 어떤 방식으로 서버사이드의 RTK 쿼리 스토어를 클라이언트사이드로 전달해 줄 수 있을까요?next-redux-wrappernext-redux-wrapper 패키지가 나설 차례입니다. 이 패키지는 서버사이드의 스토어를 클라이언트사이드 스토어에 덮어 씌워 줍니다. 서버사이드에서 실행된 RTK 쿼리를 클라이언트사이드로 가져오는 게 가능해진다는 의미이기도 합니다.store.tsnext-redux-wrapper를 적용하기 위해 약간의 수정이 필요합니다.// store.ts /** * configureStore를 감싸는 makeStore 함수를 작성 * @param context `next-redux-wrapper`에서 제공하는 context */ export const makeStore = (context: Context) => { return configureStore({ reducer: { something: somethingReducer, [rtkQueryApi.reducerPath]: rtkQueryApi.reducer, }, middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat( rtkQueryApi.middleware, ), }); }; // makeStore 함수의 ReturnType를 가져와 타입 작성 type AppStore = ReturnType<typeof makeStore>; export type AppState = ReturnType<AppStore["getState"]>; export type AppDispatch = AppStore["dispatch"]; /** * `next-redux-wrapper`에서 제공하는 `createWrapper` 함수로 만들어진 wrapper를 export */ export const wrapper = createWrapper<AppStore>(makeStore, {debug: true}); // ^ // 작성된 makeStore 함수를 넘김다음과 같이 리덕스 스토어를 설정합니다. configureStore 함수로 만들어진 store를 바로 쓰는 대신 next-redux-wrapper 패키지에서 제공하는 createWrapper 함수로 wrapper를 만들어 사용합니다._app.tsx// _app.tsx function MyApp({ Component, pageProps }: AppProps) { return ( <Component {...pageProps} /> ); } // `store.ts`에서 생성된 wrapper로 MyApp 컴포넌트를 감쌈 export default wrapper.withRedux(MyApp)react-redux 패키지의 Provider 컴포넌트로 감싸던 기존의 방식 대신 wrapper.withRedux 함수로 MyApp 컴포넌트를 감쌉니다.좋습니다. next-redux-wrapper를 사용할 준비가 끝났습니다.SSR이제 RTK 쿼리를 서버사이드에서 사용해봅시다. 생각보다 정말 간단합니다.// store를 쓰기 위해 작성한 `wrapper`의 `getServerSideProps` 함수를 사용함 export const getServerSideProps = wrapper.getServerSideProps( (store) => async (context) => { // RTK 쿼리 디스패치 store.dispatch(rtkQueryApi.endpoints.getSomething.initiate({})); // 실행된 것이 끝날 때까지 대기 await Promise.all(cropApi.util.getRunningOperationPromises()); return { props: {}, }; } );다음과 같이 RTK 쿼리를 서버사이드에서 실행할 수 있습니다.하지만 문제가 생기게 됩니다. 클라이언트사이드의 스토어는 아무 것도 바뀌지 않았습니다. next-reudx-wrapper 패키지를 설정하는 과정에서 문제라도 생겼던 걸까요?RTK Query 설정이런, RTK Query의 api를 확인해 보니 한 가지 설정을 빠뜨렸습니다.export const rtkQueryApi = createApi({   ...   // 서버사이드에서 실행된 쿼리를 클라이언트에 hydrate   extractRehydrationInfo(action, { reducerPath }) {     if (action.type === HYDRATE) {       //                ^       //   next-redux-wrapper에서 제공          // 실행된 쿼리(reducerPath)를 리턴       return action.payload[reducerPath];     }   }   ... });HYDRATE 액션 때 서버사이드에서 실행된 쿼리를 전해주는 extractRehydrationInfo 함수를 설정해줘야 합니다.혹시 다 설정해줘야 하냐구요? 맞습니다. 서버사이드에서 실행될 예정인 쿼리와 뮤테이션을 다루는 createApi 함수는 모두 같은 설정을 해야 합니다. 안하면 쿼리와 뮤테이션들이 외로워 합니다.확인해봅시다이제 제대로 데이터가 전해졌는지 확인해봅시다.redux devtools에 들어가 액션을 살펴보세요. __NEXT_REDUX_WRAPPER_HYDRATE__ 안에 원하는 데이터가 들어 있다면 성공입니다.사용const ExampleComponent = () => { const { data } = useGetMyCropsQuery({}); return ( { data ? <div>{data.something}</div> : <div>...</div> } ) }기존과 같이 훅으로 사용합니다.TMI왜 Provider 컴포넌트를 사용하지 않나요?next-redux-wrapper가 Provider 컴포넌트의 역할을 합니다.도움이 됐나요?날씨가 추우니 손도 어는 기분이네요. 여러분들은 따뜻한 손으로 개발하고 있으시죠?그렇다고요? 좋습니다, 오늘도 즐거운 개발 되세요!References[createApi | Redux Toolkit # extractRehydrationInfo](https://redux-toolkit.js.org/rtk-query/api/createApi#extractrehydrationinfo)[Server Side Rendering | Redux Toolkit](https://redux-toolkit.js.org/rtk-query/usage/server-side-rendering)[GitHub - kirill-konshin/next-redux-wrapper: Redux wrapper for Next.js](https://github.com/kirill-konshin/next-redux-wrapper)  

프론트엔드SSRRTKQueryReduxReduxToolkitReduxToolkitQueryNextjs

채널톡 아이콘