Toast 알림을 구현하면서 어디서든 간편하게 사용할 수 있도록 하기 위해 전역 상태관리가 필요했다.요즘 Zustand가 핫한 거 같아서 사용해 봤다! (+ 곰이 귀엽기도 하고 ㅎㅎ)추가로 나는 Next.js 14 App router를 사용 중이다. Zustand다른 상태관리 툴과 비교했을 때 장점은Context API와 달리 상태 변경 시 불필요한 리렌더링이 일어나지 않는다.동작을 이해하기 위해 알아야 하는 코드 양이 적다. 한 개의 중앙에 집중된 형식의 스토어 구조를 활용하면서 상태를 정의하고 사용하는 방법이 단순하다.설치# npmnpm install zustand# yarnyarn add zustand 전역상태관리를 통해 Toast 알림 만들기store 생성toast 알림은 여러 개가 나타날 수 있..
useStateconst [state, setState] = useState(initialState)useState는 배열을 반환하고 비구조화 할당을 통해 state, setState를 추출하여 사용한다. 그렇다면 useState는 어디서 오는 것일까? 함수형 컴포넌트는 렌더링이 발생하면 함수 자체가 다시 호출된다. 그렇다면 어떻게 함수가 다시 호출되었을 때 이전의 상태값을 가져올 수 있는 것인가?바로! useState는 closure로 구현되어 있기 때문에 이전의 상태값을 유지할 수 있다!그렇다면 closure란 무엇인가? 이에 대해 먼저 확인해 보자! closure란?mdn에 따르면 함수와 그 주변 상태(lexical environment, 함수가 정의될 때 주변의 스코프와 변수에 대한 정보를 포함하..
recoil, typescript, react 환경에서 모달을 전역 상태에서 관리하는 방법을 알아보자! 문제점. 너무 많아진 모달 관련 상태관리값들많은 모달들이 사용되어모달을 열기 위한 상태관리값들(useState)과 그에 대한 함수들(열고 닫는 함수등)이 불필요하게 많아지고 있었다!마치 아래와 같은 느낌이었다!const App = () => { const [isOpen1, setOpen1] = useState(false) const [isOpen2, setOpen2] = useState(false) const [isOpen3, setOpen3] = useState(false) const [isOpen4, setOpen4] = useState(false) const handleToggle1 = ..
입점사 프로젝트를 진행하며 페이지네이션과 함께 많이 쓰인 것은 필터일 것이다! 각 페이지에서 데이터를 조회하기 위해 필터와 페이지네이션이 사용되었다. 각각의 페이지마다 필터 컴포넌트로 만들면서 그에 대한 로직이 반복되어 이를 개선하고 뒤로가기 또는 새로고침 시 필터값을 유지하는 방법을 알아보겠다! 필터 컴포넌트와 필터 관련 hook 구현하기 필터 컴포넌트 초기 필터값들과 검색, 초기화 시 동작되는 함수를 전달 받는다. 사용자가 입력한 필터값을 내부적으로 관리한다. src/components/filter/deliveryTemplateFilter.tsx interface DeliveryTemplateFilterProps { initialFilterValues: FormState onSubmit: (filte..
지난 글에 이어(Pagination comonent) 오늘은 Pagination component를 잘 관리하기 위한 custom hook에 대해서 소개하겠다 Pagination custom hook 반복되는 페이지 관련 상태관리 로직을 어떻게 처리하지? 입점사 프로젝트를 진행 중이었기 때문에 거의 모든 페이지에 페이지네이션이 들어갔다 이때마다 페이지 관련 상태 관리 로직이 생겨났고 🥲 하나 잘못된 로직이 있다면 다른 부분도 소스 검색해서 똑같이 수정해줘야 했다 비효율적인 일은 없애고자 페이지네이션 관련 로직을 한 곳에서 한 번에 관리하기 위해 custom hook으로 만들어주기로 결심했다 💪 전체 소스 src/hooks/usePageInfo.ts import { useRouter } from 'next..
우리만의 디자인 시스템을 만들고 싶다 새롭게 입점사 프로젝트에 들어가며 디자인시스템대로 컴포넌트를 만들어 회사 내 다른 프로젝트에서도 사용하고 싶었다! 지금까지는 디자인 시스템이 정해져 있는 것이 아니라 그때그때 시안에 맞춰서 작업해서 소스가 더러웠다 이번 기회에 우리만의 디자인 시스템을 만들고자 했다 위처럼 버튼에 대한 디자인 시스템이 정의되어 있다면 색상, 사이즈에 따라 버튼 컴포넌트를 만들면 된다! Button Component 만들기 어떻게 만들면 좋을까에 대해서 고민하며 찾아보다가 velog의 오픈소스를 봤는데 size, color를 따로 정의하고 props로 받는 부분이 너무 깔끔하게 잘되어 있어 이를 참고하여 만들었다 사이즈 스타일링 피그마에 정의된 대로 사이즈를 나누어 각각의 사이즈를 상..
Pagination component 사용 시 아래와 같이 사용한다 const [currentPage, setCurrentPage] = useState(1); const [lastPage, setLastPage] = useState(0); // api 통신 후 값을 업데이트 해줌 const onChangePage = (newPage: number) => { setCurrentPage(newPage) } ... return ( ... ... ) Pagination component에서는 currentPage, lastPage, 페이지를 업데이트할 수 있는 함수를 전달받는다 currentPage와 lastPage가 업데이트될 때마다 화면에 보여줄 페이지 리스트를 계산해 줬다 👍 page가 1페이지인 경우 더..
리액트를 사용하기 위해 cdn을 추가해준다. 개발용 버전 React의 용량 및 성능 최적화된 배포용 버전 나의 경우에는 php 파일이라서 import React, { useState } from 'react';와 같은 방식으로 useState를 import 하는 게 불가능했다. (혹시 가능한 방법이 있다면 알려주세요..ㅎㅎ) 그래서 useState를 사용하기 위해서는 React.useState로 써줘야 한다. 바벨 추가하기 (php 파일에서 리액트 사용하는 법) 아래와 같이 잘 동작한다! https://ko.reactjs.org/docs/cdn-links.html
ButtonTab에서 클릭된 버튼에 따라 초기화, 모든 아이템 이동, 선택된 아이템만 이동하도록 구현했다. 초기화 클릭 시 availableOptions에 emojiMenus를 넣어주고 selectedOptions에 빈 배열을 넣어 초기화시켜줬다. 모든 아이템 이동을 클릭 시 spread 연산자를 통해 availableOptions와 selectedOptions 배열을 병합해 줬다. moveAll(state, action) { if (action.payload === 'left') { // 모든 아이템 왼쪽으로 이동 state.availableOptions = [ ...state.availableOptions, ...state.selectedOptions, ]; state.selectedOptions =..
addComment: (state, action) => { // 어느 게시글에 해당하는 댓글인지 찾기 위해 게시글의 id를 받아와 filter함수로 해당 게시글 찾기 const currentReview = state.data.filter( (review) => review.postNumber === action.payload.postNumber, ); // 해당 게시글에 새로운 댓글 추가 currentReview[0].comments.push(action.payload.newComment); }, addRecomment: (state, action) => { // 해당 게시글 찾기 const currentReview = state.data.filter( (review) => review.postNumbe..