A ref is a plain JavaScript object
with a single property called current,
which you can read or set.
- React 공식 문서
React의 useRef 훅은 컴포넌트 내에서 변수를 만들고 유지합니다.
리렌더링 되어도 이 값은 유지됩니다.
어떻게 가능할까요?
해당 글은 짧은 설명을 통해 기본적인 원리에 대한 이해를 돕고자 합니다.
클로저에 대한 기본적 지식이 있는 독자를 상정하고 쓴 글입니다.
(다음에 클로저에 대해서도 따로 다뤄보겠습니다. 원문에서는 클로저에 대한 기본 설명을 추가했으나 해당 글에서는 생략되었습니다!)
## useRef는 React 컴포넌트의 렉시컬 환경에 대한 참조를 유지합니다.
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
* @flow
*/
import type {RefObject} from 'shared/ReactTypes';
// an immutable object with a single mutable value
export function createRef(): RefObject {
const refObject = {
current: null,
};
if (__DEV__) {
Object.seal(refObject);
}
return refObject;
}
https://github.com/facebook/react/blob/main/packages/react/src/ReactCreateRef.js
useRef로 생성된 ref 객체 내에는 current property가 존재하고 current property에 값이 유지됩니다. useRef 훅은 클로저(closure)를 활용하여 현재 property를 유지하고 렌더링 되더라도 값을 보존합니다.
useRef가 클로저를 활용하기 때문에 useRef로 생성한 객체는 컴포넌트가 렌더링될 때마다 새로 생성되는 것이 아니라 이전 객체가 계속 사용됩니다.
클로저는 함수가 속한 렉시컬 스코프를 기억하며
함수가 렉시컬 스코프 밖에서 실행될 때에도
이 스코프에 접근할 수 있게 하는 기능을 뜻한다.
- Kyle Simpson
React에서 함수 컴포넌트는 렉시컬 스코프에 의해 실행되며,
useRef로 생성한 ref객체는 해당 함수 컴포넌트의 렉시컬 환경에 대한 참조를 유지합니다.
그렇기 때문에 useRef로 생성한 ref객체는 함수 컴포넌트 내부에서 생성된 클로저에 의해 계속 접근될 수 있습니다.
React의 useRef는 이러한 클로저 메커니즘을 활용하여 컴포넌트가 리렌더링되어도 참조를 유지합니다.
이것은 useRef 객체가 렌더링 사이에 동일한 객체로 유지된다는 뜻입니다.
또한, useRef로 생성된 ref 객체의 current 값이 변경되더라도 React는 이를 감지하지 않습니다. 이는 useState에러 리턴된 state와 달리, React가 ref 객체의 변경을 감지하지 않기 때문이고 useRef 객체는 React가 관리하는 상태(state)가 아니기 때문입니다.
React에서 컴포넌트 리렌더링이 일어나는 경우
1. state changes
2. parent re-render
3. context changes
4. hook changes
공식 문서에서 소개된 대로 useRef에 의해 반환된 ref객체는 말 그대로 순수 자바스크립트 객체이고 이 객체의 레퍼런스 주소가 메모리에 저장되어 있습니다.
(JavaScript에서 객체는 참조에 의해 전달됩니다. 즉, 객체를 변수에 할당하면 변수에는 객체의 주소가 저장되고, 실제 객체는 메모리의 특정 위치에 저장됩니다. )
원문 - https://developer-dson.tistory.com/38
Reference
https://adevnadia.medium.com/react-re-renders-guide-why-react-components-re-render-a4efab132c10
https://www.joshwcomeau.com/react/why-react-re-renders/
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
https://dev.to/dylanju/useref-3j37
https://hewonjeong.github.io/deep-dive-how-do-react-hooks-really-work-ko/
다음 내용이 궁금하다면?
이미 회원이신가요?
2024년 5월 5일 오전 11:19