> For the complete documentation index, see [llms.txt](https://shhn0509.gitbook.io/react/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://shhn0509.gitbook.io/react/react-study/mini-project/part-1/and.md).

# 이벤트 핸들링 & 타임 컨트롤

## 1. 이벤트 핸들링

### 1.1 상태가 필요한 요소&#x20;

상태가 필요한 요소는 클래스 이름을 추가 제거하는 기능이 필요하다. 이를 상태를 통해서 제어해보자.&#x20;

#### &#x20;1.1.1 하고자하는 것&#x20;

* &#x20;네비게이션 버튼을 클릭 했을 때, `hidden` 속성과, `.is-active` 클래스 이름이 추가/제거 되었으면 좋겠다.&#x20;

#### 1.1.2 구성&#x20;

* hidden 속성을 boolesn 값을 설정하는 상태, class 이름을 설정하는 상태 설정&#x20;
* 열림/ 닫힘 버튼을 클릭시 상태가 업데이트 되도록 업데이트 함수 설정&#x20;
* 해당 버튼에 업데이트 함수 바인딩 (이벤트 바인딩)&#x20;

```javascript
import './AppNavigation.scss'
import React from 'react'

class AppNavigation extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      // hidden 속성을 제어하는 상태 
      isOpen: false,
      // is-active를 추가 제거할 수 있도록 className 상태 설정 
      navClassName: 'appNavigation',
    }
  }

  handleOpenNav = () => {
    this.setState({
        isOpen: true,
        navClassName: 'appNavigation is-active'
    })
  }
  handleCloseNav = () => {
    this.setState({
        isOpen: false,
        navClassName: 'appNavigation',
    })
  }

  render() {
    return (
      <>
        <button
          onClick={this.handleOpenNav}
          className="resetButton is-open-menu"
          type="button"
          title="메뉴 열기"
          aria-label="메뉴 열기"
        >
          <span className="ir"></span>
        </button>
        <nav className={this.state.navClassName} hidden={!this.state.isOpen}>
          <h2 className="a11yHidden">메인 메뉴</h2>
          <ul className="resetList">
            { ** }
          </ul>
          <button
            onClick={this.handleCloseNav}
            className="resetButton is-close-menu"
            type="button"
            title="메뉴 닫기"
            aria-label="메뉴 닫기"
          >
            <span className="close" aria-hidden="true">
              ×
            </span>
          </button>
        </nav>
      </>
    )
  }
}

export default AppNavigation

```

## 2. 타임 컨트롤&#x20;

#### 2.1 문제&#x20;

* 네비게이션이 열고 닫힐 때 hidden 속성이 className과 같이 추가/제거 되어서 설정된 애니메이션이 적용 안된다. &#x20;

#### 2.2 해결&#x20;

* 각 속성에 시간차를 주어 애니메이션이 실행 된 다음 hidden 속성이 적용되도록 한다.&#x20;

```javascript
handleOpenNav = () => {
  this.setState(
    {
      isOpen: true,
    },
    () => {
      window.setTimeout(() => {
        this.setState({ navClassName: 'appNavigation is-active' })
      }, 400)
    }
  )
}
handleCloseNav = () => {
  this.setState(
    {
      navClassName: 'appNavigation',
    },
    () => {
      window.setTimeout(() => {
        this.setState({ isOpen: false })
      }, 400)
    }
  )
}
```

## 3. \<nav>요소에 hidden 속성? &#x20;

{% embed url="<https://shhn0509.gitbook.io/html/stylesheet/accessibility/less-than-nav-greater-than-hidden>" %}
