Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[10장][상훈] 리액트 17과 18의 변경사항 살펴보기 #51

Open
bbearcookie opened this issue May 17, 2024 · 2 comments
Open

Comments

@bbearcookie
Copy link
Collaborator

bbearcookie commented May 17, 2024

퀴즈

리액트 17 미만 버전에서는 아래 코드를 실행하면 크래쉬가 났었습니다.
그래서 handleChange 함수 내부의 상단부분에 e.persist() 를 사용해야 했었는데, 17부터는 왜 더 이상 e.persist() 를 사용하지 않아도 비동기 코드 내에서 정상적으로 이벤트 객체를 가져와서 사용할 수 있게 변경되었나요?

function handleChange(e) {
  setData(data => ({
    ...data,
    // This crashes in React 16 and earlier:
    text: e.target.value
  }));
}

정답
리액트 17 미만 버전에서는 이벤트 객체를 이벤트 풀에 넣고 꺼내서 사용한 뒤, 사용을 마치면 null로 초기화하는 방식으로 되어있었습니다. (이벤트 풀링) 그러나 17 이후에는 이러한 작업이 최적화에 별로 도움을 주는 이점도 없을 뿐더러 개발자에게 혼란을 야기한다고 생각하여 제거되었기 때문에 이젠 발생하지 않는 현상입니다.

댓글 작성법

(다음과 같이 답을 작성해 댓글로 달아주세요)
<details>
<summary>정답</summary>
<div markdown="1">
정답 설명
</div>
</details>

@bbearcookie bbearcookie self-assigned this May 17, 2024
@khakhiD
Copy link
Collaborator

khakhiD commented May 17, 2024

정답

답: 리액트 17 버전 이후부터는 이벤트 풀링을 제거했기 때문이다.

이벤트 풀링이란 이벤트 객체를 재사용하여 리액트의 성능을 최적화 하기 위한 기술이었다.

이벤트 핸들러 내에서 비동기 작업을 수행할 때 이벤트 객체가 풀링에 의해 재사용되지 않았기 때문에, 이벤트 객체의 속성에 접근하면 객체의 속성들이 초기화되거나 변경될 수 있었기 때문에 안전하지 않았다. 이벤트 객체를 사용한 뒤 내부 속성이 null로 초기화되었다.

리액트 17 버전 이후 부터는 이벤트 객체가 더 이상 재사용되지 않고, 이벤트 핸들러에서 비동기 작업을 자유롭게 사용할 수 있다.

e.persist()는 리액트의 합성 이벤트 객체에서 이벤트 풀링을 방지하기 위해 사용했다. 특정 이벤트 객체를 이벤트 풀링에서 제외하는 메서드였는데, 이제 이벤트 풀링이 제거되었으므로 사용할 필요가 없게 되었다.

@jkea1
Copy link
Collaborator

jkea1 commented May 31, 2024

정답
  • 우리가 평소 이벤트 핸들링 함수의 인자로 받는 eSyntheticEvent 객체로 여러 속성과 메서드를 포함합니다. 자주 쓰는 속성에는 e.target, e.type, e.currentTarget 등이 있고 메서드에는 e.preventDefault(), e.stopPropagation() 가 있습니다. 평소 자주 사용하지 않았지만 e.persist() 메서드도 SyntheticEvent 객체에 포함 되며 SyntheticEvent 객체가 풀링 되지 않도록 유지하는 역할을 합니다.

  • 리액트 17 이전 버전에서는 SyntheticEvent 객체가 이벤트 핸들러가 끝난 후 자동으로 풀링(pooling)되어 재사용되었습니다. 이는 메모리 사용을 줄이고 성능을 최적화하기 위한 방법이었습니다. SyntheticEvent가 풀링되면 해당 이벤트 객체의 모든 속성은 초기화되어 나중에 비동기 코드 내에서 참조하려고 하면 문제가 발생할 수 있었습니다. 이러한 이유로, 이벤트 객체를 비동기 코드에서 사용하려면 e.persist() 메서드를 호출하여 풀링을 방지하고 이벤트 객체를 유지해야 했습니다.

  • 리액트 17에서는 SyntheticEvent 객체가 자동으로 풀링되지 않고, 이벤트 핸들러가 끝난 후에도 유효하게 유지됩니다. 이에 따라 e.persist()를 호출하지 않고도 비동기 코드 내에서 이벤트 객체를 안전하게 사용할 수 있게 되었습니다.

@jkea1 jkea1 removed the 진경 label May 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants