
Hook이 준수해야 할 두가지 규칙
1) 최상위(at the Top Level)에서만 Hook을 호출해야 한다.
반복문, 조건문 혹은 중첩된 함수 내에서 Hook을 호출 하면 안된다.
대신 early return이 실행되기 전에 항상 React 함수의 최상위(at the top level)에서 Hook을 호출해야 한다.
이 규칙을 따르면 컴포넌트가 렌더링 될 때마다 항상 동일한 순서로 Hook이 호출되는 것이 보장 된다.
이러한 점은 React가 useState 와 useEffect 가 여러 번 호출되는 중에도 Hook의 상태를 올바르게 유지할 수 있도록 해준다.
2) 오직 React 함수 내에서 Hook을 호출해야 한다.
React 함수 컴포넌트에서 Hook을 호출하기
Custom Hook에서 Hook을 호출하기.
참고 : React 공식 문서
참고 : https://velog.io/@gyomni/React-Hook-useEffect-is-called-conditionally
수정 전 코드
import { useState } from "react"
const useTabs = (initialTab, allTabs) => {
if (!allTabs || !Array.isArray(allTabs)){
return;
}
const [currentIndex, setCurrentIndex] = useState(initialTab);
return {
currentItem: allTabs[currentIndex],
changeItem: setCurrentIndex
};
};
export default useTabs;
수정 후
import { useState } from "react"
const useTabs = (initialTab, allTabs) => {
const [currentIndex, setCurrentIndex] = useState(initialTab);
if (!allTabs || !Array.isArray(allTabs)){
return;
}
return {
currentItem: allTabs[currentIndex],
changeItem: setCurrentIndex
};
};
export default useTabs;
이후 오류 중
ERROR
Cannot destructure property 'currentItem' of '(0 , _component_useTabsWEBPACK_IMPORTED_MODULE_4.default)(...)' as it is undefined. 가 발생하였는데 이는
문제는 useTabs 커스텀 훅의 사용 부분에서 발생하고 있습니다. useTabs에서 반환하는 객체 중 currentItem과 changeItem을 사용하는 부분이 문제가 되고 있었다.
const{ currentItem, changeItem} = useTabs(0, useTabs.content);
return (
<div className="App">
<h1> Hello {item}</h1>
<h2> 열심히 해보자</h2>
<button onClick={incrementItem}> incrementItem</button>
<button onClick={decrementItem}> decrementItem</button>
<br></br>
<input placeholder='Name' {...name} />
<br></br>
<h3>{useInput}</h3>
<br></br>
<br></br>
{useTabs.content.map((section, index) => (
<button onClick={() => changeItem(index)}>{section.tab}</button>
))}
<div> {currentItem.content}</div>
</div>
);
}
export default App;
주요변경사항
1. 현재 코드에서 useTabs.content 대신에 직접 content 배열을 전달해야했었다. 따라서
const { currentItem, changeItem } = useTabs(0, content);에서 useTabs.content를 content로 수정하였다.
2. useTabs 훅에서 반환된 객체의 currentItem 속성은 현재 선택된 탭에 대한 정보를 포함각 탭은 content 배열의 객체이며, 해당 객체의 tab 속성에는 탭의 제목이 저장되어 있기에 map 함수에서 버튼의 내용을 section.tab으로 변경하였다.
최종 수정을 통해


해결되었다.