react native로 모바일 앱을 개발하는 업무를 막 맡았다.
전에 잠깐 flutter를 공부하고 있었는데, 갑자기 react native(RN)으로 변경되어서 급하게 react부터 훑어보고 있다.
react라는 라이브러리를 공부하면서 내용을 정리하고 있다.
참 필요에 의해 많은 기능들을 잘 만들었구나 하는 생각이 든다.
///.../// 본론으로 넘어가자...
ContextAPI의 필요성
useEffect나 useReducer 를 사용하다보면, 불편한 점이 있다.
아마득한 후손(child)으로 계층만 3단계를 넘어가면 엄청 불편해진다.
dispatch나 주요 함수들을 props로 계속 연달아서 전달해줘야 하는 점이다.
이게 한 두개도 불편한데, 엄청 많다면... (큰 불편이 아닐 수 없다)
그래서 생긴 게 ContextAPI이다.
간단히 어디서나 전역으로 접근할 수 있는 state 관리 통로를 만들어 버린 것이라고 할 수 있다.
1. 상태 관리하는 걸 먼저 만든다. 예를 들면, reducer나 useState를 사용해서 만든다.
2. 아래와 같이 createContext 한다.
import React, {useReducer, createContext, useMemo} from "react";
export const TableContext = createContext({
tableData: [], // 초기값
dispatch: () => {}, // 초기값
});
3. 적용하고 싶은 렌더링 컴포넌트들을 Provider로 감싼다.
return (
<TableContext.Provider value={{tableData: state.tableData, dispatch}}>
<Form></Form>
<div>{state.timer}</div>
<Table/>
<div>{state.result}</div>
</TableContext.Provider>
);
4. (중요!!) Provider로 넘길 때, 직접 value를 넘겨주면 성능 최적화에 위배된다. 알다시피, 불필요한 렌더링이 무척 많다.
이걸 줄이기 위해, 꼭 useMemo를 사용해야 한다.
const value = useMemo(() => ({tableData: state.tableData, dispatch}), [state.tableData]);
return (
<TableContext.Provider value={value}>
<Form></Form>
<div>{state.timer}</div>
<Table/>
<div>{state.result}</div>
</TableContext.Provider>
);
5. 하위에 있는 컴포넌트에서 사용할 때는 useContext로 context를 불러온다. 그렇기 위해, 먼저 export키워드로 노출시켜주자.
import {TableContext} from "./Minesearch";
import {START_GAME} from "./Minesearch";
const Form = () => {
const {dispatch} = useContext(TableContext);
//...
//...
const onClickStart = useCallback(() => {
dispatch({type: START_GAME, value: {row, cell, mine}});
console.log(row, cell, mine);
}, [row, cell, mine]);
return (
<div>
</div>
);
}
최근댓글