FastCampas X Yanolja BootCamp

리액트 기초

취업하고싶다! 2023. 10. 4. 19:35

전개연산자란?

특정 객체 또는 배열의 값을 다른 객체, 배열로 복제하거나 옮길 때 사용

 

배열 조합

const arr1 = [1,2,3];
const arr2 = [4,5,6];
const arr3 = [7,8,9];

const arrWrap = [...arr1, ...arr2, ...arr3];

 

객체 조합

const obj1 = {
a: 'A';
b: 'B';
}

const obj2 = {
c: 'C';
d: 'D';
}


// 객체 자체가 들어감
const objWrap = {obj1, obj2};

// 객체 자체가 아닌 각각의 값 할당
const objWrap2 = {...obj1, ...obj2};

 

 

전개연산자를 사용하면 기존 배열을 보존할 수 있음

const arr1 = [1,2,3];
const arr2 = arr1.reverse();

console.log(arr1)	// [3,2,1]
console.log(arr2)	// [3,2,1]


// 전개연산자 사용

const arr3 = [1,2,3];
const arr4 = [...arr1].reverse();

console.log(arr3)	// [1,2,3];
console.log(arr4)	// [3,2,1];

 

 

과거의 이동 목록 표시하기

틱택토 게임의 이동 정보를 기록하고 있기 때문에 플레이어에게 과거의 이동 목록을 표시할 수 있음(history state 안에 가지고 있음)

-> map() 함수 사용해서 history 배열에 있는 것들을 하나씩 나열

 

map() 메소드: 배열 내의 모든 요소 각각에 대해 주어진 함수를 호출한 결과를 모아 새로운 배열 반환

const arr1 = [1,4,9,16];

const map1 = arr1.map(x => x * 2);

console.log(map1)	// [2,8,18,32]

 

 

JSX Key 속성 이해하기

 

JSX key 속성이란? 

리액트에서 요소의 리스트를 나열할 때는 key를 넣어줘야 함

키는 리액트가 변경, 추가 또는 제거된 항목을 식별하는 데 도움이 됨

요소에 안정적인 ID를 부여하려면 배열 내부의 요소에 키를 제공해야 함

 

리액트는 가상 돔을 이용해서 바뀐 부분만 실제 돔에 적용함!

 

리액트에서는 리스트를 나열할 때 바뀐 부분만 찾을 때 어떻게 할까?

-> key를 이용해서 어떠한 부분이 바뀌었는지 인식할 수 있음

 

 

key에는 유니크한 값을 넣어줘야 함(index는 비추천)

index도 0부터 시작해서 유니크한 값을 가지지만 만약 리스트가 추가되거나 제거되면 해당 리스트들의 key값도 바뀌게 됨

 

 

 

useEffect란?

 

컴포넌트가 랜더링 될 때 특정 작업을 실행할 수 있도록 하는 Hook

처음 컴포넌트가 시작하면 UI가 랜더링되고 state가 변경되면 또 랜더링됨

 

 

fetch() 메소드란?

 

원격 API에 요청을 보내기 위해 사용할 수 있는 메소드

전역 fetch() 메소드는 네트워크에서 리소스를 가져오는 프로세스를 시작하여 response를 사용할 수 있게 되면 이행된 promise을 return함

즉, 요청을 보낸 후 response가 오면 그 response를 이용할 수 있게해주는 메소드

 

 

jsonplaceholder란?

 

가짜 데이터가 필요할 때 마다 사용할 수 있는 무료 온라인 REST API

posts, users, photos 등 여러 가지 가짜 데이터를 가져올 수 있음

 

 

얕은 비교(Shallow Compare)란?

 

숫자, 문자열 등 원시자료형은 값을 비교

배열, 객체 등 참조자료형은 값 혹은 속성을 비교하지 않고 참조되는 위치를 비교

[사용되는 경우]

1. React.memo()에서 props를 비교할 때

2. 리액트 컴포넌트가 리 랜더링을 하기 전(state 변경이 있을 때, 부모 컴포넌트가 랜더링 될 때)

const obj1 = { a : 1, b : 2 }
const obj2 = { a : 1, b : 2 }

console.log(obj1 === obj2)	// false

 

깊은 비교(Deep Compare)란?

 

얕은 비교와 달리, 깊은 비교는 객체의 경우에도 값을 비교

1. Object depth가 깊지 않은 경우: JSON.stringify() 사용

2. Object depth가 깊은 경우: lodash 라이브러리의 isEqual() 사용

const obj1 = { a : 1, b : 2 }
const obj2 = { a : 1, b : 2 }

console.log(obj1 === obj2)	// true

 

 

리액트가 리 랜더링 되는 경우

1. state 변경이 있을 때

2. 부모 컴포넌트가 랜더링 될 때

3. 새로운 props가 들어올 때

4. shouldComponentUpdate에서 true가 반환될 때

5. forceUpdate가 실행될 때

 

 

 

useCallback을 이용한 함수 최적화

 

원래 컴포넌트가 랜더링 될 때 그 안에 있는 함수도 다시 만들게 됨. 하지만 똑같은 함수를 컴포넌트가 리 랜더링 된다고해서 계속 다시 만드는 것은 좋은 현상이 아님. 그리고 이렇게 컴포넌트가 리 랜더링 될 때마다 함수를 계속 다시 만든다고 하면 만약 이 함수가 자식 컴포넌트에 props로 내려준다면 함수를 포함하고 있는 컴포넌트가 리 랜더링 될 때마다 자식 컴포넌트도 함수가 새롭게 만들어지니 계속 리 랜더링하게 됨

 

 

useCallback은 메모리제이션된 함수를 반환하는 함수

useCallback 적용은 useCallback 안에 콜백 함수와 의존성 배열을 순서대로 넣어주면 됨

const testFunction = useCallback(() =? {}, []);

함수 내에서 참조하는 state, props가 있다면 의존성 배열에 추가하면 됨

useCallback으로 인해 의존성 배열에 추가한 state, props가 변하지 않으면 함수는 새로 생성되지 않음

새로 생성되지 않기 때문에 메모리에 새로 할당되지 않고 동일 참조 값을 사용함

의존성 배열에 아무것도 없다면 컴포넌트가 최초 랜더링 시에만 함수가 생성되며 그 이후에는 동일한 참조 값을 사용하는 함수가 됨

 

 

useMemo를 이용한 결과 값 최적화

 

Memoization이란?

비용이 많이 드는 함수 호출의 결과를 저장하고 동일한 입력이 다시 발생할 때 캐시된 결과를 반환해 컴퓨터 프로그램의 속도를 높이는 데 주로 사요되는 최적화 기술

 

Component 내의 compute 함수가 만약 복잡한 연산을 수행하면 결과 값을 리턴하는데 오랜 시간이 걸리게 됨.

이럴 시에 컴포넌트가 계속 리 랜더링 된다면 연산을 계속 수행하는데 오랜 시간이 걸려서 성능에 안좋은 영향을 미치게 되며 UI 지연 현상도 일어남

 

이러한 현상을 해결하는 것이 useMemo.

compute 함수에 넘겨주는 a,b의 값이 이전과 동일하다면 컴포넌트가 리 랜더링 되어도 연산을 다시 하지않고 이전 랜더링 때 저장해두었던 값을 재활용함

function Component({a,b}) {
    const result = useMemo(() => compute(a,b),[a,b])
    return <div>{result}</div>
}