과거 프로그래밍 자료들/React
[웹 게임을 만들며 배우는 React] - 지뢰찾기(1), contextAPI
평부
2022. 9. 30. 16:18
출처: https://www.inflearn.com/course/web-game-react/dashboard
* Cotext API
- 부모와 자식 관계가 다층적일 때 props 물려주기 힘듦
- 예를 들어 부모는 MineSearch.jsx 자식은 Table.jsx > Tr.jsx > Td.jsx일 때 Td가 MineSearch에서 데이터를 가져오고 싶을 때 MineSearch > Table > Tr > Td 순으로 물려줘야 함
- 이 과정에서 MineSearch에서 Td로 바로 데이터를 전달하게 하는 것 = Context API
- 부모 : createContext 사용(useMemo 사용)
▶ MineSearch가 리렌더링 될 때마다 {{ tableData: state.tableData, dispatch }}도 새로 생김
▶ 객체가 새로 생긴다는 것은 contextAPI를 쓰는 자식들도 매번 새로 리렌더링됨(성능적으로 문제 생김)
▶ 매번 새로운 객체가 생기지 않게 useMemo(객체값 기억) 사용 (렌더링 캐싱이라고도 함)
//문제 있는 코드
<TableContext.Provider value={{ tableData: state.tableData, dispatch }}>
//수정한 코드
const value = useMemo(
() => ({ tableData: state.tableData, dispatch }),
[state.tableData]
)
<TableContext.Provider value={value}>
//부모
import React, { useReducer, createContext, useMemo } from "react";
import Table from "./Table";
export const TableContext = createContext({
tableData: [],
dispatch: () => {},
});
const MineSearch = () => {
const [state, dispatch] = useReducer(reducer, initialState);
const value = useMemo(
() => ({ tableData: state.tableData, dispatch }),
[state.tableData]
)
return (
<TableContext.Provider value={value}>
<Table>
</TableContext.Provider>
);
};
▶ 자식 : useContext 사용
[Table.jsx]
import React, { useContext } from "react";
import { TableContext } from "./MineSearch";
import Tr from "./Tr";
const Table = () => {
const { tableData } = useContext(TableContext);
return (
<table>
{Array(tableData.length)
.fill()
.map((tr, i) => (
<Tr rowIndex={i} />
))}
</table>
);
};
export default Table;
[Tr.jsx]
import React, { useContext } from "react";
import { TableContext } from "./MineSearch";
import Td from "./Td";
//Table로 부터 rowIndex 받음
const Tr = ({ rowIndex }) => {
const { tableData } = useContext(TableContext);
return (
<tr>
{tableData[0] &&
Array(tableData[0].length)
.fill()
.map((td, i) => <Td rowIndex={rowIndex} cellIndex={i} />)}
</tr>
);
};
export default Tr;
[Td.jsx]
import React, { useContext } from "react";
import { CODE, TableContext } from "./MineSearch";
const getTdStyle = (code) => {
switch (code) {
case CODE.NORMAL:
case CODE.MINE:
return {
background: "#444",
};
case CODE.CLICKED_MINE:
case CODE.OPENED:
return {
background: "white",
};
case CODE.QUESTION_MINE:
case CODE.QUESTION:
return {
background: "yellow",
};
case CODE.FLAG_MINE:
case CODE.FLAG:
return {
background: "red",
};
default:
return {
background: "white",
};
}
};
const getTdText = (data) => {};
const Td = ({ rowIndex, cellIndex }) => {
const { tableData } = useContext(TableContext);
return (
<td style={getTdStyle(tableData[rowIndex][cellIndex])}>
{getTdText(tableData[rowIndex][cellIndex])}
</td>
);
};
export default Td;