[Project] event-handler 하나로 합치기 !

Simple Key·2020년 5월 14일
0
post-custom-banner

1. 하나의 Event-Handler를 사용하기

<ul>태그 내에 <li>로 이루어진 4개의 리스트를 만들고 각 리스트를 클릭하면 그 <li>의 배경색이 변경되고 보여지는 컨텐츠도 바꾸려면 어떻게 해야할까 ?


// -------- 생략 -------- //
clickHome = (e) => {
	setState({
    	Home : true
    })
}

clickMenu1 = (e) => {
	setState({
    	Menu1 : true
    })
}
// -------- 생략 -------- //

예전에는 이런식으로 똑같은 형태의 이벤트 핸들러를 각각의 요소에마다 따로 만들어 주었다. 또 state값 역시 다 따로 만들어줘야 해서 불필요하게 코드가 길어지게 되었다. 이러한 상황을 개선하기 위해서 map()메서드를 활용하면 된다.


먼저 map()을 사용하면 <li>도 일일이 다 코드를 만들어 줄 필요도 없게된다.

import React, {Component} from "react";

const tabs = ['회사소개', '시작하기', '상품보기', '고객센터'];

class Draft extends Component {
  render(){
    return(
      <div className='wrapper'>
        <ul></ul> // ⬅︎ 이 사이에 <li>대신 map메서드로 <li>를 리턴해준다.🙂
      </div>
    )
  }
}

⬆︎ <ul>태그를 만들어서 <li>가 들어가야 할 곳을 만들어준다. <li>태그를 직접 써주는 대신 map()으로 <li>를 return하게 만든다.

import React, {Component} from "react";

const tabs = ['회사소개', '시작하기', '상품보기', '고객센터'];

class Draft extends Component {
  render(){
    return(
      <div className='wrapper'>
        <ul>
          {tabs.map((tab)=>{ // tabs배열의 각 요소(tab)를 한번씩 인덱스 순서대로 가져온다.
              return(
                <li>{tab}</li> // tabs배열의 각 요소(tab)를 한번씩 리턴
              )
          	})
          }
        </ul>
      </div>
    )
  }
}

⬆︎ map()으로 tabs에 들어있는 '회사소개','시작하기','상품보기','고객센터'가 <li></li>에 담겨서 반환되어 보여지게 된다. 이제 각 리스트를 클릭하면 해당 리스트에 맞는 컨텐트가 보여지게 만들어야한다.

import React, {Component} from "react";

const tabs = ['회사소개', '시작하기', '상품보기', '고객센터'];

const tabsComponents = {
    // tabs의 각 리스트를 클릭했을때 보여줄 컨텐츠들을 따로 컴포넌트로 만들어 준 뒤,
    // 객체에 담는데, 객체의 key는 tabs의 인덱스, key value는 tabs의 각 요소로 설정
    0: <Intro />,
    1: <Start />,
    2: <Products />,
    3: <CustomerCt />
}

class Draft extends Component {
  
  state = {
  	activeTabId : 0 // state에 li태그에 넣을 className을 state로 저장해준다.
  };
  
  clickHandler = (id) => {
    this.setState({
      activeTabId : id // 클릭을 하면 setState가 돌면서 activeTabId 값이 변경되는 이벤트핸들러
    })
  }

  render(){
    return(
      <div className="wrapper">
        <ul>
          {tabs.map((tab , index)=>{
              return(
                <li 
                  className={activeTabId === 0 ? "selected":""}
                  key={index}
                  onClick={()=>{this.clickHandler(index)}}>
                  //map으로 각각 받은 index를 onClick이벤트가 발생하면 clickHandler 인자값으로 넘긴다.
                  {tab}
                </li> 
              )
          	})
          }
        </ul>
        <div>{tabsComponents[activeTabId]}</div>
        //onClick이 발생하면 state(acitveTabId)값에 onClick이 발생한 리스트의 인덱스 값이 저장되고,
        //tabsComponents[요기에 그 값이] 들어가면서 해당 컴포넌트를 나타내가 된다!!
      </div>
    )
  }
}

2. 하나의 이벤트 핸들러를 프로젝트에 적용하기

이러한 코딩을 참고하여 나의 프로젝트에 적용하기로 했다.

⬆︎이번 프로젝트에서는 function형 컴포넌트로 hooks를 사용하기로 했기때문에 useState로 state값을 저장했다.

⬆︎GQ, JungAng, Esquire 스타일 컴포넌트에 각각 onClick 이벤트를 설정해주고 하나의 이벤트핸들러(나는 clickHandler 라고 지어줌) 를 실행시켜준다. 대신 각각의 id값 처럼 번호를 이벤트핸들러의 인자로 넘겨준다. 이벤트핸들러에서는 받은 인자값을 state값에 저장하게 된다.
또 state라는 props를 주고 그 안에도 전달해준다.

⬆︎state값으로 저장된 번호를 articles객체의 key값으로도 저장되어있기 때문에 이렇게 객체에서 해당 번호의 컴포넌트를 불러와 랜더하게 된다. 👍

⬆︎전달받은 props값을 삼항연산자를 사용해서 스타일을 그때그때 다르게 적용 가능하다. 예를들어 <GQ />를 클릭하면 이벤트핸들러에서 hooks로 0이란 값이 저장되고 그 값을 다시 <GQ state={clicked} />의 props인 state에도 불러오게 된다. 그러면 삼항연산자에서 true가 될 것이고 만약 <GQ/>에서 <JungAng/>이나 <Esquire/>를 클릭하면 state값이 바뀌면서 삼항연산자에서는 false가 될 것이다. 클릭이 되어서 true가 되거나 false가 되면서 다른 스타일링이 적용되는 것!

profile
프론트엔드 개발자 심기현 입니다.
post-custom-banner

0개의 댓글