⚙️ Project13 React, Tailwind에서 다크 모드, 반응형 웹사이트 구현하기 이번 포트폴리오 작업을 진행하면서 이전부터 꼭 해보고 싶었던 기능 다크모드와 반응형 웹사이트를 구현을 해보기로 마음 먹어서 과정을 기록하면 좋을 것 같았습니다. 특히 Tailwind CSS는 반응형 웹 디자인 및 다크 모드 지원과 관련하여 많은 편의성을 제공하는 강력한 CSS 프레임워크 중 하나입니다. 🌙 다크모드 먼저 tailwind.config.js에 아래와 같이 추가해줍니다. class : 수동으로 변경 할 수 있도록 html 태그의 className 속성에 dark가 추가되었을때, 다크 모드 스타일이 적용 media : 운영체제 설정에 따라 다크 모드 스타일이 적용 됨 기본적으로는 media 속성을 사용하지만 darkMode를 class로 설정해주면 class를 add, remove하는 것을 통해.. 2024. 1. 22. React에서 가로로 스크롤 (with GSAP) 포트폴리오 작업을 하면서 내가 만든 프로젝트들을 가로로 길게 배치하여 스크롤을 내리면 가로로 스클롤이 되게 구현하고 싶었습니다. 구글링을 하다가 많은 사람들이 사용하는 GSAP이라는 라이브러리를 사용하게 되었습니다. ✅ GSAP GSAP 라이브러리는 가로 스크롤 뿐만 아니라 다양한 애니메이션을 제공하는 강력한 라이브러리입니다. https://gsap.com/ Homepage | GSAP GSAP is an industry standard JavaScript animation library from GreenSock that lets you craft high-performance animations that work in every major browser. gsap.com ⚙️ 구현 방법 npm ist.. 2024. 1. 6. 찜하기 기능 수정 🔽 이전 글 https://lotusstudy.tistory.com/156 이 전에 찜하기 기능 관련하여 백엔드 분과 날짜 조율을 하고 API 관련하여 얘기를 나누었습니다. 백엔드분도 수긍하여 바로 수정해 주셨고 수정한 api 동작 흐름은 상품의 하트를 클릭하면 찜한 상품의 상품 id가 담긴 배열을 받습니다. 그 배열에 현재 클릭한 상품 id가 있다면 찜하기 해제(delete)를 하고 없다면 찜하기(post)를 하는 로직입니다. 1. 찜한 상품 id 배열을 받아오는 코드 ⚙️ 처음 접한 개념 enabled : useQuery 훅을 사용할 때 해당 옵션을 설정함으로써 쿼리를 자동으로 실행하거나 중단할 수 있습니다. true일 때 : 쿼리가 자동으로 실행됩니다. 이는 컴포넌트가 처음 렌더링될 때 또는 re.. 2023. 7. 31. infinite scroll 이번 프로젝트를 진행하면서 저는 상품 CRUD 관련 페이지를 만들고 있습니다. 원하는 카테고리를 선택하고 관련 상품들이 나오면 해당 상품들을 무한 스크롤로 구현될 수 있게 해보려고 합니다. 저는 useRef와 React Query의 옵션 중 하나인 isFetching을 사용하여 무한 스크롤을 구현해 보았습니다. 아직 많은 상품들이 등록되어 있지 않아 size는 5로 지정하였습니다. 위의 코드는 isFetching을 의존성 배열로 둔 useEffect의 콜백함수 안에는 handleScroll이라는 함수를 정의하였습니다. ⚙️ 처음 접한 개념 Element.getBoundingClientRect() :엘리먼트의 크기와 뷰포트에 상대적인 위치 정보를 제공하는 DOMRect 객체를 반환합니다. 반환 값은 pad.. 2023. 7. 19. React 위도 경도 얻어와 사용자 위치 등록 오늘은 react에서 위도와 경도를 얻어와서 사용자의 위치를 구하는 것을 기록하려고 합니다. 사용자 위치를 구하는 기능은 이전에 Vanilla JS로 구현을 해본 경험이 있어 팀원들에게 제가 할 수 있다고 말해서 제가 맡게된 역할입니다. 하지만 이번엔 React를 통해 구현할 예정이기 때문에 이 과정을 기록하면 좋을 것 같습니다. 🤔 Geolocation API Geolocation API는 사용자의 위도, 경도를 제공해 줍니다. HTML에서 자체적으로 제공해주는 API입니다. npm에 설치해서 사용할 수도 있지만 복잡하지 않아 직접 구현해 보았습니다. https://www.npmjs.com/package/react-hook-geolocation react-hook-geolocation React hoo.. 2023. 7. 18. 합성컴포넌트를 이용한 모달 이번 프로젝트 진행 중 공통 컴포넌트를 구현해야 하는 역할을 맡았는데 그중 모달이 은근히 헷갈렸습니다. 부트캠프 진행 중 모달을 만들어보긴 하였지만 완벽히 이해하지는 않았는지 이번에 다시 하려고 하니 감이 잘 오지 않았습니다.! 이번 기회에 블로깅 하면서 차근차근 익혀나가 보려구요!! 처음에 제가 진행한 방식은 *Portal을 사용하여 z-index 처리 없이 모달을 편하게 처리해 주는 방식으로 구현하였습니다. *Portal : 부모 컴포넌트의 DOM 계층 구조 바깥에 있는 DOM 노드로 자식을 렌더링 하는 방법. setOnModal(false)} /> {children} setOnModal(false)}>{leftButtonText} {rightButtonText} 모달은 위의 코드처럼 icon(MdE.. 2023. 7. 18. 상품 이미지 여러장 등록하기 / img파일, text를 formData로 보내기 상품 이미지 여러 장 등록하기 제가 이번 프로젝트에서 맡은 역할 중 빌려줄 상품에 대한 정보를 등록하는 페이지가 있습니다. 바로 저희가 많이 사용했던 번개장터나 당근마켓처럼 사진을 업록드 하고 상품에 대한 글을 적는 페이지입니다. 먼저, 사진을 여러 장 업로드할 수 있는 기능을 만들어 보려고 합니다. 저는 우선 사진을 최대 5장까지 업로드할 수 있도록 하고 싶었습니다. 5장으로 상품 사진을 보여주기에 충분하다고 생각하였고 5장이 넘어가면 정해진 사이즈를 벗어난다고 생각하였기 때문입니다. 상품을 등록할 input 태그를 만들어 file을 첨부할 수 있게 하였고 label을 통해 커스터마이즈를 하였습니다. handleAddImages의 함수에서는 imageLists에 상품 사진을 올린 사진을 저장합니다. i.. 2023. 7. 16. 찜하기 기능 구현 (with 500error, 코드 문제점) const addInterestMutation = useMutation((productId: string) => axios .post(`${process.env.REACT_APP_API_URL}/api/members/interests`, { memberId: '1', productId: productId, }) .then((res) => { const { data } = res; setInterestId(data.interestId); }), ); const removeInterestMutation = useMutation( (interestId: string) => axios.delete(`${process.env.REACT_APP_API_URL}/api/members/interests`, { data.. 2023. 7. 16. React Hook Form 사용하기 제가 이번 프로젝트에서 빌려줄 상품에 대한 정보를 올리는 페이지를 만들어야 했습니다. 처음엔 form 태그를 이용하여 input 값을 전송하려고 하였습니다. 하지만 해당 상품 정보에 필수적으로 입력해야 하는 input 항목이 상품 사진, 최소 대여시간, 고정금액, 1일 당 추가금액, 연체료, 제목, 내용, 카테고리 총 8개의 항목을 적어야 했습니다. 이렇게 되면 하나의 항목이 변경될 때 마다 실시간으로 동기화되고 리렌더링이 됩니다. 이러한 점은 성능과 유지보수 관련하여 좋지 못하다고 생각이 들었습니다. 위의 문제점을 해결하기 위해 저는 React Hook Form 라이브러리를 사용하였습니다. 🤔 React Hook Form 이란? React Hook Form은 React 기반의 폼 관리 라이브러리 중 하.. 2023. 7. 12. [Pre-project] 스택오버플로우 클론 - week1 🧩 준비 단계 프로젝트가 시작한 지 일주일이 지난 시점에 글을 쓴다. 이번에 처음으로 백엔드 분들이랑 진행하는 거여서 굉장히 걱정되고 떨렸다. 팀은 랜덤으로 정해졌다. 간단한 자기소개를 하고 소통할 툴을 정했다. 먼저 디스코드에서는 각팀으로 나누어 회의도 하고 다 같이 모여 회의를 한다. 그리고 코드스테이츠에서 템플릿으로 준 노션도 활용하여 기록도 하긴 하였지만 우리는 이번에 '지라'라는 툴을 선택하였다. 초반에 FE, BE 나눠 사용할 스택을 정했다. FE 쪽은 TypeScript, tailwind, styled-components, RTK 이렇게 사용하기로 했지만 다들 익숙하지 않을 뿐만 아니라 시간이 부족해 JavaScript, styled-components, RTK로 사용하기로 하였다. 그다음 .. 2023. 6. 17. 드롭다운 말풍선 꼬리 만들기 위와 같이 드롭다운 말풍선 꼬리를 만들고 싶습니다. border 속성과 ::before를 조합하여 사용할 수 있습니다. border border 속성은 테두리 두께, 형태, 색상을 설정할 수 있습니다. const dropdown = styled.div` border-top: 15px solid green; border-left: 15px solid red; border-right: 15px solid blue; border-bottom: 15px solid yellow; `; 위의 코드를 적용시키면 아래와 같은 형태를 볼 수 있습니다. border-top: 0px solid green; border-left: 15px solid red; border-right: 15px solid blue; border.. 2023. 5. 25. [ToDo] - 리팩토링 TO Do Page input 창에 글을 입력하고 엔터를 치면 createItem 함수를 실행하게 하였다. 하지만 문제는 createItem 함수 안에서 태그들을 생성하고, 카운팅, 삭제 등 모든 일을 작성하였는데 이렇게 한 함수 안에 모든 기능들을 적으면 코드가 복잡해져 유지보수가 어렵다고 해서 리팩토링이 시급하다고 느꼈다. 🔽 리팩토링 전 createItem 함수 코드 더보기 createItem 함수 안에 있는 코드들인데 길이가 상당히 길고 복잡하고 중복도 많다. const createItem = (content) => { // li 생성 const li_list = document.createElement("li"); li_list.classList.add("todos-display__list");.. 2023. 4. 29. [ToDo] - input checkbox 꾸미기 ToDo page를 만들다가 checkbox 스타일을 바꾸고 싶은데 생각보다 까다롭고(?) 처음 접하는 내용이라 기록해보려 한다. 기존의 input checkbox의 디자인은 이렇다. input[type="checkbox"] { width: 1.563rem; height: 1.563rem; margin-right: 25px; border: 1px solid var(--color-gray); border-radius: 50%; cursor: pointer; position: relative; } 위의 코드에서 모양을 원형으로 해주었는데도 체크 박스의 스타일이 바뀌지 않는 것을 확인할 수 있다. 1. 체크박스 모양 없애기 appearance : 네이티브로 지원되는 모양 해제하거나 추가할 때 사용한다. app.. 2023. 4. 29. 이전 1 다음 728x90