-
카테고리
-
세부 분야
프론트엔드
-
해결 여부
미해결
Td와 Tr 컴포넌트에 memo를 씌우지 않아도 되나요?
23.05.25 22:30 작성 23.05.25 22:32 수정 조회수 229
0
timer 때문에 Table 전체가 리렌더링되는 문제를 해결하기위해
강의에서는 Table과 하위컴포넌트 Tr, Td 모두에 memo를 씌우셨고
하위컴포넌트가 다 memo가 돼있어야지 상위컴포넌트도 memo를 적용할 수 있게 된다고 말씀하셨는데요
제가 Tr Td에 memo를 없애고
Table에만 적용해봤더니
그래도 리렌더링되지 않길래
이렇게 해도 되는지 궁금해서 질문드립니다
import React, { useReducer, createContext, useMemo, useEffect } from 'react';
import Table from './Table';
import Form from './Form';
// 중략
const MineSearch = () => {
const [state, dispatch] = useReducer(reducer, initalState);
const { tableData, halted, timer, result } = state;
const value = useMemo(() => ({ tableData: tableData, halted: halted, dispatch })
, [tableData, halted]);
useEffect(() => {
if (!halted) {
const timer = setInterval(() => {
dispatch({ type: INCREMENT_TIMER });
}, 1000);
return () => {
clearInterval(timer);
}
}
}, [halted]);
return (
<TableContext.Provider value={value}>
<Form />
<div>{timer}</div>
<Table />
<div>{result}</div>
</TableContext.Provider>
);
};
export default MineSearch;
import React, { useContext, memo } from 'react';
import Tr from './Tr';
import { TableContext } from './MineSearch';
const Table = memo(() => {
const { tableData } = useContext(TableContext);
return (
<table>
{Array(tableData.length).fill().map((tr, i) => <Tr key={i} rowIndex={i} />)}
</table>
);
});
export default Table;
import React, { useContext, memo } from 'react';
import Td from './Td';
import { TableContext } from './MineSearch';
const Tr = ({ rowIndex }) => {
const { tableData } = useContext(TableContext);
return (
<tr>
{tableData[0] && Array(tableData[0].length).fill().map((v, i) => <Td key={i} rowIndex={rowIndex} cellIndex={i} />)}
</tr>
);
};
export default Tr;
import React, { useContext, useCallback, memo, useMemo } from 'react';
import {
TableContext, CODE,
OPEN_CELL, CLICK_MINE, FLAG_CELL, QUESTION_CELL, NORMALIZE_CELL
} from './MineSearch';
// 중략
const Td = ({ rowIndex, cellIndex }) => {
const { tableData, dispatch, halted } = useContext(TableContext);
const onClickTd = useCallback(() => {
if (halted) {
return;
}
switch (tableData[rowIndex][cellIndex]) {
case CODE.OPENED:
case CODE.FLAG:
case CODE.QUESTION:
case CODE.FLAG_MINE:
case CODE.QUESTION_MINE:
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.NORMAL:
case CODE.MINE:
dispatch({ type: FLAG_CELL, row: rowIndex, cell: cellIndex });
return
case CODE.FLAG:
case CODE.FLAG_MINE:
dispatch({ type: QUESTION_CELL, row: rowIndex, cell: cellIndex });
return;
case CODE.QUESTION:
case CODE.QUESTION_MINE:
dispatch({ type: NORMALIZE_CELL, row: rowIndex, cell: cellIndex });
return;
default:
return;
}
}, [tableData[rowIndex][cellIndex], halted]);
return (
<RealTd onClickTd={onClickTd} onRightClickTd={onRightClickTd} data={tableData[rowIndex][cellIndex]} />
)
};
const RealTd = memo(({ onClickTd, onRightClickTd, data }) => {
console.log('RealTd rendered');
return (
<td
onClick={onClickTd}
onContextMenu={onRightClickTd}
style={getTdStyle(data)}
> {getTdText(data)}</td>
);
});
export default Td;
답변을 작성해보세요.
답변 1