React는 dependency array에서 변경이 일어났는지 어떻게 알까?
클로저란?
function makeFunc() {
var name = "Mozilla";
function displayName() { // displayName() is the inner function, a closure
alert(name); // displayName() uses variable declared in the parent function
}
return displayName;
}
var name = "kkkk";
const myFunc = makeFunc();
myFunc(); // Mozilla
- 클로저란, 주변 상태 (렉시컬 환경)에 대한 참조와 함께, 번들로 묶인 기능의 조합.
- 클로저를 사용하면 내부 함수에서 외부함수의 범위에 접근 가능
- myFunc 함수를 실행하면 여전히 Mozilla 가 출력되는건, 내부함수인 display 함수가 여전히 외부함수를 기억하고 있는 것
useState 내부 코드
function useState(initialState) {
var dispatcher = resolveDispatcher();
return dispatcher.useState(initialState);
useState 뿐만 아니라 모든 훅의 내부 코드는 위의 형태
dispatcher에는 resolveDispatcher함수의 결과가 할당되고, dispatcher의useState메서드에 초기값을 전달하고 반환된 값을 리턴한다.
function resolveDispatcher() {
var dispatcher = ReactCurrentDispatcher.current;
return dispatcher;
}
그리고 resolveDispatcher는 ReactCurrentDispatcher라는 객체의 current프로퍼티를 반환하는데
여기서 ReactCurrentDispatcher는 전역에 설정되어있는 객체이다.
따라서 useState가 반환한 상태의 배열은 전역 객체로부터 오고, hook을 호출하면 클로저 동작에 의해 컴포넌트 밖에 있는 외부 스코프에 존재하는 상태에 접근 가능한 것. 컴포넌트에서 값의 변경이 있으면 외부의 값이 변경되고 컴포넌트 내부에서 사용된다.
따라서 함수컴포넌트의 바디 전체가 리렌더링 되어도, 상태는 유지된다.
비슷하게 동작하도록 구현해보자면 아래와 같음
let _value;
export useState(initialValue){
if (_value === 'undefined') {
_value = initialValue;
}
const setValue = newValue => {
_value = newValue;
}
return [_value, setValue];
}
- dependecy array 에 있는 것들도 위와 같이 동작하겠지!