관리 메뉴

프론트엔드 정복하기

React hooks로 Tab 기능 구현 본문

React/hooks

React hooks로 Tab 기능 구현

GROWNFRESH 2021. 1. 27. 13:57

 

React hooks로 탭 기능을 어떻게 구현할까.

 

 

아래 그림처럼 상단에 탭타이틀이 있고, 하단에 탭 콘텐츠가 있으며, 각 탭 타이틀을 클릭할 경우 해당 컨텐츠가 보이도록 할 것이다.

  • 1 ) 탭타이틀을 클릭하면 해당 타이틀에 'is-active'라는 class를 부여해서 포커싱된 탭에 맞는 스타일을 부여할 것이고,
  • 2 ) 각 탭을 클릭하면 해당하는 콘텐츠만 화면 보여지도록 할 것이다.

 

 


 

먼저 (1) 탭 Title, (2) 탭 Content를 담은 배열을 선언한다.

const tabContArr=[
        {
            tabTitle:(
                <li> 탭1 </li>
            ),
            tabCont:(
                <div> 탭1 내용 </div>
            )
        },
        {
            tabTitle:(
                <li> 탭2 </li>
            ),
            tabCont:(
                <div> 탭2 내용 </div>
            )
        }
    ];

 

 

return되는 템플릿에 map 함수를 사용해서 각 obj의 탭 Title이 작성되도록 한다.

return (
    <ul className="tabs is-boxed">
	    {tabContArr.map((section, index)=>{
		    return section.tabTitle
	    })}
    </ul>
);

(위와 같이 각 tabContArr obj의 tabTitle을 return한다.)

 

 

 

이 때 각 탭 Title을 클릭하면 => 해당 태그의 index 값이 useState에 저장되도록 한다.

 

[ active한 index값을 관리하는 State ] 를 먼저 선언한다.

const [activeIndex, setActiveIndex] = useState(0);

// initialState에 원하는 index값을 입력하면 된다.
// 초기 화면에 0번째 탭이 active되길 원한다면 0값을 입력한다.

 

 

이제 탭타이틀을 클릭하면 해당 탭의 index값을 <activeIndex State>로 셋팅하는 함수를 생성한다.

앞서 작성했던 tabContArr 배열 내에서 작성해줄 것이다.

const [activeIndex, setActiveIndex] = useState(0);

const tabContArr=[
        {
            tabTitle:(
                <li onClick={()=>tabClickHandler(0)}> 탭1 </li>
            ),
            tabCont:(
                <div>탭1 내용</div>
            )
        },
        {
            tabTitle:(
                <li onClick={()=>tabClickHandler(1)}> 탭2 </li>
            ),
            tabCont:(
                <div>탭2 내용</div>
            )
        }
    ];
    
    
 const tabClickHandler=(index)=>{
 	setActiveIndex(index)
 }

 

 

 

tabContArr 배열 중에  activeIndex에 해당하는 tabCont를  ul태그 (탭 Title) 아래에서 보여줄 것이다.

return (
    <ul className="tabs is-boxed">
	    {tabContArr.map((section, index)=>{
		    return section.tabTitle
	    })}
    </ul>
    
    // activeIndex의 탭콘트만 보여줌!
    <div>
	    { tabContArr[activeIndex].tabCont }
    </div>
);

 

 

 

>>>>>>  이제 탭타이틀을 클릭하면 해당 탭콘텐츠만 보일것이다!

 

 

 

마지막으로 클릭한 탭타이틀에 'is-active' class를 부여할 것이다.

[ activeIndex가 각 탭타이틀의 index일치하면 ]   ====>>>  'is-active' 클래스를 부여하도록 할 것이다.

const tabCont=[
        {
            tabTitle:(
                <li className={activeIndex===0 ? "is-active" : ""} onClick={()=>tabClickHandler(0)}>
					탭1
                </li>
            ),
            tabCont:(
                <div>탭1 내용</div>
            )
        },
        {
            tabTitle:(
                <li className={activeIndex===1 ? "is-active" : ""} onClick={()=>tabClickHandler(1)}>
                    탭2
                </li>
            ),
            tabCont:(
                <div>탭2 내용</div>
            )
        }
    ];

 

 

 

 

 

아래는 소스 전문

더보기
import React, {useState} from 'react';

export default function Orgchart() {
    const [activeIndex, setActiveIndex]=useState(0);

    const tabClickHandler=(index)=>{
        setActiveIndex(index);
    };

    const tabContArr=[
        {
            tabTitle:(
                <li className={activeIndex===0 ? "is-active" : ""} onClick={()=>tabClickHandler(0)}> 탭1 </li>
            ),
            tabCont:(
                <div> 탭1 내용 </div>
            )
        },
        {
            tabTitle:(
                <li className={activeIndex===1 ? "is-active" : ""} onClick={()=>tabClickHandler(1)}> 탭2 </li>
            ),
            tabCont:(
                <div> 탭2 내용 </div>
            )
        }
    ];

    return (
        <div>
          <ul className="tabs is-boxed">
            {tabContArr.map((section, index)=>{
                return section.tabTitle
            })}
          </ul>
          <div>
          	{tabContArr[activeIndex].tabCont}
          </div>
        </div>
    );
}