Tech

· Tech/ReactJS
폼 데이터를 관리하다가 제어 컴포넌트와 비제어 컴포넌트에 대해 공부해보게되었다.📌 제어 컴포넌트와 비제어 컴포넌트제어 컴포넌트리액트 상태에 의해 값이 제어되는 컴포넌트이다. 사용자 입력값으로 자신의 상태를 관리하고 업데이트하고, 상태가 업데이트 될 때마다 컴포넌트는 리렌더링된다.폼 데이터가 상태에 저장되어 있어 데이터의 흐름이 명확하고, 로직 구현도 수월하지만, 빈번한 리렌더링으로 인해 불필요한 api 호출 등 자원 낭비가 발생할 수 있다.import React, { useState } from 'react';function ControlledComponent() { const [inputValue, setInputValue] = useState(''); const handleChange = (ev..
· Tech/ReactJS
📍 기존의 에러핸들링매번 try-catch로 api 통신 에러만 잡아냈을 뿐 에러처리에 대한 진지한 고민을 해본 경험이 없었다. 에러의 종류를 알고 커스텀 에러를 정의해 전역적인 에러 처리를 하고 싶다는 생각이 들었다. 📍 에러 핸들링 방법 선택에러 핸들링 방법은 여러가지가 있다 1. try-catch문- 특정 동작이나 함수 호출에 대한 에러 처리 2. promise catch문- 네트워크 요청 등의 비동기 코드에서 발생한 에러 처리 3. axios interceptor- 네트워크 에러 처리- axios 라이브러리 제공 기능 4. react-query onError- 데이터 fetching 중 발생한 에러 처리- react query 라이브러리 제공 기능 5. error boundary- 하위 컴포넌..
· Tech/ReactJS
📌 문제상황 - 사용자 경험 향상을 위해 상품 상세 페이지 로딩 시간을 줄이고자 상품 데이터 prefetch 도입- 전체 상품 조회 페이지에서 상품 썸네일 이미지에 hover 했을 때 상품 데이터 prefetch 하도록 설계- 마우스 움직임에 따라 불필요한 네트워크 요청 다량 발생  📌 원인 분석 const { handlePrefetchProduct } = usePrefetchProduct({ productId: data.id }); // prefetch 커스텀훅 const handleMouseEnter = () => { handlePrefetchProduct(); }; ;- 마우스가 잠깐이라도 스쳐지나간 경우 (ex 스크롤 시) 스쳐간 모든 상품에 대한 데이터 prefetch 동작 ..
· Tech/ReactJS
🚨 고민 발생해당 컴포넌트는 공통 컴포넌트로 만들어져있다.여러 곳에서 사용되기 때문에 공통 컴포넌트로 분리했던 건데,, 문제가 생겼다.사용처마다 스타일이나 요소 배치 등의 컴포넌트 요구사항이 조금씩 다르는 것이다. 결국 여러 조건을 걸 수밖에 없었고 아래와 같이 꽤 복잡한 공통 컴포넌트가 만들어졌다.const ProductBoardItem = forwardRef( ( { item, children, checkHandler, checkedItems, selectedCnt, isCart }, ref ) => { return ( { checkHandler( checked as boolean, sel..
· Tech/ReactJS
📌 문제상황// 실제 코드는 부가적인 기능으로 코드가 복잡하여 최대한 간소화한 코드를 예시로 사용했다 {[1, 2, 3].map((_) => ( 이름 가격 ))};- Grid 배치로 크기를 자동으로 설정한 grid 아이템 이미지의 로딩 전후로 리플로우 발생 이슈 발견- w-full 과 aspect-square로 높이와 너비 비율을 설정했다고 생각했기 때문에 리플로우 없이 로딩 될 것이라 생각했지만, 예상과는 다른 동작 결과를 보임  📌 원인 분석=>  aspect ratio을 1:1로 세팅해둔 것이 높이를 설정한 것이라 생각한 게 문제 - 높이가 명시적으로 정해진 것이 아니기 때문에 브라우저는 이미지를 로드하기 전까지 높이를 정확하게 알 수 없음. 즉, ..
· Tech/ReactJS
📍 문제상황장바구니 아이템을 선택한 후 결제까지 완료하면 선택했던 아이템들은 장바구니에서 삭제가 되는 것이 정상 동작이다. 그런데 내 프로젝트에서는 아이템들이 삭제되었다가 장바구니를 다시 열면 재생성되어있는 이슈가 발생했다.삭제된 아이템이 개수가 0인 상태로 재생성되어 있었던 것.. 뭐야 무서워.. 📍 원인 분석콘솔을 통해 이전 장바구니 스토어 아이템 id에 해당하는 상품 데이터(=products)가 남아있는 것이 문제인 것을 찾아냈다.결제 이후 로직은 대충 다음과 같다.1) 결제 성공2) zustand 장바구니 스토어 아이템 삭제3) 장바구니 스토어 아이템 id에 해당하는 상품 데이터(=products) fetch 쿼리 캐싱 무효화 지난 products가 렌더링되는 근본적인 이유는 캐싱 무효화가 동..
· Tech/ReactJS
🔎 비동기적으로 동작하는 setStatesetState로 상태 업데이트 후 예상처럼 값이 나오지 않는 경험을 여러번 했었다. 이유를 찾아보니 호출한 직후 상태가 바로 업데이트 되지 않을 수 있어 상태 업데이트 후 바로 상태값을 확인할 때 예상한 값이 나오지 않을 수 있다는 것이었다. 아래와 같은 방법을 통해 이 문제를 해결했었다.1) useEffect 훅을 사용하여 상태 변경 후에 다음 로직을 실행하도록 설계한다.useEffect(() => { console.log(value); }, [value])2) 이전 상태에 의존할 경우 함수형 업데이트를 통하여 처리한다. const increment = () => { setCount(prevCount => prevCount + 1);}; 🔎 비동기..
· Tech/ReactJS
검색어 입력 중 검색창 외부를 클릭하면 연관 검색어 창이 닫히도록 구현해야 할 일이 생겼다 비슷한 경험으로 과거 모달을 띄우고 모달 외부를 클릭하면 모달이 닫히도록 구현한 적이 있는데, 그때는 어두운 불투명 오버레이 컴포넌트를 깔고 오버레이 컴포넌트에 onClick 이벤트 핸들러를 할당하여 클릭 이벤트가 발생하면 모달을 닫히는 동작으로 간단하게 구현할 수 있었다. 이번에도 동일한 방법으로 투명 오버레이를 깔아 구현해볼까 생각했으나 연관 검색어 창이 활성화 된 상태에서도 지도 확대 축소나 스크롤 등의 이벤트는 정상 동작 해야했기 때문에 불가능하다고 판단하였다. 💭 생각한 두가지 방법 그래서 생각해본 두가지 방법..! 우선 연관 검색어 창이 열려있는 지 닫혀있는지를 boolean으로 나타내는 state값을 ..
· Tech/Styling
TailwindCSS에서 SCSS로 바꾸는 도중 문제가 발생했다.!! 근데 해결하고 보니 어처구니 없는 기초적인 실수라서 다시는 같은 실수를 하지 않기 위해 부끄럽지만 기록해보려 한다. 🚨 문제 발생 토글 버튼을 직접 구현하는 과정에서 css가 적용되지 않는 문제가 발생했다. 원래대로라면 체크박스 형식의 input 선택 유무에 따라 .btnInputBody 와 .btnInputBall의 속성이 바뀌어야 한다. 하지만 속성이 바뀌지 않았다..ㅜㅜ tailwindCSS로는 무난하게 구현했었는데 왜 문제가 발생했을까? import styles from "./input.module.scss" ; .btnInput { input{ display:none } input:checked { .btnInputBody{ ..
· Tech/NextJS
Next13의 서버 컴포넌트를 활용한 data fetching 방법에 대해 공부하다보면 상당부분이 react-query와 흡사하다는 것을 느낄 수 있다. Next13의 data-fetching 그리고 react-query Next 13 버전에서는 fetch() api를 지원하여 서버 컴포넌트 내부에서 data fetching이 좀 더 간편하도록 도와준다. fetch 옵션을 통해 캐싱 , revalidate 등의 기능도 쉽게 사용할 수 있다. 여기서 한가지 궁금증이 생겼다. 그렇다면 next13에서 react-query 사용할 필요가 없을까?? 보통 react-query를 사용하는 이유의 대부분이 next13의 fetch api가 지원하고있는 기능을 사용하기 위해서라고 생각한다. 캐싱, 동기화 및 업데이트..
코어 자바스크립트라는 책을 읽다가 자바스크립트의 작동 원리에 대해 정확히 알고 싶어서 정리하게 되었다. 자바스크립트는 단일 스레드 기반의 언어자 동기적인 언어이다. 즉 순차적으로 한번에 하나의 작업만 처리할 수 있다. 자바스크립트가 실행되는 환경을 자바스크립트 런타임이라고 한다. 자바스크립트에도 다양한 런타임이 있고 각각의 런타임은 환경과 규칙을 정의한다. 브라우저 : 웹 브라우저에서 실행되는 자바스크립트 코드를 위한 환경이다. Node.js : 브라우저 외부에서 자바스크립트가 실행 가능하도록 한다 ( ex 서버 작업 ) React Native : 모바일 앱 개발을 위한 환경이다. Electron : 데스크톱 애플리케이션을 위한 환경이다. 웹 개발을 주로 하는 프론트엔드 개발자로서 웹에서의 동작 방식이 ..
다양한 상태를 관리하며 더 효율적인 상태관리에 대하여 고민하게 되었다. 📌 상태(state)는 무엇인가? 상태는 변하는 데이터이다. 더 정확히 말하자면 리렌더링에 영향을 미치는 변하는 값이다. 리액트에서 페이지는 주로 props나 상태에 영향을 받아 컴포넌트가 변화할 때 리렌더링이 된다. 리렌더링이 유발되면 가상 dom에서 변경된 부분만 캐치하여 실제 dom에 반영되고 우리가 의도한대로 값을 변경하여 보여준다. 📌 상태 관리의 종류 상태는 지역상태와 전역상태로 나뉘고 그에 따른 관리 방법이 다르다. 지역 상태 ( local state ) 관리 한 컴포넌트 안에서 useState를 통하여 상태를 선언하고ㅁ 상위 컴포넌트에서 하위 컴포넌트로 props를 넘겨 전달하는 props drilling 방식의 상태관..
· Tech/ReactJS
📌 구현화면 버튼을 누르면 새로운 input이 생기고, UX를 위하여 새로 생긴 input 창에 바로 focus 되는 방식으로 동작하기를 원했다. 📌 구현내용 1. input Ref 만들기 questions은 나열하는 질문들의 값을 담는 state이고, lastInputRef는 가장 마지막의 input 값을 담기 위한 ref이다. map 함수를 사용하여 questions를 컴포넌트의 인자에 담아 렌더링 시킨다. 이때 lastInputRef도 인자로 담아 보낸다. 이렇게 하면 모든 질문의 input의 값을 거쳐서 결국 마지막에 렌더링 되는 마지막 input의 값이 lastInputRef에 담기게 된다. const [questions, setQuestions] = useState(); const lastIn..
· Tech/ReactJS
구현 화면 태그를 입력한 뒤 엔터를 누르면 등록되는 방식으로 구현하였다. 태그의 X표시를 누르면 태그가 삭제된다. 구현과정 1. 기본 구조 생성 우선 기본적인 디자인을 잡아보자. 입력한 태그를 담을 tags state를 만들어 map 함수를 활용해 뿌린다. const [tags, setTags] = useState([]); {tags.map((tag, idx) => ( {tag} × ))} ; 사용한 스타일 컴포넌트의 css는 다음과 같다. const TagInputContainer = styled.div` ${flexICenter} flex-wrap: wrap; gap: 0.5em; background-color: ${(props) => props.theme.colors.gray.xxs}; paddin..
· Tech/NextJS
Next를 접하면서 생긴 궁금증이 있다. Next는 서버 사이드 렌더링 기법을 사용하고 서버 사이드 렌더링은 서버에서 컴포넌트를 해석하여 사용자에게 보여줄 페이지를 구성한다. 별도로 구현한 백엔드 서버가 있는 것도 아닌데 여기서 서버는 어떤 서버를 말하는 것일까..? 궁금해서 찾아보게 되었다. 📌 서버란? 클라이언트의 요청에 응답하여 서비스를 제공하는 프로그램이다. 이때 제공하는 서비스에 따라 종류가 여러개로 나뉘게 된다. ex ) 웹 서버, db 서버, 캐시 서버 등 📌 웹 서버와 웹 애플리케이션 서버 서버의 다양한 종류가 있지만 관련 핵심인 웹 서버와 웹 애플리케이션 서버에 대해 얘기해보고자 한다. 🎇 웹 서버 ( Web Server ) 클라이언트로부터 http 요청을 받아 정적인 컨텐츠( html,..
닝닝깅
'Tech' 카테고리의 글 목록