지뢰찾기 만들기(6)
Step 6
context API 최적화
react dev tools를 사용하면
리렌더링 될 때 마다 깜빡이는걸 시각적으로 확인 할 수 있다.
timer 때문에 계속 깜빡이므로
Form과 Table 그리고 그 아래에 있는 컴포넌트들을 모두 memo로 묶어준다.
Form.jsx
const Form = memo(() => {
const [row, setRow] = useState(10); // 줄(세로)
const [cell, setCell] = useState(10); // 칸(가로)
const [mine, setMine] = useState(20); // 지뢰 개수
const { dispatch }= useContext(TableContext);
// useCallback으로 감싸주면 불필요한 렌더링 막아줌
const onChangeRow = useCallback((e) => {
setRow(e.target.value);
}, []);
const onChangeCell = useCallback((e) => {
setCell(e.target.value);
}, []);
const onChangeMine = useCallback((e) => {
setMine(e.target.value);
}, []);
const onClickBtn = useCallback(() => {
dispatch({ type: START_GAME, row, cell, mine});
}, [row, cell, mine]);
return (
<div>
<input type="number" placeholder="세로" value={row} onChange={onChangeRow} />
<input type="number" placeholder="가로" value={cell} onChange={onChangeCell} />
<input type="number" placeholder="지뢰" value={mine} onChange={onChangeMine} />
<button onClick={onClickBtn}>시작</button>
</div>
)
})
Table.jsx
const Table = memo(() => {
const { tableData } = useContext(TableContext);
return (
<table>
{Array(tableData.length).fill().map((tr, i) => <Tr rowIndex={i} />)}
</table>
)
})
Tr.jsx
const Tr = memo(({ rowIndex }) => {
const { tableData } = useContext(TableContext);
return (
<tr>
{tableData[0] && Array(tableData[0].length).fill().map((td, i) => <Td rowIndex={ rowIndex } cellIndex={i} />)}
</tr>
)
})
Td.jsx
const Td = memo(({ rowIndex, cellIndex }) => {
const { tableData, dispatch, halted } = useContext(TableContext);
const onClickTd = useCallback(() => {
if (halted) {
return;
}
switch (tableData[rowIndex][cellIndex]) {
case CODE.OPENED:
case CODE.FLAG_MINE:
case CODE.FLAG:
case CODE.QUESTION_MINE:
case CODE.QUESTION:
return;
case CODE.NORMAL:
dispatch( {type: OPEN_CELL, row: rowIndex, cell: cellIndex} );
return;
case CODE.MINE:
dispatch( {type: CLICK_MINE, row: rowIndex, cell: cellIndex} );
return;
default:
return;
}
}, [tableData[rowIndex][cellIndex], halted]);
const onRightClickTd = useCallback((e) => {
e.preventDefault(); // 디폴트로 메뉴가 뜨는것을 방지
if (halted) {
return;
}
switch (tableData[rowIndex][cellIndex]) {
case CODE.OPENED:
return;
case CODE.NORMAL:
case CODE.MINE:
dispatch( {type: FLAG_CELL, row: rowIndex, cell: cellIndex} );
return;
case CODE.FLAG_MINE:
case CODE.FLAG:
dispatch( {type: QUESTION_CELL, row: rowIndex, cell: cellIndex} );
return;
case CODE.QUESTION_MINE:
case CODE.QUESTION:
dispatch( {type: NORMAL_CELL, row: rowIndex, cell: cellIndex} );
return;
default:
return;
}
}, [tableData[rowIndex][cellIndex], halted]);
return (
<td
style={getTdStyle(tableData[rowIndex][cellIndex])}
onClick={onClickTd}
onContextMenu={onRightClickTd}
>{getTdText(tableData[rowIndex][cellIndex])}
</td>
)
})
Author And Source
이 문제에 관하여(지뢰찾기 만들기(6)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@whanhee97/React-지뢰찾기-만들기6저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)