목록분류 전체보기 (89)
신비한 개발사전

Firebase에 앱을 호스팅한다면 원치 않는 외부인으로부터 내 앱의 데이터를 보호할 수 있도록 보안규칙을 작성하게 된다. Firebase에서는 Firestore와 Firebase Storage 각각의 서비스마다 별도로 보안규칙이 필요하다. 초창기에는 Firebase Storage 보안규칙에서 Firestore에 저장된 데이터를 알 방법이 없어서, Firestore 데이터베이스의 데이터를 Storage가 참조할 수 있도록 각종 방법으로 복잡한 함수들을 구현해야 했다고 한다. 하지만 2022년 업데이트 후로는 Storage에서도 Firestore 데이터베이스의 데이터를 활용해 규칙을 작성할 수 있도록 Firestore를 간편하게 참조하는 함수를 사용할 수 있게 됐다. firestore.get 함수로 특정 ..
Next.js 프로젝트에서는 다양한 방법으로 페이지의 route path와 쿼리 파라미터를 읽을 수 있는데, 그중 Pages Router에서 useRouter 훅 외적으로 쓸 수 있는 방법을 정리해봤다. useParams 훅으로 dynamic route값 읽기내 페이지가 dynamic route를 쓴다면 useParams() 훅으로 바로 그 값에 접근할 수 있다. useRouter() 훅의 라우터 객체를 통하지 않고 순수하게 query 객체만 읽을 수 있는 전용 훅이다.// src/pages/[hello]/index.tsximport { useParams } from "next/navigation";export default function Page() { const params = useParams(..
Next.js 13 이상부터 App Router를 사용하면서 내비게이션 동작 방식이 변경됐다. 이전 버전의 pages 디렉토리를 사용하던 Pages Router에서 app 디렉토리를 사용하는 App Router로 전환하려면 라우터 관련 코드를 수정해줘야 한다. useRouter 훅 사용App Router에서도 클라이언트 컴포넌트에 한해 useRouter 훅으로 router를 생성해 router.push() 메소드를 사용할 수 있다. 다만 기존 Pages Router의 "next/router"에서 import하던 라우터를 App Router에서 그대로 사용하게 되면 "NextRouter was not mounted." 오류가 발생한다. App Router 디렉토리에 생성된 컴포넌트의 경우 useRouter..
Next.js를 배우고 여러 자료를 읽으면서 종종 SSR이나 RSC 등의 단어를 접했었는데, 좀처럼 이해되지 않아서 개념을 정리해보기로 했다. Server-side rendering(SSR)서버사이드에서의 서버는 HTML 문서가 호스팅되는 서버를 말한다. 자체 서버가 없을 경우 깃헙 pages에 내 웹앱을 호스팅한다면 깃헙이 서버인 것이고, Vercel 같은 서비스에 호스팅하면 Vercel의 서버를 쓰는 것이다. 일반적으로 React로 웹 프론트엔드를 구현할 경우 컨텐츠가 없는 빈 HTML 문서를 먼저 다운로드 받고, HTML 문서 안에 있는 태그를 읽어 필요한 자바스크립트 파일을 추가로 다운로드해서 DOM 요소들을 자바스크립트를 통해 주입하게 된다. 이러한 방식은 모두 브라우저 단에서만 일어나기 때문..

Material UI(MUI)는 구글의 디자인 프레임워크(Material Design)를 기준으로 하는 리액트 전용 UI 라이브러리다. 디자인 프레임워크는 간단히 말해서 하나의 표준으로 삼는 UI 스타일이라고 보면 된다.MUI는 Material Design을 따라 input, button, select처럼 웹에 흔히 쓰이는 구성 요소들을 컴포넌트화했기 때문에, 커스터마이징에만 익숙해지면 빠르고 간편하게 어디에서나 통용되는 UI 컴포넌트를 활용할 수 있다. MUI 컴포넌트를 내 사이트에 맞게 커스터마이징하는 방법은 다양한데, 그 중 커스텀 스타일을 개별적으로 적용하는 방법과 일괄로 적용하는 방법이 가장 보편적인 것으로 보인다. sx prop 사용 (개별 적용)각 MUI 컴포넌트에는 리액트 컴포넌트의 sty..
리액트 앱에서 setInterval처럼 자동으로 반복 실행되는 함수를 사용할 땐 리렌더링으로 인한 사이드이펙트를 걱정할 수밖에 없다. 내 앱은 1초마다 시간을 세는 타이머 앱인데, 부모 컴포넌트의 상태가 변하면 부모 컴포넌트는 물론 자식 컴포넌트까지 리렌더링되는 리액트의 특성 때문에 타이머와 상관없는 상태 값을 바꿔도 타이머가 리셋되는 현상이 있었다.// 부모 컴포넌트 - TimerContainerconst TimerContainer = () => { const [isRunning, setIsRunning] = useState(false); // 부모 컴포넌트의 상태 const intervalId = useRef(null); const startTimer = () => { setIsRunnin..
참여하고 있는 팀 프로젝트에서 계획에는 없었던 실시간 채팅 기능을 만들기로 결정됐다. 노마드코더에서 Socket.IO로 Zoom 클론코딩을 해봤던 경험이 있어서 자신있게 프론트에서는 내가 웹소켓을 맡겠다고 했으나... 서버쪽 구현을 맡은 멤버가 처음 들어보는 STOMP로 웹소켓을 구현했다고 해서, 같은 웹소켓이지만 완전 새로운 공부를 하게 됐다. STOMP란?STOMP는 Simple(또는 Streaming) Text Oriented Messaging Protocol의 약자로, 웹소켓(WebSocket) 환경에서 돌아가는 HTTP 서브프로토콜이다. 메세지 기반 전송에 특화되어 있어서 실시간 채팅 서비스 등을 구현할 때 사용하기 좋다고 한다. STOMP의 구독—발행 구조가 이해하기 쉬워서 다행히 사용법을 빨..
Intersection observer는 특정 DOM 요소가 트리거로 지정된 다른 DOM 요소와 만났을 때 함수를 실행시켜주는 웹 API 기능이다. 트리거로 지정한 DOM 요소가 있어야 제대로 작동하는 만큼, 이런저런 상태 변화 때문에 리렌더링이 자주 일어나는 리액트 프레임워크에서는 유의해야 할 pitfall이 있다. 사라진 타겟Intersection observer를 활용하기 위해서는 observer가 바라볼 타겟 요소가 필요한데, 리액트에서는 일반적으로 querySelector 대신 useRef 훅에 많이 의존하게 된다.const Component = () => { const ref = useRef(null); // DOM 요소를 저장할 변수 return 내 컴포넌트; // DOM 요소에 ref ..