π λ€μ΄κ°κΈ°
μ΄λ²μλ 리μ‘νΈ Deep Diveμ 첫λ²μ§Έ μ₯μ νΊμ보며 λΆμ‘±ν λΆλΆμ λ©κΏλ³΄λ €κ³ νλ€.
κ°λ¨ν μμ½λ³΄λ€λ μ€μνκ±°λ λ―Έμ² κ°κ³Όνλ λΆλΆλ€μ μ§μ΄λ³΄κ³ μ νλ€.
β μλ°μ€ν¬λ¦½νΈμ λ λ€λ₯Έ λΉκ΅, Object.is
- == π κ°μμ λΉκ΅νκΈ° μ μ μμͺ½μ΄ κ°μ νμ μ΄ μλλΌλ©΄, λΉκ΅ν μ μλλ‘ κ°μ λ‘ νλ³νμ μ§ννλ€.
- === π κ°μ ν λ³νμ μ§ννμ§ μμΌλ©°, Object.isμ λ¬λ¦¬ κ°λ°μκ° κΈ°λνλ λ°©ν₯μΌλ‘ λΉκ΅λμ§ μμ μ μλ€.
5 == '5' // true
Object.is(5, '5'); // false
Number.NaN === NaN // false
Object.is(Number.NaN, NaN) //true
βοΈλ€λ§, μ£Όμν΄μΌ ν μ μ κ°μ²΄ λΉκ΅μμλ μ°¨μ΄κ° μλ€λ κ²μ΄λ€.
Object.isλ λλ±λΉκ΅ ( === )κ° κ°μ§λ νκ³λ₯Ό 극볡νκΈ° μν΄ λ§λ€μ΄μ§ κ²μ΄λ©°, κ°μ²΄ κ° λΉκ΅μ μμ΄μλ JSμ νΉμ§ λλ¬Έμ μ¬μ ν νκ³κ° μλ€.
π리μ‘νΈμμμ λλ± λΉκ΅ κ³Όμ
function is(x: any, y: any) {
return (
(x === y && (x !== 0 || 1 / x === 1 / y)) || (x !== x && y !== y)
);
}
// Object.isκ° μ‘΄μ¬νμ§ μλλ€λ©΄, μ ν¨μ μ¬μ©
const objectIs: (x: any, y: any) => boolean =
typeof Object.is === 'function' ? Object.is : is;
export default objectIs;
κΈ°λ³Έμ μΌλ‘ 리μ‘νΈμμλ μμ is ν¨μλ₯Ό κΈ°λ°μΌλ‘ shallowEqualμ λΉκ΅νκ³ μλ€.
μλμ²λΌ λ§μ΄λ€.
function shallowEqual(objA: mixed, objB: mixed): boolean {
// Object.isλ‘ λ¨Όμ λΉκ΅λ₯Ό μν
if (is(objA, objB)) {
return true;
}
if (
typeof objA !== 'object' ||
objA === null ||
typeof objB !== 'object' ||
objB === null
) {
return false;
}
// ν€λ₯Ό κΊΌλ΄κ³
const keysA = Object.keys(objA);
const keysB = Object.keys(objB);
if (keysA.length !== keysB.length) {
return false;
}
// Aμ ν€λ₯Ό κΈ°μ€μΌλ‘, Bμ ν€μ κ°μ μ²΄ν¬ , κ°μ²΄κ° μμ λΉκ΅λ§ μν
for (let i = 0; i < keysA.length; i++) {
const currentKey = keysA[i];
if (
!hasOwnProperty.call(objB, currentKey) ||
!is(objA[currentKey], objB[currentKey])
) {
return false;
}
}
return true;
}
export default shallowEqual;
νμ§λ§, μ¬κΈ°μλ λ¨μ μ μλ€.
λ°λ‘ μμ λΉκ΅λ§ κ°λ₯νλ€λ κ²μ΄λ€. λλ¬Έμ μ°λ¦¬λ useMemoλ₯Ό μ¬μ©ν λ μ΄ λΆλΆμ μΈμ§νκ³ μμ΄μΌ νλ€.
β ν¨μ
μλ°μ€ν¬λ¦½νΈμμ ν¨μλ μΌκΈ κ°μ²΄μ΄λ€.
λ€λ₯Έ κ°μ²΄λ€μ μΌλ°μ μΌλ‘ μ μ© κ°λ₯ν μ°μ°μ λͺ¨λ μ§μνλ©°, μ΄λ ν¨μκ° λ€λ₯Έ ν¨μμ 맀κ°λ³μκ° λκ±°λ λ°νκ°, ν λΉμ΄ κ°λ₯νλ€λ κ²μ μλ―Ένλ€.
κ·Έλμ μ°λ¦¬λ κ³ μ°¨ ν¨μλ₯Ό μμ±ν μ μλ κ²μ΄λ€.
const add = function(a){
return function(b){
return a+b
}
}
add(1)(3) // 4
리μ‘νΈμμλ κ³ μ°¨ ν¨μμ μ μ¬νκ² κ³ μ°¨ μ»΄ν¬λνΈλ₯Ό λ§λ€μ΄ μ»΄ν¬λνΈ λ΄λΆμμ 곡ν΅μΌλ‘ κ΄λ¦¬λλ λ‘μ§μ λΆλ¦¬ν΄ κ΄λ¦¬ν μ μκΈ°λ νλ€.
ν΄λΉ λΆλΆμ λν΄μλ 3.2μ μμ λ€λ£¨κ³ μ νλ€.
κ·Έλ λ€λ©΄ 리μ‘νΈμμ μ΄λ€ λ°©μμΌλ‘ ν¨μλ₯Ό νμ©ν΄μΌ ν κΉ?
1οΈβ£ ν¨μμ λΆμ ν¨κ³Όλ₯Ό μ΅λν μ΅μ νλΌ.
μ°λ¦¬κ° νν λ§νλ λΆμν¨κ³Όλ₯Ό μ΅μ ν ν¨μλ μμν¨μλΌκ³ λ μ¬λ¦΄ μ μλ€.
λ¬Όλ‘ μ»΄ν¬λνΈλ₯Ό μμν¨μλ‘ λ§λ€κ² λλ€λ©΄, μμΈ‘ κ°λ₯νκ³ μμ μ μ΄κ² μ»΄ν¬λνΈλ₯Ό λ§λ€ μ μλ€.
νμ§λ§, λͺ¨λ κ³³μμ κ·ΈλμΌλ§ νλ κ²μ μλλ€.
μ¬μ€, μ»΄ν¬λνΈ λ΄λΆμμ ν΄λΉ APIλ₯Ό νΈμΆνκ³ console.log( )λ₯Ό μ€νμν€κΈ°λ§ ν΄λ λΆμν¨κ³Όλ₯Ό κ°μ Έμ€κΈ°μ μ€λ¬΄μμ μ΄λ λλμ± νΌνκΈ° μ΄λ ΅λ€. κ·Έλμ μ°λ¦¬λ μ΄λ₯Ό μ΅μ νλ λ°©ν₯μΌλ‘ κ°μΌ λλ κ²μ΄λ€.
useEffectμ μ¬μ©μ μμ¨ μλ μμ§λ§, μλμ μ΅μννμ¬ ν¨μμ μν μ μ’νλ κ²μ΄ μ€μνλ€.
2οΈβ£ κ°λ₯ν ν ν¨μλ₯Ό μκ² λ§λ€μ΄λΌ.
ν¨μλΉ μ½λμ κΈΈμ΄κ° κΈΈμ΄μ§μλ‘ λ¬Έμ λ₯Ό μΌμΌν¬ μ¬μ§κ° μλ μ½λκ° λ°μν νλ₯ μ΄ λμμ§κ³
λ΄λΆμμ μ΄λ€ μΌμ΄ λ°μνλμ§ μΆμ νκΈ° μ΄λ €μμ§λ€.
μ΄ μΈμλ βοΈμ€μ²©μ΄ μΌλ§λ λ§κ³ , μ½λ°±μ μΌλ§λ μλμ§βοΈμ λ°λ₯Έ λ¬Έμ λ λ°μν μ μλ€.
μ΅μ μ ν¨μ ν¬κΈ°λ₯Ό λ¨μΈν μλ μμΌλ κ°λ₯ν ν ν¨μμ ν¬κΈ°λ₯Ό μκ² νλ κ²μ΄ μ’λ€.
3οΈβ£ λꡬλ μ΄ν΄ν μ μλ μ΄λ¦μ λΆμ¬λΌ.
μ΄λμμ μ΄λ€ κ°λ°μ ν΄λ μ΄ λΆλΆμ μ€μνλ€κ³ μκ°νλ€.
μ»΄ν¬λνΈ λ΄μμ λΉμ¦λμ€ λ‘μ§μ΄ λ€μ΄κ°λ μκ°, μ΄λ¦μ΄ λͺ¨νΈνκ±°λ ν΄λΉ κΈ°λ₯μ μμΈ‘ν μ μλ€λ©΄ νμ νκΈ°λ λμ± λ μ΄λ €μ΄ κ΅¬μ‘°λ‘ λ³ν΄κ° κ²μ΄λ€. λ°λΌμ κ°λ₯ν ν ν¨μμ μ΄λ¦μ κ°κ²°νκ³ μ΄ν΄νκΈ° μ½κ² λΆμ΄λ κ²μ΄ μ’λ€.
μ΄κ²μ μ½λ°±ν¨μμλ μ μ©ν μ μλ€.
useEffect(function apiRequest(){
},[])
μ΄λ₯Ό ν΅ν΄ useEffectμμ μ½λλ₯Ό μ΄ν΄λ³΄μ§ μμλ, λ΄λΆμμ μ΄λ€ κΈ°λ₯μ μννλμ§ λ―Έλ¦¬ μμΈ‘ν μ μλ€λ μ₯μ μ κ°μ§κ² λλ€.
β ν΄λμ€
νμ¬λ ν¨μν μ»΄ν¬λνΈλ₯Ό μ£Όλ‘ μ¬μ©νκ³ μμ§λ§, ν΄λμ€νμ μ΄ν΄νκ² λλ€λ©΄ 리μ‘νΈμ μλλ°©μμ μμνκ² λ°μλ€μΌ μ μμ κ²μ΄λ€.
π Object.getPrototype( )
Object.getPrototypeκ³Ό λμΌνκ² μλνλ κ²μ λ°λ‘ _ _ proto_ _ μ΄λ€.
νμ§λ§, _ _proto_ _λ κ°κΈμ μ¬μ©νμ§ μλ κ²μ΄ μ’λ€. μλνλ©΄, typeof null === 'object' μ μ μ¬νκ² μλ μλν νμ€μ μλμ§λ§ κ³Όκ±° λΈλΌμ°μ κ° μ΄λ₯Ό μ¬μ©νκΈ°μ μ μ§λλ κΈ°λ₯μ΄κΈ° λλ¬Έμ΄λ€.
μ¬κΈ°μ, νλ‘ν νμ 체μ΄λμ νΉμ±μ λ°κ²¬ν μ μλ€.
λͺ¨λ κ°μ²΄λ νλ‘ν νμ μ κ°μ§κ³ μκ³ , νΉμ μμ±μ μ°Ύμλ μμ μΌλ‘λΆν° μμν΄μ μ΅μμ κ°μ²΄μΈ ObjectκΉμ§ νκ² λλ€.
toStringμ λλΆλΆμ κ°μ²΄μμ μ¬μ©ν μ μλ κ²λ λΉμ·ν λ Όλ¦¬μ΄λ€.
ν΄λμ€λ‘ λ§λ ν¨μλ₯Ό babelμ΄ μ΄λ»κ² λ³ννλμ§ νμΈν μ μλ μ¬μ΄νΈμ΄λ€. ν΄λ¦ν΄μ μ΄ν΄λ³΄μ.
β Typescript
μ΄μ λ μμ΄μλ μλ κ°λ°μΈμ΄λ‘ μ리μ‘μ νμ μ€ν¬λ¦½νΈλ₯Ό μ΄λ»κ² 리μ‘νΈμ ν¨κ³Όμ μΌλ‘ μμ±ν΄μΌ νλμ§ μ΄ν΄λ³΄μ.
1οΈβ£ any λμ unknownμ μ¬μ©νμ.
anyλ νμ μ€ν¬λ¦½νΈλ₯Ό μ¬μ©νλ μλ―Έλ₯Ό μμ λ νμ μ΄λ€.
μλνλ©΄, λ°νμμ λͺ¨λ νμ μ λ°μλ€μ΄κΈ°μ μ¬μ€μ μλ°μ€ν¬λ¦½νΈμλ λ€λ₯Όκ² μλ€.
κ·Έλμ λΆκ°νΌνκ² νμ μ λ¨μ ν μ μλ λΆλΆμ λν΄μλ unknownμ μ¬μ©νλ κ²μ΄ μ’λ€.
μ΄λ€ κ°λ ν λΉν μ μμΌλ, νμ μ’νκΈ° μ΄νμλ§ μ¬μ©ν μ μλ€. μ΄λ top typeμΌλ‘ λΆλ¦¬κΈ°λ νλ€.
const getTodoItem = (callback:unknown) => {
if( typeof callback === 'function') callback();
throw new Error('callbackμ ν¨μμ¬μΌ ν©λλ€')
}
μ΄λ₯Ό μ νμ©νκΈ°λ§ νλ€λ©΄, μμμΉ λͺ»ν νμ μ λ°μκ³Ό λμμ μμ ν μ¬μ©λ κ°λ₯νκ² λλ€.
μμ λ§ν top typeμ λ°λ κ°λ μ bottom type μ΄λ€. μ΄λ neverλ₯Ό μ§μΉνλ€.
type what1 = string & number
type what2 = ('happehee' | 'seohee') & 'front-end'
what1 μλ stringκ³Ό numberλ₯Ό λλ€ λ§μ‘±ν΄μΌ νμ§λ§, μ΄λ μ‘΄μ¬νμ§ μκΈ°μ neverλ‘ νμ μ΄ μ§μ λλ€.
what2λ λ§μ°¬κ°μ§λ‘, μμͺ½μ νμ μ κ΅μ°¨μ μ΄ λ°μνμ§ μμ neverκ° μ μΈλλ€.
2οΈβ£ νμ κ°λλ₯Ό μ κ·Ή νμ©νμ
νμ μ μ’νλ λ° λμμ μ£Όλ κ²μ΄ λ°λ‘ νμ κ°λμ΄λ€.
- instanceof π μ§μ ν μΈμ€ν΄μ€κ° νΉμ ν΄λμ€μ μΈμ€ν΄μ€ μΈμ§ νμΈν μ μλ μ°μ°μ
- typeof π νΉμ μμμ λν΄ μλ£νμ νμΈνλ λ° μ¬μ©
- in π μ΄λ€ κ°μ²΄μ ν€κ° μ‘΄μ¬νλμ§ νμΈνλλ° μ¬μ©
3οΈβ£ μ λ€λ¦
ν¨μλ ν΄λμ€ λ΄λΆμμ λ¨μΌ νμ μ΄ μλ λ€μν νμ μ λμνλλ‘ λμμ£Όλ λꡬμ΄λ€.
λ¨μΌ μ λ€λ¦μ΄ μλ λ€μ€ μ λ€λ¦μ μ¬μ©νλ κ²½μ°, T,G 보λ€λ μλ―Έμλ μ λ€λ¦ ννμ μ μ΄μ£Όλ κ²μ΄ μ’λ€.
const multipleGeneric<First, Second>(a1 : First , a2: Second):[First, Second]{
return [a1, a2]
}
const [a ,b] = multipleGeneric<string, number>('happhee', 12)
4οΈβ£ μΈλ±μ€ μκ·Έλμ²
μμ§λ μ νμ©νμ§ λͺ»νκ³ μλ νΉμ±μ€μ νλμ΄κΈ°λ νλ€.
type Happhee = {
// π μλΆλΆμ΄ μΈλ±μ€ μκ·Έλμ² μ΄λ€.
[key: string]: string;
};
const happheeKid: Happhee = {
hobby: 'dance',
fruite: 'strawberry',
};
console.log(happheeKid['hobby']); // dance
console.log(happheeKid['fruite']); // strawberry
console.log(happheeKid['age']); // undefined
μμ κ°μ΄ μΈλ±μ€ μκ·Έλμ²λ₯Ό μ¬μ©νλ©΄, ν€μ νμ μ λΆμ¬ν μ μλ€λ μ₯μ μ΄ μμΌλ©° μ΄λ λμ μΈ κ°μ²΄λ₯Ό μ μν λ μ μ©νλ€.
βοΈ λ€λ§ ν€μ λ²μκ° μ»€μ§λ κ²½μ° βοΈ
νμ μ λ²μκ° λ무 컀μ§λ―λ‘ μ‘΄μ¬νμ§ μλ ν€λ‘ μ κ·Όνλ©΄ undefinedλ‘ λ°νλλ€.
λ°λΌμ κ°μ²΄μ ν€λ₯Ό λμ μΌλ‘ μ μΈνλ κ²½μ°λ₯Ό μ΅λν μ§μνκ³ , κ°μ²΄μ νμ λ νμμ λ°λΌ μ’νμΌ νλ κ³Όμ μ΄ νμνλ€.
type Happhee = {
[key: 'hobboy' | 'fruite' ]: string;
};
type Happhee = Record<'hobby'|'fruite', string>
λ°©λ²μ λ κ°μ§ μ΄λ€.
- νμ μ μ¬μ©ν μΈλ±μ€ μκ·Έλμ²
λ€λ§ 첫 λ²μ§Έμ λ°©λ²μμλ μλμ κ°μ μ€λ₯κ° λ°μνλ€.
λλ¬Έμ μ°λ¦¬λ 맡λ νμ μ μ¬μ©ν΄μ ν΄λΉ λ¬Έμ λ₯Ό ν΄κ²°ν΄μΌ νλ€.
type Info = 'hobby' | 'fruite';
type Happhee = {
[key in Info ]: string;
};
type Happhee = Record<'hobby'|'fruite', string>
λ λ²μ§Έ λ°©λ²μ
- recordλ₯Ό μ¬μ©ν νμ μ’νκΈ°
μ΄λ κ² νμ μ μ’νλ Object.keysλ‘ μ κ·Όνμλ keyμ νμ μ΄ string [ ] λ‘ μΆλ‘ λλ κ²μ νμΈν μ μλ€.
μ¬μ€ κ·Έλμ νλ² asλ‘ νμ μ λ¨μΈν΄μ£Όμ΄μΌ νλ€.
const happheeKeyList = Object.keys(happheeKid);
(happheeKeyList as Array<keyof Happhee>).map((key) => happheeKid[key]);
λ¨μΈλ³΄λ€ κ°λλ‘ μμ μ μ΄κ² μ¬μ©νκ³ μΆλ€λ©΄ μλμ κ°μ΄ ν΄λΉ κ°λ ν¨μλ₯Ό λ§λ€λ©΄ λλ€.
const guardKeyOf = <T extends Object>(obj: T): Array<keyof T> => {
return Array.from(Object.keys(obj)) as Array<keyof T>;
};
guardKeyOf(happheeKid).map((key) => happheeKid[key]);
κ°λ ν¨μκ° μλνλ λ°©μμ λ€μ μμμ κ°λ€.
- 맀κ°λ³μμ νμ μ Tμ΄λ€.
- λ°ν κ°μ 맀κ°λ³μμ ν€ νμ μ΄λ€.
κ·Έλ λ€λ©΄ μ Object.keysκ° string[]μΌλ‘ λ§λ€μ΄μ§κ±ΈκΉ?
π νμ μ€ν¬λ¦½νΈμ ꡬ쑰μ νμ΄ν νΉμ§λλ¬Έμ λ νμ΄νμ΄ μ΄λ£¨μ΄μ§κΈ° λλ¬Έμ΄λ€. μ¦, νμ 체ν¬μ κ·Έ κ°μ΄ κ°μ§ ννμλ§ μ§μ€νλ€λ κ².
π ν¬κ΄μ μΈ λμμ μν΄ string[]μΌλ‘ μ 곡λλ κ²μ΄λ€.
π μ 리νκΈ°
μ΄λ² μκ°μλ 리μ‘νΈμμ λΉκ΅κ³Όμ , ν¨μ μμ± λ°©λ², νμ κ°λλ₯Ό μ¬μ©νλ λ°©λ²μ μ΄ν΄λ³΄μλ€.
μ€λ¬΄μμ μ μ©νμ§ λͺ»ν λ΄μ©λ€κ³Ό recordμ κ°μ νμ μ μ¬μ©νλ λ°©λ²μ λ₯μνκ² λ€λ£¨λ©΄ μ’μ κ² κ°λ€λ μκ°μ νκ² λλ μκ°μ΄μλ€.
π μ°Έκ³ μλ£
'WEB > React' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
Reactμ ν¨ν€μ§ ꡬ쑰μ μ©μ΄ μ 리 (0) | 2023.12.03 |
---|---|
[ React ] useQuery μ useMuataionλ₯Ό νμ©ν κΈ°λ₯κ°μ (0) | 2023.11.30 |
[ λͺ¨λ 리μ‘νΈ : Deep Dive ] - 리μ‘νΈμ λν΄ (1) | 2023.11.13 |
PWA + Safari (0) | 2023.07.03 |
Intersection Observer API λ₯Ό νμ©ν 무νμ€ν¬λ‘€ ꡬν (0) | 2023.07.03 |