const p1 = () => new Promise((resolve) => {
setTimeout(() => {
console.log('@4초 완료');
resolve('4초 작업 완료');
}, 4000);
});
const p2 = () => new Promise((resolve) => {
setTimeout(() => {
console.log('@2초 완료');
resolve('2초 작업 완료');
}, 2000);
});
// 1. 병렬 작업
Promise.all([p1, p2]);
// 2. 선후행 작업
p1().then(()=> p2()});
컴포넌트는 어떻게 나누는 것이 좋을까?
외부 상태에 의존적인(props의 변경에 따라 변경되어야 하는) 컴포넌트와 외부 상태에 의존적이지 않은(props를 주입만 받는) 컴포넌트를 분리한다.
보통 페이지는 page 컴포넌트끼리 분리하고, UX의 흐름을 가지고 있는 컴포넌트들은 flow 컴포넌트로 별도 분리한다.
컴포넌트를 어느 시점에 분리할 것인가?
앱의 규모마다 다루는 로직의 복잡도마다 다르지만, 코드를 쓰다가 고민되는 시점이 생겼을 때, 그때가 분리 시점이 된다.
아키텍처 개선을 위해서는?
Code Split : 코드를 많이 쓰이는 화면 단위로 나누는 방식으로 개선
SSR을 이용 : 서버사이드 렌더링을 통해 개선
컴포넌트의 형태는 어떻게 만들어야 할까?
디자인 패턴을 사용하는 것보다는 개발의 유연성을 살려서 서비스, 백 오피스 등 성격에 맞는 최적의 형태의 컴포넌트 패턴을 만들어 낸다.
컨테이너 컴포넌트에는 디자인 요소를 쓰지 않는다.
효율적인 컴포넌트 호출 및 관리를 위해서는?
// containers - index.ts
export * from "./OrderStatus";
export * from "./MonitorController";
export * from "./Notification";
// App.tsx
import {
NotificationContainer,
OrderStatusContiner,
MonitorControllerContainer
} from "./containers";
가. compile 타임에 적용되는 스펙트럼
type Person = {
name: string;
age: number;
job?: []; // 있을 수도, 없을 수도 있는 값에는 ?를 붙인다.
}
// 아래와 같이 런타임에서 typeScript 에러를 잡을 수 없다.
// 어떤 상황이 런타임이고 컴파일인지 정확히 파악해야 어디에서 에러가 나는지 확인할 수 있다.
const p: Person = JSON.parse(prompt('객체를 입력해주세요'));
// 제네릭을 사용한 타입스크립트 컴파일 타임 예시
function identity<T>(arg: T): T {
return arg;
}
identity<string>('acdd');
identity<number>('adf'); // compile error!
나. type & interface 비교
interface
상속을 지원하고, union 타입을 지원하지 않는다.
모든 interface는 public 메서드이며, props는 모두 interface를 사용한다.
// union 타입 예시
type box = number | string; // number, string 두 개의 타입을 받을 수 있다.
let b: box = 10;
box = '10'