전체 글 160

[TypeScript] React에서 rest props의 타입 지정은 어떻게 할 수 있을까?

📍 문제가 발생한 상황 ant design 라이브러리를 사용한 프로젝트에서 Modal 컴포넌트의 modal open 관련 로직을 별도의 ui 컴포넌트로 작성해 사용하는 쪽에서는 관련 로직에 대한 상태 없이도 사용할 수 있게 설계하고자 했다. 처음에 생각한 코드는 다음과 같다. import { Modal as AntdModal } from 'antd'; function Modal({ title, children, ...rest }) { const [isOpen, setIsOpen] = useState(false); return ( setIsOpen(false)} {...rest}> {children} ); } 이렇게 선언한 컴포넌트를 사용부에서는 다음과 같이 호출한다. centered나 width 같은 스..

디자인 패턴 - Flyweight 패턴

비슷한 객체를 대량으로 만들어야 할 때 메모리를 절약할 수 있게 해주는 유용한 패턴 동일한 객체 인스턴스를 여러 번 사용할 수 있도록 하는 패턴으로, 새 복사본을 생성하는 대신 flyweight factory 또는 캐시에서 실제 객체를 공유한다. 이렇게 하면 객체를 생성하는 동안 메모리와 시간을 절약할 수 있다. flyweight는 객체의 set에 대한 공유 인스턴스 역할을 하므로 중복 복사본을 만들지 않고도 해당 객체에 접근할 수 있다. flyweight 패턴은 반드시 고유해야 하는 객체가 아닌 객체를 생성할 수 있는 방법을 제공한다. 이러한 예시로는 문자열이나 이미지처럼 일반적으로 사용되는 항목이 있다. 예제 코드) 책을 추가할 수 있는 앱 - 모든 책은 title, author, isbn 속성을 가..

디자인 패턴 - Mixin 패턴

특정 기능을 구현한 객체나 함수를 다른 객체에 '혼합'하여 그 기능을 추가하는 패턴 다시 말해 특정 행동을 실행해주는 메소드를 제공하는데, 단독으로 쓰이지 않고 다른 클래스에 행동을 더해주는 용도로 사용된다. 상속을 사용하지 않고도 여러 객체나 클래스의 프로토타입에 동일한 기능을 제공할 수 있다. class Dog { constructor(name) { this.name = name } } const dogFunctionality = { bark: () => console.log('Woof!'), wagTail: () => console.log('Wagging my tail!'), play: () => console.log('Playing!'), } // 메소드 복사 Object.assign(Dog.pr..

super 키워드

키워드 super는 다음과 같을 때 사용한다. - super.method(...)는 부모 클래스에 정의된 메소드를 호출한다. - super(...)는 부모 생성자를 호출하는데, 자식 생성자 내부에서만 사용할 수 있다. 1. 메소드 오버라이딩 class Animal { constructor(name) { this.speed = 0; this.name = name; } run(speed) { this.speed = speed; alert(`${this.name}가 속도 ${this.speed}로 달립니다.`); } stop() { this.speed = 0; alert(`${this.name}가 멈췄습니다.`); } } class Rabbit extends Animal { hide() { alert(`${t..

더닝 크루거 효과

달력을 보니 딱 1년 전 오늘, 2022년 10월 20일이 6개월 과정 부트캠프의 개강일이었다. 추석 연휴가 끝나고 지난 보름 가량 내내 씨름하고 있는 기능이 있다. 아직까지 해결하지 못했고, 근 시일 내에 해결할 수 있을 것 같지 않다. 뭐가 문제인지 파악하는 데에만 몇날 며칠의 시간을 보냈다. 이런 시간을 보내면서 부트캠프 과정이 끝나고 취업 준비를 하며 프론트엔드 기능 구현 챌린지를 할 때 시간이 걸릴 뿐 찾아보면 구현하지 못할 기능이 없을 것 같다고 자신만만해 하던 나 녀석이 떠올랐다. 유명한 더닝 크루거 곡선의 우매함의 봉우리를 향해 등반하고 있던 시절이었다고 할 수 있다. 그리고 두세 달이 지난 지금은 문제의 봉우리를 지나 절망의 계곡의 내리막길에 들어선 시간이라고 할 수 있다. 예전 글을 뒤..

돌멩이 하나 2023.10.20

Object.assign()

Object.assign() 메소드는 하나 혹은 그 이상의 source 객체의 열거 가능한 모든 속성을 복사해서 target 객체에 붙여넣은 후 target 객체를 return 한다. const target = { a: 1, b: 2 }; const source = { b: 4, c: 5 }; const returnedTarget = Object.assign(target, source); console.log(target); // Expected output: Object { a: 1, b: 4, c: 5 } console.log(returnedTarget === target); // Expected output: true 복수의 source 객체도 가능하다. // syntax Object.assign(..

디자인 패턴 - Proxy 패턴

Proxy는 다른 사람의 '대리인'이라는 의미 Proxy 패턴은 해당 객체를 직접 다루는 것이 아니라 Proxy 객체와 인터렉션하는 것이다. Proxy 클래스의 두 번째 인자는 핸들러이다. 핸들러 객체에서 인터렉션의 종류에 따른 특정 동작들을 정의할 수 있다. const person = { name: "John Doe", age: 42, nationality: "American" }; const personProxy = new Proxy(person, { get: (obj, prop) => { console.log(`The value of ${prop} is ${obj[prop]}`); }, set: (obj, prop, value) => { console.log(`Changed ${prop} from ..

디자인 패턴 - Provider 패턴

props drilling에 의존하지 않고 컴포넌트가 직접 데이터에 접근할 수 있는 방법 데이터를 사용할 컴포넌트를 Provider로 감싼다. Provider는 HOC(고차 컴포넌트)로 Context라는 객체를 제공한다. React가 제공하는 createContext 메소드를 활용해 Context 객체를 만들어낼 수 있다. Context 오브젝트에 포함된 React 컴포넌트인 Provider는 context를 구독하는 컴포넌트들에게 context의 변화를 알리는 역할을 한다. Provider 컴포넌트는 value라는 prop으로 하위 컴포넌트들에 내려줄 데이터를 받는다. 이 컴포넌트의 모든 자식 컴포넌트들은 해당 provider를 통해 value props에 접근할 수 있다. const DataConte..

디자인 패턴 - Factory 패턴

팩토리 패턴을 사용하면 함수를 호출하는 것으로 객체를 만들 수 있다. new 키워드를 사용하는 대신 함수 호출의 결과로 객체를 만들 수 있는 것이다. 장점 동일한 프로퍼티를 가진 여러 작은 객체를 만들어낼 때 유용하다. 유사한 반복 작업을 하는 객체를 만드는 것이 팩토리 패턴의 주요 목적이다. 단점 대부분의 상황에서 객체를 일일히 만드는 것보다 클래스를 활용하는 편이 메모리를 절약하는 데 더 효과적이다. 예제 코드) chart import React from 'react'; // Chart Factory function createChart(chartType, data) { switch (chartType) { case 'bar': return new BarChart(data); case 'line': ..

디자인 패턴 - Prototype 패턴

2. Prototype Pattern 동일한 타입의 여러 객체들이 프로퍼티를 공유할 때 유용하게 사용할 수 있다. 생성자의 prototype 프로퍼티와 생성된 인스턴스의 __proto__ 프로퍼티는 동일하며, 이들을 통해 Prototype 객체를 확인할 수 있다. class Dog { constructor(name) { this.name = name } bark() { return `Woof!` } } const dog1 = new Dog('Daisy') const dog2 = new Dog('Max') const dog3 = new Dog('Spot') console.log(Dog.prototype) // constructor: ƒ Dog(name, breed) bark: ƒ bark() console..