inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

웹 게임을 만들며 배우는 React

8-8. Context api 최적화

Td와 Tr 컴포넌트에 memo를 씌우지 않아도 되나요?

378

박규석

작성한 질문수 9

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;

react

답변 1

0

제로초(조현영)

timer 때문에는 Table만 memo 씌우셔도 됩니다.

다만 셀 데이터때문에는 Tr Td에 씌우셔야할 수 있습니다.

0

욱둥이

Table에서 props로 Tr, Td에 rowIndex, cellIndex를 순차적으로 적용했기 때문인가요?

npm run dev 실행 시 포트가 안뜨는 문제

0

211

2

timeouts.current를 useEffect 의 input값으로 넣었을때

0

89

2

렌더링 테스트 코드 (Hooks)

0

80

1

Cannot find package 'react-refesh' 이런 에러 뜨시는 분들 보세요.

0

154

1

해당 에러 뜨는 분들 보세요. "Uncaught TypeError: ReactDom.createRoot is not a function"

1

193

1

강사님 레포지토리에서 코드 복사 시 master 브랜치 말고 react18 브랜치꺼 복붙하세요ㅠㅠ

0

99

1

useMemo와 useCallback 사용 시기

0

208

2

onRightClickTd가 작동을 하지 않습니다.

0

228

1

action.type 불러오는 방식

0

222

2

onClickRedo 질문

0

172

1

const Try = require(./Try) 빨간줄

0

249

1

npx webpack 실행시

0

316

1

지뢰찾기 강좌에서 빈칸들 한번에 열기 파트에서 여쭤보고싶은부분이 있어서 글 올립니다.

0

236

1

강좌에서 다루지 않은 기능들은 어떻게 학습하면 좋을까요?

0

311

1

react devtool이 enable 않됩니다.

0

532

2

React 랜더링이 되지 않습니다.

0

414

2

비동기로 동작하는 setState에 대해서

0

332

1

npm run dev 할 때 에러발생

0

480

2

memo, PureComponenet, shouldComponentUpdate 관련 질문

0

207

1

devMiddleware의 필요성

0

353

1

리액트에서 화살표 함수를 사용해야하는 이유

0

937

2

path.join관련질문

0

283

2

2-9. 웹팩 데브 서버와 핫 리로딩 설치과정 시 에러

0

376

1

next.js 에서 이와 비슷한 예제를 돌리고있는데 react랑 달라서 질문 드립니

1

494

4