새소식

React ·JS·TS

(React Hooks) useState - useTabs

  • -
const content = [
  {
    tab: "Section1",
    content: "Content of Section 1"
  },
  {
    tab: "Section2",
    content: "Content of Section 2"
  }
];

export default function App() {
  return (
    <div className="App">
      <h1>Hello</h1>
      {content.map((section) => (
        <button key={section.tab}>{section.tab}</button>
      ))}
    </div>
  );
}

content 에서 tab의 값을 section.tab으로 호출하여 출력해준다.

tab의 갯수만큼 버튼이 return된다.

 

 

 

 

const useTabs = (initialTab, allTabs) => {
  const [currentIndex, setCurrentIndex] = useState(initialTab);
}

useTabs 에  초기 탭 인덱스와 탭 정보가 담긴 배열 (initialTab, allTabs)의 인자를 받아서

useState(initialTab) 을 작성하여 useState가 항상 initalTab을 갖게 한다

 

 

 

 

  const tabs = useTabs(0, content);

App함수에서 tabs라는 변수를 선언하여 content배열에 담긴 0번 인덱스의 값을 담아준다.

 

 

 

 

const useTabs = (initialTab, allTabs) => {
  const [currentIndex, setCurrentIndex] = useState(initialTab);
  if (!allTabs || !Array.isArray(allTabs)){
    return;
  }
  return {
    currentItem : allTabs[currentIndex],
  }
}

if (!allTabs || !Array.isArray(allTabs)) 에서 배열이 아닐땐 바로 return을 시키고

 

배열일 경우엔 현재 선택된 탭의 정보와 탭을 변경할 수 있는 함수를 반환.

currentItem(현재 선택된 탭의 정보), changeItem(탭을 변경할 수 있는 함수)

이 함수를 호출하면 해당 인덱스의 탭으로 변경된다.

 

 

 

  const {currentItem} = useTabs(0, content);

받아오는 useTabs의 값을 {currentItem}으로 바꿔주고

      <div>
        {currentItem.content}
      </div>

해당 값이 출력 될 수 있게 버튼아랫쪽에 값을 적어준다.

인덱스 0 번의 content 값이 고정으로 출력이 되기 때문에 0 을 index를 바꿔줄 요소가 필요하다

 

 

 

  return {
    currentItem : allTabs[currentIndex],
    changeItem : setCurrentIndex
  }

useTabs의 index값을 바꿔줄 changeItem : setCurrentIndex을  return해준다

 

 

 

 

export default function App() {
  const {currentItem, changeItem} = useTabs(0, content);
  return (
    <div className="App">
      <h1>Hello</h1>
      {content.map((section, index) => (
        <button onClick={()=> changeItem(index)} key={section.tab}>{section.tab}</button>
      ))}
      <div>
        {currentItem.content}
      </div>
    </div>
  );
}

{currentItem, changeItem}으로 changeItem 값을 받아준다
이후 버튼의 onClick으로 changeItem을 호출하여 index번호로 값을 받아준다

클릭을 했을 때 setCurrentIndex는 changeItem으로 useState를 업데이트 시켜 

currentIndex의 currentItem을 바꿔주어 모든것을 새로고침한다.

 

 

 

 

 

const content = [
  {
    tab: "Section1",
    content: "Content of Section 1"
  },
  {
    tab: "Section2",
    content: "Content of Section 2"
  }
];

const useTabs = (initialTab, allTabs) => {
  const [currentIndex, setCurrentIndex] = useState(initialTab);
  if (!allTabs || !Array.isArray(allTabs)){
    return;
  }
  return {
    currentItem : allTabs[currentIndex],
    changeItem : setCurrentIndex
  }
}

export default function App() {
  const {currentItem, changeItem} = useTabs(0, content);
  return (
    <div className="App">
      <h1>Hello</h1>
      {content.map((section, index) => (
        <button onClick={()=> changeItem(index)} key={section.tab}>{section.tab}</button>
      ))}
      <div>
        {currentItem.content}
      </div>
    </div>
  );
}

전체코드

 

 

 

## 트러블슈팅

const useTabs = (initialTab, allTabs) => {
  if (!allTabs || !Array.isArray(allTabs)){
    const [currentIndex, setCurrentIndex] = useState(initialTab);
    return;
  }
  return {
    currentItem : allTabs[currentIndex],
    changeItem : setCurrentIndex
  }
}

위 코드를 작성할 때 

React Hook "useState" 오류 해결방법

 

React Hook "useState" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?

 

 

 

 

const useTabs = (initialTab, allTabs) => {
  const [currentIndex, setCurrentIndex] = useState(initialTab);
  if (!allTabs || !Array.isArray(allTabs)){
    return;
  }
  return {
    currentItem : allTabs[currentIndex],
    changeItem : setCurrentIndex
  }
}

 

위와 같은 에러가 떴을 때 아래와 같이 useState()를 최상단으로 이동시켜주시면 된다.

 

 

setState >> 모든것을 새로고침 해준다(re-render)

render function이 없어도 render 가능

'React ·JS·TS' 카테고리의 다른 글

Lifecycle Methods(생명주기 메서드)  (1) 2023.10.16
(React Hooks) useEffect - useTitle / useClick  (1) 2023.10.16
(React Hooks) useEffect  (1) 2023.10.16
(React Hooks) useState - useInput  (0) 2023.10.16
(React Hooks) useState  (0) 2023.10.16
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.