inflearn logo
강의

Course

Instructor

Learning React while making web games

3-11. Preventing unfair child re-rendering (PureComponent and memo)

질문있습니다!

228

Jack

11 asked

0

안녕하세요 제로초님.

 

3-11강을 수강하던중 의문이 생겼습니다.

1. 만약 try컴포넌트에 memo를 사용하게 되면 숫자를 입력할때는 부모컴포넌트인  NumberBaseball에서 onChangeInput 함수가 실행되어 value state만 변경되어서 자식컴포넌트인 try컴포넌트는 리렌더링이 되자않는것은 이해했습니다. 

 

그러나 숫자를 입력하고 입력버튼을 눌러 onSubmitForm함수가 실행되게 되면 tries state 배열에 데이터가 추가되고 try컴포넌트에 props인 tryInfo props를 넘겨주잖아요? 이때 tries state배열이 변경되었는데 왜 자식컴포넌트인 try를 리렌더링이 되지 않는지 궁금합니다!

입력버튼을 눌렀을 때는 tries의 state가 변하고 props를 넘겨주니 자식컴포넌트인 try 컴포넌트가 한번 렌더링 되어야 하는거 아닌가요?..

 

밑에는 전체 코드입니다!

 


const NumberBaseball = () => {
  const [answer, setAnswer] = useState(getNumbers());
  const [value, setValue] = useState("");
  const [result, setResult] = useState("");
  const [tries, setTries] = useState([]);
  const inputEl = useRef(null);

  const onSubmitForm = useCallback(
    (e) => {
      e.preventDefault();
      if (value === answer.join("")) {
        setTries((t) => [
          ...t,
          {
            try: value,
            result: "홈런!",
          },
        ]);
        setResult("홈런!");
        alert("게임을 다시 실행합니다.");
        setValue("");
        setAnswer(getNumbers());
        setTries([]);
        inputEl.current.focus();
      } else {
        const answerArray = value.split("").map((v) => parseInt(v));
        let strike = 0;
        let ball = 0;
        if (tries.length >= 9) {
          setResult(`10번 넘게 틀려서 실패! 답은 ${answer.join(",")}였습니다!`); // state set은 비동기
          alert("게임을 다시 시작합니다.");
          setValue("");
          setAnswer(getNumbers());
          setTries([]);
          inputEl.current.focus();
        } else {
          console.log("답은", answer.join(""));
          for (let i = 0; i < 4; i += 1) {
            if (answerArray[i] === answer[i]) {
              console.log("strike", answerArray[i], answer[i]);
              strike += 1;
            } else if (answer.includes(answerArray[i])) {
              console.log(
                "ball",
                answerArray[i],
                answer.indexOf(answerArray[i])
              );
              ball += 1;
            }
          }
          setTries((t) => [
            ...t,
            {
              try: value,
              result: `${strike} 스트라이크, ${ball} 볼입니다.`,
            },
          ]);
          setValue("");
          inputEl.current.focus();
        }
      }
    },
    [value, answer]
  );

  const onChangeInput = useCallback((e) => setValue(e.target.value), []);

  return (
    <>
      <h1>{result}</h1>
      <form onSubmit={onSubmitForm}>
        <input
          ref={inputEl}
          maxLength={4}
          value={value}
          onChange={onChangeInput}
        />
        <button>입력!</button>
      </form>
      <div>시도: {tries.length}</div>
      <ul>
        {tries.map((v, i) => (
          <Try key={`${i + 1}차 시도 : ${v.try}`} tryInfo={v} />
        ))}
      </ul>
    </>
  );
};

export default NumberBaseball;
 
 
try.js
 
 
import React, { memo } from 'react';

const Try = memo(({tryInfo}) => {
  return (
    <li>
      <div>{tryInfo.try}</div>
      <div>{tryInfo.result}</div>
    </li>
  );
});

export default Try;

react

Answer 1

0

zerocho

tries의 값은 새로운 객체 하나가 생긴 것 빼고는 다른 객체들은 바뀌지 않았습니다. 거기다 memo로 감쌌으므로 부모가 리렌더링되더라도 자식은 props가 같으므로 리렌더링되지 않습니다.

0

Jack

아... 제가 잘못이해한것 같습니다. 

그러면 tries state에 배열에 객체가 하나 추가 혹은 제거 되더라도 state가 추가 혹은 제거되는 것일 뿐 tries state가 변경되는 것은 아니어서 리렌더링이 일어나지 않는다는 말씀이시죠? (Memo도 사용했기 때문)

 

제가 이해한게 맞나요?...

0

zerocho

tries state가 변경돼서 리렌더링은 일어나고요. 다만 자식 Try 캄포넌트는 리렌더링되지 않게 저희가 장치했으니 안일어나는겁니다.

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

0

204

2

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

0

88

2

렌더링 테스트 코드 (Hooks)

0

80

1

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

0

149

1

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

1

191

1

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

0

95

1

useMemo와 useCallback 사용 시기

0

207

2

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

0

226

1

action.type 불러오는 방식

0

222

2

onClickRedo 질문

0

172

1

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

0

248

1

npx webpack 실행시

0

313

1

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

0

235

1

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

0

311

1

react devtool이 enable 않됩니다.

0

531

2

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

0

412

2

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

0

331

1

npm run dev 할 때 에러발생

0

480

2

memo, PureComponenet, shouldComponentUpdate 관련 질문

0

206

1

devMiddleware의 필요성

0

352

1

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

0

935

2

path.join관련질문

0

282

2

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

0

374

1

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

1

491

4