React Hooks (2) - useTab

김민석·2020년 8월 10일
0

React Hooks

목록 보기
3/11

이번에는 useTab 작업을 해보겠습니다.
useTab 이란 버튼을 클릭했을때 해당 버튼의 내용을 다르게 보여주는 것을 뜻합니다.
함수명은 다르게 하셔도 상관없습니다.

우선 컨텐츠를 생성해주겠습니다.

해당 컨텐츠는 tab과 content를 가지며 내용은 다음과 같습니다.

그 다음 map을 이용해 버튼 2개를 생성해줍니다.


그러면 2개의 버튼이 생성되게 됩니다. 당연히 컨텐츠 속성의 개수를 추가하면 더 많은 버튼이 생성되게 됩니다.
그 다음 버튼의 해당 section의 내용이 content가 출력이 되도록 해야합니다.

그래서 이런식으로 tab을 사용해보겠습니다. useTab의 기본값은 0으로 주게되면 우리는 Tab을 가지게 됩니다.

그리고 우리는 선택한 tab의 content를 얻는게 목적이죠? 그 말은 내가 현재 선택한 content의 인덱스를 얻고 싶다는 것입니다.
useTab에 0을 주었기 때문에 우리는 content[0]을 얻고자 하는 것이고 따라서 해당하는 값을 어딘가에서 return 받아야 합니다.

그래서 App 위에 위의 이미지처럼 useTab을 정의했는데 오류가 발생하게 되죠? 이는 useTab에서 매개변수를 하나만 받고 있기 때문입니다. 따라서 매개변수를 하나 추가해줘야 합니다. 여기서 추가 설명을 하나 하자면 currentItem은 allTabs를 가지고 리턴됩니다. 그리고 allTabs는 currentIndex를 인덱스값으로 가집니다.

위에서 말한 것처럼 매배변수를 하나 추가해주면 오류가 해결 된 모습을 볼 수 있습니다. 하지만 매개변수가 하나라도 에러가 안뜨게 할 수는 없을까요? 물론 방법은 있습니다.

useTab에 해당 if문을 추가해주겠습니다. 여기서 Array.isArray() 메서드는 해당 인자가 Array인지 알려주는 메서드입니다. 해당 조건이 일치하면 아무일없이 return 되고 끝나게 됩니다. 즉 배열이 아닐떄 그냥 return을 해버리는 것이고 따라서 useTab에 매개변수가 하나만 있더라도 오류가 발생하지 않게 되는 것이죠.

여기서 해당 함수를 이해하기 어려우신 분이 있으실텐데 다시한번 살펴보겠습니다.

content는 배열입니다.

해당 코드를 보면 useTab은 2개의 매개변수를 받고 App에서 보면 useTab으로 2개의 인덱스로 0과 content를 받고있습니다.
따라서 그러면 useState 메서드의 기본값으로 initalTab, 즉 0으로 세팅이 되서 useState(0)과 같은 코드입니다. 따라서 useState 앞의 currentIndex = 0이 되고 후에 setCurrentIndex는 content가 되는겁니다. 이해가 안되시면 다시 한번 천천히 읽어보시길 바랍니다.

따라서

해당 이미지의 currentItem은 content의 0번째 배열, 즉 첫번째 요소들은 리턴하고 currentItem.content는 첫번째 배열의 content 입니다.

이제 버튼 클릭시 해당 텍스트가 바뀌도록 해야합니다.


그러면 useState의 2번째 변수에 접근해야하므로 changeItem을 setCurrentIndex로 정의하여 값에 접근하여 바꿔줄수 있도록 하겠습니다.

그 후 버튼에 이런식으로 onclick 이벤트에 함수로 changeItem, 즉 section의 index를 해당 인덱스로 바꿔주는 이벤트를 넣어주면 클릭시 버튼이 정상적으로 작동하고 텍스트도 정상적으로 출력하게됩니다.
(여기서 index는 출력해보시면 알겠지만 첫번째 0부터 +1씩 증가하는 방식입니다. 정확하게 보시려면 콘솔에 찍어보시거나 버튼 뒤에 텍스트 붙혀보시는게 좋습니다.)

저도 해당 예제를 보면서 useState를 다시 보았는데 해당 hook은 useState가 정확하게 뭔지 안다면 크게 어렵지 않을 것 같습니다.
제일 중요한 것은 useState를 어떻게 사용하는지, setState(useState의 2번째 변수)는 새로 고침(re-render)해준다는 것 입니다. render function이 없다고 render가 안되는 것은 아닙니다.

위는 해당 예제의 전체 코드입니다. 이상입니다!!

profile
web development 주니어

0개의 댓글