React Hooks를 활용한 간단한 React 구현하기
2024-10-21 08:12:53React Hooks의 소개
React는 많은 개발자들에게 사랑받는 JavaScript 라이브러리로, 사용자 인터페이스를 구축하는 데 주로 사용됩니다. React의 강력한 기능 중 하나는 컴포넌트 기반 아키텍처와 상태를 관리하는 방법입니다. 이 튜토리얼에서는 React의 Hooks, 특히 useState에 대한 내용을 깊이 있게 다루어보겠습니다. 쉽게 구현할 수 있는 방법도 함께 소개할 예정입니다. 중간중간 교정 사항과 함께 진행합니다.
이전 장에서 다룬 내용 정리
이전 장에서는 가상 DOM(vDOM)에 대한 개념을 다루었고, vDOM을 비교하는 방법과 CSS 스타일 속성을 효과적으로 처리하는 방법에 대해 설명했습니다. 하지만 몇 가지 수정 사항이 남아있었으므로, 이를 정리한 후 본격적으로 Hooks에 대한 내용을 진행하겠습니다.
vDOM 비교 기능 수정
JavaScript에서 두 함수가 같은 경우는 오직 참조가 같을 때입니다. 이러한 특성을 고려하여 vDOM 비교 시 함수 비교를 생략하도록 코드를 수정하였습니다. 아래 코드에서 key와 함수 비교를 건너뛰도록 개선하였습니다:
if (aProps[key] instanceof Function && bProps[key] instanceof Function) continue
이 개선 사항은 성능 최적화에도 기여할 것입니다.
CSS 처리 방식 변경
CSS 스타일은 특별한 속성으로 다루어져야 하며, .style 속성으로 접근해야 합니다. 다음과 같은 방식으로 CSS 속성을 보다 잘 처리할 수 있도록 개선하였습니다:
if (name === 'style') {
Object.entries(value as Record<string, unknown>).forEach(([styleName, styleValue]) => {
element.style[styleName as any] = styleValue as any
})
}
이제 vDOM을 다루는 방식이 보다 명확해졌습니다. 이러한 개선 후 다음 단계로 전진하겠습니다.
Hooks의 개념
이 장의 주제인 Hooks는 React의 기능 중 상태를 관리하기 위한 강력한 도구입니다. 특히 useState 훅을 사용하면 컴포넌트에서 상태를 손쉽게 관리할 수 있습니다. 이전 구현에서는 상태를 유지하기 위한 방법이 다소 복잡하였으나, 훅을 사용함으로써 코드가 한층 간결해질 것입니다.
useState 훅 구현하기
useState 훅은 상태 변수를 정의하고 이를 업데이트하기 위한 함수 쌍을 반환합니다. 이러한 방식은 React의 기존 구현과는 약간 다릅니다. 아래와 같이 초기 값을 받아들이는 useState의 시그니처를 설정할 수 있습니다:
function useState<T>(initialValue: T): [() => T, (newValue: T) => void] {
// 구현 내용
}
내부 상태 저정 방식
컴포넌트가 다시 렌더링될 때 상태를 잃지 않기 위해 적절한 장소에 값을 저장해야 합니다. 이를 위해 Fiber 인터페이스에 상태를 저장할 수 있는 필드를 추가합니다:
interface Fiber {
hooks?: {
state: unknown[]
},
}
이렇게 구현하면, 각 컴포넌트에서 필요할 때마다 이전 상태를 쉽게 참조할 수 있습니다.
Hooks의 마운트 프로세스
Hooks는 mount 함수에서 등록되며, 이를 통해 컴포넌트의 렌더링 시기와 상태를 연결합니다. 아래와 같이 mount 함수를 수정하여 이전 fiber 구조체의 상태를 저장하도록 합니다:
export function mount(app: FuncComponent, props: VDomAttributes, children: VDomNode[], parent: HTMLElement) {
reRender = () => {
// render 처리 로직
}
reRender()
}
상태 업데이트 함수
상태를 업데이트하기 위한 함수는 훅에서 반환되는 setter 함수입니다. 다음에는 이 setter 함수를 사용하여 상태를 업데이트하는 방법을 구현해보겠습니다:
const setState = (newState: T) => {
oldFiber!.hooks!.state[hookIndex] = newState
reRender()
}
위와 같이 상태를 업데이트하고 나면, reRender 함수를 호출하여 컴포넌트를 다시 렌더링합니다. 이렇게 함으로써, 상태 변화에 따른 UI 갱신이 이루어집니다.
Hooks 사용 시 유의 사항
React의 Hooks를 사용할 때 몇 가지 규칙을 반드시 지켜야 합니다. 다음과 같은 기본 원칙을 통해 React의 예상치 못한 행동을 피할 수 있습니다:
- Hooks는 상위 함수에서만 호출해야 합니다.
- 조건문이나 반복문 내부에서 Hooks를 호출하지 마십시오.
이러한 원칙을 따르면, 상태 관리를 보다 효과적으로 수행할 수 있습니다.
간단한 React 예제
마지막으로, useState 훅을 사용하여 카운터 예제를 만들어 보겠습니다. 사용자가 버튼을 클릭할 때마다 카운트가 증가합니다.
const App: FuncComponent = (props: VDomAttributes, _: VDomNode[]) => {
const [cnt, setCnt] = useState(0)
return <div>
<button onClick={() => setCnt(cnt() + 1)}>Click me</button>
<p>Count: {cnt()}</p>
</div>
}
이 코드를 통해 카운터 앱의 기본적인 동작 방식을 구현해봤습니다. 사용자 인터페이스의 반응성이 강조되는 예제라고 하겠습니다.
결론
React의 Hooks, 특히 useState의 개념을 통해 상태 관리가 유용해졌습니다. 이번 글에서는 Hooks의 기본 개념과 useState 훅을 통해 어떻게 손쉽게 상태를 관리할 수 있는지를 살펴보았습니다. 이러한 기법을 통해 더욱 효율적이고 유지보수가 용이한 React 애플리케이션을 만들어 나갈 수 있을 것입니다.
참고 문헌
위의 링크를 통해 React에 대한 더욱 상세한 내용을 확인해 보실 수 있습니다.