[React] 얕은 복사와 불변성
·
React
개인 프로젝트에서 드래그 앤 드랍 기능을 구현 중이었는데, 의문이 들었다.배열의 순서를 변경하는 과정에서, 왜 Array.from()을 이용해서 얕은 복사를 할까?결론부터 말하면 참조값이 변경되어야 React가 상태 변경을 감지할 수 있기 때문이다.그리고 불변성의 원칙을 지키기 위함이다.그럼 하나씩 더 자세히 살펴보자.얕은 복사를 해서 새로운 배열 인스턴스를 생성하면, 배열 자체는 새로운 참조가 되지만, 배열 내부 객체들은 여전히 원본과 같은 객체를 참조한다.하지만 이렇게 최상위 레벨에서는 새로운 참조값이 생성되지만, 내부 객체는 여전히 원본과 동일한 참조를 공유한다.드래그 앤 드롭 로직같은 경우엔 항목의 순서만 변경하고 항목 자체의 내용은 수정하지 않기 때문에 원본과 같은 객체를 참조해도 상관이 없다...
[React] 외부 클릭 감지 훅 만들기
·
React
모달 안에 있는 드롭다운이 열려있는 상태에서, 모달 내부지만 드롭다운 관련 요소들 외부를 클릭하면 드롭다운이 꺼지고, 모달 외부를 클릭하면 드롭다운과 모달이 함께 꺼지도록 구현하고 싶었다.그래서 아래와 같은 로직을 이용했다. useEffect(() => { const handleClickOutside = (event: MouseEvent) => { const modalContent = document.querySelector('[data-modal-container="true"]'); // 모달 공통 컴포넌트 컨테이너 // 모달 내부 클릭인지 확인 if (modalContent && modalContent.contains(event.target as Node)) { ..
[Axios] 서버에서 사용자가 업로드한 파일을 받아오지 못하는 에러 핸들링
·
트러블 슈팅
express에서 multer를 이용해서 사용자의 프로필 사진 변경 api를 구현하고 있었는데,분명 클라이언트에서는 사진 파일을 정상적으로 받아서 보내는데, 서버에서 계속 undefined로 받는 상황이 생겼다.처음엔 변수명 타입이 잘못되어있었다 (...) 그래서 profileImage -> profileImg 로 일괄 수정했지만 변화가 없었다.이것저것 세세하게 디버깅 해봤는데 원인을 찾지 못해서 골머리를 앓았다... :)그러다 결국 원인을 찾아서 해결했고...범인은 프론...트...이게 문제가 됐던 코드이다. formData를 보내주면서 headers를 Content-Type: multipart/form-data로 설정해주지 않았는데, 그 이유는 브라우저가 formData에 맞는 헤더와 boundary..
[Next.js + Zustand] localStorage hydration 에러 핸들링
·
트러블 슈팅
Next.js와 zustand를 사용하고 있는 프로젝트 진행 중, 서버 컴포넌트 하위의 클라이언트 컴포넌트에서 persist가 적용되어있는 auth store의 유저 아이디 정보를 가져오려고 useAuthStore.getState()를 했더니 오류가 났다.[zustand persist middleware] Unable to update item 'auth-storage', the given storage is currently unavailable.💦 오류 원인 - 서버 환경에서 로컬 스토리지 접근 시도서버 사이드 렌더링 중에는 window 객체와 localStorage가 존재하지 않는다.useAuthStore.getState()를 컴포넌트 최상위 레벨에서 호출하면 서버에서 렌더링될 때 localSto..
[Next.js & React-Query] 서버 컴포넌트에서 QueryClient 호출하기
·
Next.js
Next.js의 서버 컴포넌트에서 prefetchQuery를 사용하기 위해서는 queryClient가 필요하다.매 컴포넌트마다 queryClient를 생성하면 여러 서버 컴포넌트에서 동일한 queryClient에 접근해야될 때 비효율적이므로, queryClient 컴포넌트를 따로 만들어서 관리하는 것이 좋다.그런데 서버 컴포넌트와 클라이언트 컴포넌트에서 queryClient를 호출하는 방식이 다르다.클라이언트에서 쿼리 호출용'use client';import { QueryClient, QueryClientProvider } from '@tanstack/react-query';import { ReactNode, useState } from 'react';interface QueryProviderProps..
[React] 이벤트 핸들러에 함수를 전달하는 방식
·
React
리액트에서 버튼 등 하위 컴포넌트에 이벤트 핸들러를 연결할 때,#1 onDelete()}>삭제이렇게 익명 함수로 감싸서 전달하는 방식을 사용했었는데, #2삭제이렇게 익명 함수로 감싸지 않고 직접 전달하는 방식이 더 효율적이라는 것을 알게 되었다. 이 방법은 onDelete함수 자체의 참조를 전달하는 것이다.물론 두 버튼의 기능에 대해서는 차이가 없다. 두 방식 모두 버튼을 클릭하면 onDelete 함수가 정상적으로 실행된다.#3삭제하지만 위와 같이 사용한다면 onDelete 함수의 결과값을 전달하는 것이 되므로 오류가 난다. 컴포넌트 렌더링 시점에 함수가 바로 실행되기 때문이다.#4 onDelete(item.id)}>삭제그런데 함수에 인자를 넘겨야 할 때는 당연하게도 익명 함수로 감싸서 전달해야 한다. ..