
인트로
이제부터 React Hook에 대해 알아보면서 본격 리액트를 시작해보려고 합니다.
useState부터 시작해 보죠.
훅이 나타나게 된 이유는 공식 문서를 통해 알 수 있습니다. 꼭 읽어보세요.
Hook을 사용하여 함수형 프로그래밍을 할 수 있습니다.
useState
state를 함수 컴포넌트 안에서 사용할 수 있게 해 줍니다.
state를 추가하고 싶을 때 useState Hook을 이용하여 state를 사용할 수 있습니다.
우선 useState를 사용하려면 import를 해줘야 합니다.
import React, { useState } from "react";
다음과 같이 새로운 state 변수를 선언할 수 있습니다.
const [item, setItem] = useState(0);
이때 state 변수명은 아무렇게나 지으셔도 됩니다.
useState는 인자로 state의 초기값을 받고 state 변수와 해당 변수를 갱신할 수 있는 함수를 반환합니다.
setItem을 사용해서 item 값을 바꿀 수 있는 것이죠.
저는 버튼을 클릭했을 때 state 값이 바뀌는 실습을 진행하기 위해 초기값에 0을 주었습니다.
useState 대표 예제
그럼 이제 간단한 카운트 버튼 예제 코드를 봅시다. 가장 대표적인 예제입니다.
<div>state value : {item}</div>
<button onClick={incrementItem}>Increment</button>
<button onClick={decrementItem}>Decrement</button>
<button onClick={resetItem}>reset</button>
클릭했을 때 item 값이 증가하는 버튼, 감소하는 버튼, 초기값으로 리셋해 주는 버튼 총 3개의 버튼을 만들었습니다.
버튼을 클릭하면 해당하는 함수가 실행됩니다.
const incrementItem = () => setItem(item + 1);
const decrementItem = () => setItem(item - 1);
const resetItem = () => setItem(0);

버튼을 클릭했을 때 컴포넌트를 리렌더링 하는 코드를 useState Hook을 사용하여 짧고 간단하게 작성할 수 있었습니다.
Custom Hook
저는 노마드코더 강의를 들으면서 리액트 공부를 하고 있는데요. useState를 이용하여 Custom Hook을 만드는 예제를 진행하였습니다.
여기서 Custom Hook은 개발자가 직접 만든 hook을 말합니다.
커스텀 훅을 만들면서 useState 사용법을 익힐 수 있었습니다.
useInput
첫 번째 커스텀 훅은 useInput입니다.
element는 input 만 있으면 됩니다.
사용자가 input을 입력했을 때 유효성을 검사하여 값이 적절한 경우에만 input의 value가 바뀌는 그런 커스텀 훅입니다.
<h2>Here is Input</h2>
<input type="text" placeholder="name" {...name} />
직접 확인해 보도록 합시다.
const useInput = (initialValue, validator) => {
const [value, setValue] = useState(initialValue);
const onChange = (event) => {
// const value = event.target.value
const {
target: { value },
} = event;
let willUpdate = true;
if (typeof validator === "function") {
willUpdate = validator(value);
}
if (willUpdate) {
setValue(value);
}
};
return { value, onChange };
첫 번째 라인
useInput은 인자로 초기값과 유효성 검사를 위한 함수를 받습니다.
useState 반환값
value는 텍스트박스에 표시되는 텍스트입니다. 초기값은 아래 코드 블록에서 확인하실 수 있는데 인자로 'Hi '를 주었습니다.
요소값이 변경되었을 때 값이 적절하다면(willUpdate === true) setValue 함수를 이용하여 value 값을 경신해 줍니다.
onChange 함수
onChange 함수 내부가 좀 생소할 수 있는데 1)과 2)는 같은 동작을 합니다. destructuring에 대해서 저도 어서 공부해야겠네요...
여기서 value는 useState의 value가 아닙니다. 'shadowing'에 의해 여기서 value는 event로부터 온 value 값이 됩니다.
input 텍스트박스의 요소 값이 바뀔 때마다 해당 value의 유효성을 검사하고 적절하면 state 변수에 해당하는 value를 갱신해 줍니다.
// 1)
const {
target: { value },
} = event;
// 2)
const value = event.target.value
validator 함수
유효성을 검사하는 함수로 value의 길이를 10글자로 제한하고 있습니다.
const maxLen = (value) => value.length < 11;
const name = useInput("Hi ", maxLen);
console.log(name);
1)과 2) 역시 같은 동작을 한다고 합니다. 가독성면에서 아주 좋습니다. 왜 이렇게 되는지는 따로 블로깅을 또 하도록 하죠.
이렇게 텍스트박스에 값을 입력할 때마다 유효성 검사를 해주는 커스텀 훅을 만들어볼 수 있었습니다.
// 1)
<input type="text" placeholder="name" {...name} />
// 2)
<input type="text" placeholder="name" value={name.value} onChange={name.onChange} />

입력할 수 있는 문자열 길이가 10으로 제한되어있기 때문에 아무리 타이핑을 해도 더 이상 값이 입력되지 않습니다.
useTabs
Tab을 클릭하면 Tab에 해당하는 콘텐츠를 보여주는 훅입니다.

바로 확인해 봅시다.
const content = [
{
id: 1,
tab: "Section 1",
content: "This is Section 1",
},
{
id: 2,
tab: "Section 2",
content: "This is Section 2",
},
];
content 배열
객체로 구성된 배열입니다. 객체의 tab 값이 button 콘텐츠이고 객체의 content 값이 버튼을 눌렀을 때 보이는 값이 됩니다.
버튼(Tab)
map을 사용하여 content 요소만큼 button을 만들어줍니다. 각 버튼에 onClick 이벤트를 할당합니다.
버튼을 클릭했을 때 changeItem(index)가 실행되는 데 changeItem에는 state 변수를 갱신하는 함수인 setCurrentIndex가 할당되어 있습니다.
해당 콘텐츠보이기
currentItem.content 즉 최근 클릭한 tab에 해당하는 콘텐츠가 보이게 됩니다.
{content.map((section, index) => (
<button key={section.id} onClick={() => changeItem(index)}>
{section.tab}
</button>
))}
<div>{currentItem.content}</div>
const { currentItem, changeItem } = useTabs(0, content);
useTabs 인자
첫 번째 값으로는 초기 탭 즉 배열의 인덱스 값을 넘겨줍니다.
초기값으로 0을 넘겨주기 때문에 content[0] 값이 currentItem 값으로 할당됩니다.
미리 만들어놓은 content배열을 두 번째 인자로 전달해 줍니다. 이때 전달한 값이 배열이 아니거나 falsy 한 값일 경우 바로 함수를 종료합니다.
useTabs 반환값
currentItem에는 content 배열 인덱스에 해당하는 객체가 할당됩니다.
Section 1 Tab을 클릭했을 경우 currentIndex에 0, Section 2 Tab을 클릭했을 경우 currentIndex에 1이 들어갑니다.
즉 currentItem에는 각각 클릭했을 때 content[0], content[1]이 들어갑니다.
const useTabs = (initialTab, allTabs) => {
const [currentIndex, setCurrentIndex] = useState(initialTab);
if (!allTabs || !Array.isArray(allTabs)) {
return;
}
return {
currentItem: allTabs[currentIndex],
changeItem: setCurrentIndex,
};
};
결과적으로 버튼을 클릭했을 때 currentIndex 값이 최근 클릭한 버튼(탭)에 해당하는 index값으로 갱신되면서 currentItem의 값이 content[index] 값으로 바뀌고 해당 콘텐츠가 보이게 됩니다.
커스텀 훅 만들기 되게 재밌는 것 같네요. 나중에 나만의 커스텀 훅도 한 번 만들어봐야겠습니다.
일단 빨리 디스트럭처링 할당부터 공부해야겠어요^..
디스트럭처링 할당 내가 해냄
인트로리액트 코드를 보는데 디스트럭처링 할당이 빗발치더라고요.빠르게 이해하려면 디스트럭처링 할당에 대해서도 조금 더 살펴볼 필요가 있겠다는 생각이 들었습니다. 바로 시작하겠습니
i-did-it.tistory.com
노마드코더 실전형 리액트 훅 강의 내용을 참고하였습니다.
'내가 해냄 > React' 카테고리의 다른 글
리액트에서 SCSS 사용하기 내가 해냄 (0) | 2023.03.26 |
---|---|
useAxios 내가 해냄 (2) | 2023.03.23 |
[유용한 기능]useNotification, useFullscreen 내가 해냄 (1) | 2023.03.23 |
useEffect 내가 해냄 (1) | 2023.03.22 |
[유용한 기능]useConfirm, usePreventLeave 내가 해냄 (0) | 2023.03.22 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!