자바스크립트 클로저 실제로 활용해서 문제 해결하면서 드디어 이해했다

배경 설명
ReactQuill 텍스트 에디터에서 이미지 업로드 기능 구현 중.
AdminEditor 컴포넌트 하위에 별도의 이미지 업로드 컴포넌트(ImageUploader) 존재.
ImageUploader에서 이미지 Input 받아서, Quill 에디터가 있는 부모 컴포넌트(AdminEditor)에서 사용자 입력 중 커서가 있는 위치에 해당 이미지를 삽입해야 한다.
문제
자식 컴포넌트(ImageUploader)가 부모 컴포넌트(AdminEditor)의 매번 바뀌는 ref값(커서가 있는 위치)을 어떻게 알고 그걸 활용하는가?
커서 위치 정보 = quillInstanceRef
에 있음.
그러니 반드시 AdminEditor에 있는 정보이고, props로 값을 전달해줄 수도 없음.
커서 옮길 때마다 컴포넌트 리렌더링 할 거야?
해결책
AdminEditor에서 함수를 정의하고 그걸 ImageUploader에 props로 보내면 클로저를 통해서 활용할 수 있다.
// AdminEditor.tsx
function AdminEditor = () => {
const quillInstanceRef = useRef(null); // ← 이 변수는 AdminEditor 스코프에 있음
const insertImage = (imageUrl: string) => {
// 이 함수는 정의될 때 quillInstanceRef에 대한 참조를 "기억"함
if (quillInstanceRef.current) { // ← 여전히 AdminEditor의 quillInstanceRef에 접근
const range = quillInstanceRef.current.getSelection(true);
// ...
}
};
return (
<>
{/* ... */}
<ImageUploader
onImageInsert={insertImage} // ← 함수를 props로 전달
/>
</>
);
};
함수 정의 시점:
insertImage
함수가 정의될 때, 이 함수는 자신의 정의된 스코프(AdminEditor)에 있는 모든 변수들의 참조(메모리 주소값)을 기억.함수 전달:
insertImage
함수가 props로 전달될 때, 함수와 함께 클로저도 전달.ImageUploader에서
onImageInsert
를 호출: AdminEditor에서 정의된insertImage
함수 실행. 이 함수는 여전히 AdminEditor의quillInstanceRef
에 접근할 수 있다.
quillInstanceRef
에 저장된 값이 전달되는 것이 아니다!!quillInstanceRef
의 참조(주소값) 이 전달되는 것이다.insertImage
함수가 클로저를 통해 원래 스코프의 변수들을 "기억"하고 있기 때문에, 어디서 호출되든 원래 변수에 접근할 수 있는 것.
참나 변수를 기억한다, 변수를 참조한다는 표현을 내가 이해 못 하고 있던 거였다
주소값 얘기였구나
진작 그렇게 설명해주지