웹_프론트엔드

    [자바스크립트] 객체 불변성(Immutability)이 중요한 이유

    객체 불변성(Immutability)객체가 생성된 후에 내부 상태가 변경할 수 없는 디자인 패턴을 의미한다. 즉, 한 번 생성된 객체는 변경되지 않고 그대로 유지된다는 뜻이다. immutable value vs. mutable value자바스크립트의 원시 타입(primitive data type)은 변경 불가능한 immutable value로, 7가지가 있다.booleannullundefinednumberbigintstringsymbol변경이 불가능하다는 것은 메모리 영역에서 변경이 불가능하다는 뜻이며, 재할당은 가능하다.var str = '가나다'; // 메모리에 문자열 '가나다' 생성. 변수 str은 메모리에 생성된 문자열 '가나다'의 메모리를 가리킴str = '하하하';// 재할당이 가능하다. //..

    [CSS] 이미지 스프라이트 (Image Sprite)

    이미지 스프라이트(Image Sprite)란?여러 개의 이미지를 하나의 이미지로 합쳐서 사용하는 기법. 목적웹 페이지에 이미지가 있을 때 웹 브라우저는 서버에 이미지를 요청한다. 때때로 사용되는 이미지가 많을 경우에는 이 요청 또한 많아지기에 웹 페이지의 로딩 시간이 오래 걸리게 된다. 이미지 스프라이트 기법을 사용하면, 이 요청을 줄여 로딩 시간을 단축할 수 있다. 이미지가 갖고 있는 의미가 적으며 단순 디자인을 위한 이미지를 사용할 때 적합한 기법이다.  위처럼, 여러 개의 이미지를 하나로 합쳐서 background-position을 요리조리 돌려가며 사용한다. 장점이미지 로딩 속도 최적화간결한 마크업변경이 잦지 않은 이미지의 경우 유지 보수 용이단점CSS background-image 속성을 사용하..

    [CSS] IR 기법

    IR(Image Replacement) 기법이란?이미지의 대체 텍스트를 제공하기 위한 CSS 기법으로, 주로 이미지를 볼 수 없는 사용자에게 적절한 대체 텍스트를 제공하기 위함이다. 이미지 스프라이트(Image Sprite) 기법을 사용하는 경우에도 쓰일 수 있다.  위와 같이 img 태그를 사용할 때 alt 속성으로 대체 텍스트를 삽입할 수 있지만, CSS background-image 속성을 사용해서 이미지를 사용하는 경우에는 그럴 수 없다. 네이버에서는 아래처럼 사용했다..blind { position: absolute; clip: rect(0 0 0 0); width: 1px; height: 1px; margin: -1px; overflow: hidden;} 그리고 H5BP(HTML5 Boiler..

    [리액트] gh-pages 배포 후 새로고침시 404 오류

    깃허브 페이지에 리액트 프로젝트를 배포한 후 404 오류가 뜨는 경우가 있다. 루트 디렉토리가 아니라 서브 디렉토리(ex. https://mygithub.github.io/example/서브디렉토리)로 최초 진입하거나, 진입 후 새로고침 할 때 이 현상이 발생하는 것 같다. 해결 방법 1: public 디렉토리에 404.html 생성 해결 방법 2: index.html 내 스크립트 추가 해결 방법 3: Hash router 사용 이는 SEO 최적화에 좋지 않기에 패스.

    [타입스크립트] 배열 내용으로 중복 코드 없이 타입 정의하기

    // 특정한 나라 이름으로 이루어진 배열 type TCountry = "한국" | "태국" | "페루" | "뉴질랜드" | "포르투갈"; const countries = ["한국", "태국", "페루", "뉴질랜드", "포르투갈"]; 위와 같이 특정 값으로 이루어진 배열이 있을 때, 이 배열을 위한 타입을 작성하면 중복 문자열이 생긴다. 이럴 때 아래와 같이 작성하면 중복 문자열을 줄일 수 있다. // 특정한 나라 이름으로 이루어진 배열 const countries = ["한국", "태국", "페루", "뉴질랜드", "포르투갈"] as const; // 배열 내의 나라 이름들로만 만드는 type type TCountry = (typeof countries)[number]; countries 배열을 as ..

    [자바스크립트] 배열 안에 배열이 있을때 flat한 배열로 만들기

    1. 최신 자바스크립트 API인 flat() 사용 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat Array.prototype.flat() - JavaScript | MDN The flat() method of Array instances creates a new array with all sub-array elements concatenated into it recursively up to the specified depth. developer.mozilla.org 2. 직접 메소드 작성해보기 // arr: 배열, d: 차원 const flatDeep = (arr: any[], d = 1..

    [리액트] react-daum-postcode 우편번호 검색 컴포넌트 예시

    import { Button, Container, ModalBody, ModalFooter, Row, } from "@doar/components"; import { Dispatch, SetStateAction, useState } from "react"; import DaumPostcode from "react-daum-postcode"; import { Address } from "react-daum-postcode/lib/loadPostcode"; interface IFindAddress { setAddress: Dispatch; onClose: () => void; } const FindAddress = ({ setAddress, onClose }: IFindAddress) => { const s..

    [자바스크립트] 이미지 URL을 File 또는 FileList로 변환하기

    1개의 이미지 URL을 File 또는 FileList로 변환하기 export const convertImageUrlToFileList = async ( imageUrl: string ): Promise => { const response = await fetch(imageUrl); if (!response.ok) { throw new Error("이미지를 받을 수 없습니다."); } const data = await response.blob(); const ext = imageUrl.split(".").pop() || ""; const filename = imageUrl.split("/").pop() || ""; const metadata = { type: `image/${ext}` }; const fi..

    [리액트] 컴파운드 컴포넌트 패턴으로 작성하는 모달 컴포넌트 (+ dialogue 태그 활용)

    문제 발견: 기존 모달 컴포넌트의 중복 코드 양산 리액트 프로젝트에서 모달 컴포넌트를 만들어 두고 사용할 때마다 매번 아래처럼 모달 상태를 위한 코드들이 양산되었다. // 모달을 보여줄 것인지 아닌지의 boolean 상태 const [show, setShow] = useState(false); // 필요시 모달 상태 핸들러까지... const modalHandler = () => { setShow((prev: boolean) => !prev); }; return ( 모달 내용(children) ) 위처럼, Modal 컴포넌트로 props를 내려주기 위해서 모달을 사용하는 상위 컴포넌트마다 모달 상태 관련 코드를 중복 작성해야 하는 것이다. 이런 컴포넌트 작성 패턴을 '렌더 프롭스 패턴(Render Pro..

    [타입스크립트] 웹뷰 인터페이스 브릿지

    // index.d.ts // Window 객체에 각 네이티브별 인터페이스와 메서드 정의 declare global { interface Window { webkit?: { messageHandlers: { iOSInterfaceGoToScheme: { postMessage: (message: string) => void; }, iOSInterfaceCloseWebview: { postMessage: (message: string) => void; }; }; }; AndroidInterface?: { goToScheme: (data: string) => void; closeWebview: (message: string) => void; }; } } // aos, ios 각각 해당 인터페이스가 있는지 확인..