1. Hook
Hook의 규칙: https://reactjs.org/docs/hooks-rules.html#gatsby-focus-wrapper
리액트 훅은 class를 사용하지 않아도 state나 다른 리액트의 기능을 사용할 수 있도록 돕는 기능입니다.
16.8 버전부터 추가되었으며, 여러가지 제약사항이 있습니다.
1. 최상위에서만 Hook을 호출해야 합니다.
반복문이나 조건문, 중첩된 함수에서 호출하면 안됩니다. React 함수의 최상위에서 Hook이 실행되어야 합니다.
2. React 함수 내에서만 호출하세요.
일반 자바스크립트 함수에서 호출하면 안됩니다. 리액트 안이 아닌 일반 자바스크립트 함수로는 Hook을 제대로 실행할 수 없습니다.
2. 어떻게 내부적으로 돌아가는 것일까?
리액트 내부적으로 Hook과 관련된 배열을 가지고 있는 것 같다.
컴포넌트가 만들어질 때, Hook의 배열을 세팅하는 방식으로 구현하면 아래와 같다.
// react.js
const hooks = [];
let currentComponent = 0;
export class Component {
constructor(props) {
this.props = props;
}
}
function createDOM(node) {
if (typeof node === 'string' || typeof node === 'number') {
return document.createTextNode(node);
}
const element = document.createElement(node.tag);
node.props && Object
.entries(node.props)
.forEach(([name, value]) => element.setAttribute(name, value));
node.children && node.children
.map(createDOM)
.forEach(element.appendChild.bind(element));
return element;
}
function makeProps(props, children) {
return {
...props,
children: children.length === 1 ? children[0] : children
}
}
function useState(initValue) {
let position = currentComponent - 1;
if (!hooks[position]) {
hooks[position] = initValue;
}
const modifier = nextValue => {
hooks[position] = nextValue;
};
return [ hooks[position], modifier ];
}
export function createElement(tag, props, ...children) {
if (typeof tag === 'function') {
if (tag.prototype instanceof Component) {
const instance = new tag(makeProps(props, children));
return instance.render();
}
hooks[currentComponent] = null;
currentComponent++;
if (children.length > 0) {
return tag(makeProps(props, children));
} else {
return tag(props);
}
}
return { tag, props, children };
}
export const render = (function() {
let prevDom = null;
return function(vdom, container) {
if (prevDom === null) {
prevDom = vdom;
}
// diff
container.appendChild(createDOM(vdom));
}
})();
tag 함수가 호출되기 전에 Hook을 초기화 한다. (Hook 세팅)
useState의 경우 hooks가 없는 경우 배열에다가 현재 컴포넌트와 인덱스 값을 넣는다.
함수 Component가 호출된 다음에 Hook이 함수 안에서 호출되어서 index가 맞아 떨어지는 것이 이 코드의 핵심이다.
그래서 순서가 중요하고, 순서 보장이 Hook에서는 중요하다.
본 코드는 리액트 훅을 이해할 수 있는 수도코드 수준으로 제작된 것이라서
실제 리액트 라이브러리 내의 훅과는 코드가 다소 다를 수 있다.
React 만들기 시리즈는 여기까지 입니다.
끝!