💻오늘 배운 내용
useContext
전역 데이터를 관리하는 api
- createContext : context 생성
- Consumer : context 변화 감지
- Provider : context 전달(to 하위 컴포넌트)
1. context 폴더 > FamilyContext.js 생성
import { createContext } from "react";
// 여기서 null은 초기값
export const FamilyContext = createContext(null);
2. props를 가장 처음 전달하던 컴포넌트에서 FamilyContext를 import해주고 자식컴포넌트를 <Provider>로 감싸준다.
이때 전달할 데이터를 객체 형태로 전달한다.
import React from "react";
import Father from "./Father";
import { FamilyContext } from "../context/FamilyContext";
function GrandFather() {
const houseName = "스파르타";
const pocketMoney = 10000;
return (
<FamilyContext.Provider value={{ houseName, pocketMoney }}>
<Father />
</FamilyContext.Provider>
);
}
export default GrandFather;
3. props를 전달하기만 하던 컴포넌트에서는 useContext hook을 쓰면 아무것도 안해도 됨
import React from "react";
import Child from "./Child";
function Father() {
return <Child />;
}
export default Father;
4. consumer로서 FamilyContext를 import해주고 내려받은 정보를 인자로 받아서 사용
import React, { useContext } from "react";
import { FamilyContext } from "../context/FamilyContext";
function Child({ houseName, pocketMoney }) {
return (
<div>
나는 이 집안의 막내에요.
<br />
할아버지가 우리 집 이름은 <span style={stressedWord}>{data.houseName}</span>
라고 하셨어요.
<br />
게다가 용돈도 <span style={stressedWord}>{data.pocketMoney}</span>원만큼이나
주셨답니다.
</div>
);
}
export default Child;
useContext 사용 시 주의점
prop drilling 방지하고 손쉽게 전역 데이터를 관리할 수 있다는 장점은 있지만
Provider에서 제공한 value가 달라진다면 useContext를 사용하고 있는 모든 컴포넌트가 리렌더링 된다.
>>최적화 문제가 발생할 수 있기 때문에 value 부분을 항상 신경써주어야 한다.
React 최적화 ( React.memo / useCallback / useMemo )
1] React.memo
부모 컴포넌트가 리렌더링 되면 자식컴포넌트는 모두 리렌더링 된다.
> 이를 방지 하기 위한 것이 React.memo
부모 컴포넌트의 state의 변경으로 인해 props가 변경이 일어나지 않는 한 컴포넌트는 리렌더링 되지 않는다.
이것을 component memoization이라도 한다.
사용예제) export 할 때 React.memo()를 붙여주면 된다.
export default React.memo(컴포넌트 이름);
* 메모이제이션을 했는데도 리렌더링이 되는 경우?
함수형 컴포넌트를 사용하기 때문이다. 함수도 객체의 한 종류.
따라서 부모 컴포넌트가 리렌더링 되면 모양은 같더라도 다시 만들어지면서 그 주솟값이 달라지고
이에 따라 하위 컴포넌트는 props가 변경됐다고 인식하기 때문에 리렌더링 될 수있다.
그래서! 함수를 메모리 공간에 저장해놓고, 특정 조건이 아닌 경우엔 변경되지 않도록 할 때
사용하는 hook이 아래의 useCallback
2] useCallback
함수를 메모리 공간에 저장해놓고, 특정 조건이 아닌 경우엔 변경되지 않도록 할 때 사용하는 hook
React.memo는 컴포넌트를 memoization 했다면, useCallback은 인자로 들어오는 함수 자체를 memoization한다.
// 변경 전
const initCount = () => {
setCount(0);
};
// 변경 후
const initCount = useCallback(() => {
setCount(0);
}, []);
useCallback이 count가 0일 때의 시점을 기준으로 메모리에 함수를 저장하기 위해서는 dependency array가 필요하다.
3] useMemo
동일한 값을 반환하는 함수를 계속 호출해야 하면 필요없는 렌더링을 한다고 볼 수 있다.
그래서 React는 맨 처음 해당 값을 반환할 때 그 값을 특별한 곳(메모리)에 저장하는 hook을 만들었는데 그것이 useMemo.
이미 저장한 값을 단순히 꺼내와서 시용한다. => 캐싱을 한다
사용예제)
// as-is
const value = 반환할_함수();
// to-be
const value = useMemo(()=> {
return 반환할_함수()
}, [dependencyArray]);
dependency Array의 값이 변경 될 때만 "반환할 함수"가 호출되고,
그 외의 경우에는 memoization 해놨던 값을 가져오기만 한다.
React.memo => component를 memoization
useCallback => function을 memoization
useMemo => value를 memoization
그러나 남발하게 되면 별도의 메모리 확보를 너무나 많이 하게 되기 때문에 오히려 성능이 악화될 수 있다.
필요할 때만 쓰기!
🧐궁금점과 부족한 내용
api의 의미
리액트 훅의 함수를 가리켜 api라는 말을 많이 사용하는데
여태 api라 함은 서버와 클라이언트 간의 그 어떤 연결고리? 정도로 인식해왔다.
'Application Programming Interface'
운영체제와 응용프로그램 사이의 통신에 사용되는 언어나 메시지 형식
가게의 점원 같은 역할, API = '중간 전달자'
ㄲeact hook은 Class 형태였던 Component를 function을 통해 만들 수 있게 해주는 API이다.
그런데 나는 이것도 헷갈리기 때문에 API란 HTML 요소에 접근해서 수정할 수 있는 함수 정도로 이해해두자..
📋레퍼런스
'내일배움캠프 > Today I Learned' 카테고리의 다른 글
[TIL 2023.06.22] Redux에 대하여 2 (Action Creator, Payload, useDispatch, Ducks 패턴) (0) | 2023.06.23 |
---|---|
[TIL 2023.06.21] Redux에 대하여 1 (개념 및 초기셋팅~Module 만들기 및 스토어에 연결) (0) | 2023.06.22 |
[TIL 2023.06.19] React Styled components / useEffect / useRef (0) | 2023.06.20 |
[TIL 2023.06.16] 후발대 과제 / React counter app 만들기 (0) | 2023.06.19 |
[TIL 2023.06.15] React 프로젝트 GitHub Pages 배포하기 / 컴포넌트 분리하기 (1) | 2023.06.16 |