Dev/reactJS

javascript classList.toggle로 jquery addClass, removeClass, toggleClass 구현하기 / 더보기 버튼 클릭시 영역 확장

허연동백hipublic2020 2022. 11. 3. 13:01
반응형

아래처럼 더 보기 버튼을 누르면 위 영역이 확장되면서 내용을 더 보여주는 컴포넌트를 구현하려고 한다.

사실 jquery라면 일도 아니지만, javascript 특히 react에서는 귀찮다.

여러분이 느끼셨을 것 같지만, JavaScript, 특히 React를 사용하면서 DOM을 선택하는 작업이 매우 번거로울 때가 많습니다. 

그리고 이것은 jQuery를 사용하시던 분들에게는 특히 더 그렇게 느껴질 수 있습니다. jQuery의 힘을 알고 있는 우리에게 이는 상당히 실망스러운 측면 중 하나일 것입니다. 

그러나, 이렇게 불편함을 겪고 있는 것은 저희들만은 아닙니다. 사실, 이 문제를 해결하기 위한 방법은 많습니다. 여러 가지 가능한 방법들이 있지만, 주요한 두 가지 해결책은 ref 사용과 useState 사용입니다. 

ref를 사용하는 방법은 일반적으로 더 직관적이며, 직접적인 방법입니다. ref는 React에서 DOM 요소를 직접 다루기 위해 사용하는 기능입니다. 이를 통해 우리는 DOM 요소에 직접 접근하고 그것을 조작하는 데 필요한 정보를 얻을 수 있습니다. 

이 방법은 jQuery에 익숙한 개발자들에게 특히 편리할 것입니다. useState를 사용하는 것은 좀 더 복잡한 해결책이지만, 이는 상태 관리의 측면에서 더 큰 유연성을 제공합니다. useState는 React의 Hooks 중 하나로, 함수형 컴포넌트에서 상태를 관리할 수 있게 합니다. 이 방법은 DOM의 상태를 관리하는 데에 매우 효과적입니다. 

그럼에도 불구하고, 이러한 방법들이 모두 완벽한 해결책은 아닙니다.

 왜냐하면 코드가 길어질수록, 이러한 작업들은 더욱 번거로워지고 복잡해질 수 있기 때문입니다.

 jQuery의 강력함은 DOM을 쉽게 선택하게 해주는 데 있습니다. 

이는 JavaScript와 React에서 복잡하게 느껴지는 부분이기도 합니다. 

그래서 이 문제를 해결하는 방법이 필요합니다. JavaScript에서 DOM 선택을 더 스마트하게, 그리고 더 간결하게 만드는 방법이 필요합니다. 

요약하면, JavaScript와 React를 사용하는 동안 DOM 선택과 조작에 대한 효율성과 단순성이 크게 필요합니다. 

이는 jQuery의 힘이 바로 이 점에서 나타나며, 이에 대한 해결책이 절실하게 필요합니다. DOM을 더 쉽게 다루는 방법을 찾아 개발 과정을 더 효율적이고 즐겁게 만드는 것이 우리의 목표가 되어야 합니다.

그걸 좀 더 스마트하게 줄여주면 된다.

 // list Extender
  const ExtendClass = (e) => {
    e.target.parentElement.classList.toggle("extend");
  };

  // render 처리
  return (
    <div className="person-detail-form-body">
      <h5>도서</h5>
      <div className="extender-wrap">
        <ul className="history-list medium-list">
          <li>글글글</li>
          <li>글글글</li>
          <li>글글글</li>
          <li>글글글</li>
          <li>글글글</li>
          <li>글글글</li>
        </ul>
        <button
          className="btn-extender"
          onClick={(e) => {
            ExtendClass(e);
          }}
        ></button>
      </div>
    </div>
  );

extender-wrap 클래스는 sCSS로 다음과 같이 max-height를 제어해 준다.

.extender-wrap {
  margin-bottom: 20px;
  &:not(.extend) {
    & > ul {
      max-height: 100px;
      overflow: hidden;
    }
  }
  & > ul {
    margin-bottom: 5px;
  }
}

와 같다.

버튼은 부모 요소의 자식으로 들어가 있고, 버튼의 이벤트에서 부모요소는 parentElement로 찾는다.

부모요소의 classList는 toggle()을 사용해서 특정 클래스를 추가하고 제거할 수 있다.

className을 사용하면, 클래스를 할당하거나 제거할 수는 있지만 toggle을 이용할 수 없어서 classList를 사용하는 것이 편하다.

참고로 버튼의 애로우는 css transeform의 rotate를 이용해서 뒤집어 준다.

.btn-extender {
  width: 100%;
  display: flex;
  border: 0 none;
  justify-content: center;
  align-items: center;
  &::after {
    font-family: sans-serif;
    font-size: 1.05rem;
    content: "〉";
    transform: rotate(90deg);
  }
  .extend &::after {
    transform: rotate(-90deg);
  }
}

HTML 문서 내에서, 우리는 종종 요소들 사이의 계층 관계를 다루게 됩니다. 그중에는 버튼 요소와 그 버튼의 부모 요소 간의 관계를 처리하는 상황도 흔히 있습니다. 이러한 상황에서, JavaScript를 사용하여 동적인 행동을 구현하려면 이 요소들 간의 상호작용을 이해하는 것이 중요합니다. 가령, 버튼 요소가 부모 요소의 자식 요소로 존재하는 구조를 생각해 봅시다. 이럴 때 버튼 요소에서 발생하는 이벤트를 통해 부모 요소에 접근할 필요가 있다고 가정해 봅시다. JavaScript에서는 이를 위해 `parentElement`라는 속성을 제공합니다. `parentElement` 속성은 요소의 부모 요소를 반환하므로, 버튼의 이벤트 내에서 `parentElement`를 사용하면 부모 요소를 손쉽게 찾을 수 있습니다. 그렇다면 찾은 부모 요소에 대해 어떤 동작을 수행하려 할까요? 여기서는 클래스를 추가하거나 제거하는 동작을 예로 들어보겠습니다. 이런 동작은 요소의 `classList` 객체와 그 안의 `toggle()` 메서드를 사용하여 수행할 수 있습니다. `toggle()` 메서드는 지정한 클래스가 요소에 있는 경우 그 클래스를 제거하고, 없는 경우 추가합니다. 즉, 한 번의 호출로 클래스의 존재 여부를 '토글'할 수 있는 것입니다. 그렇다면 왜 `classList`와 `toggle()`을 사용하는 것일까요? 그 이유는 `className` 속성을 사용하는 것보다 더 편리하기 때문입니다. `className` 속성을 사용하면 클래스를 할당하거나 제거할 수는 있지만, `toggle()`과 같은 동작을 수행하려면 추가적인 코드가 필요합니다. 반면 `classList`는 다양한 메서드를 제공하여 클래스 조작을 훨씬 간결하게 할 수 있습니다. 이렇게 보면, 버튼 요소와 부모 요소 사이의 상호작용은 DOM 조작의 핵심적인 부분입니다. `parentElement`, `classList`, `toggle()`과 같은 기능을 이해하고 활용하는 것은 웹 개발자로서의 역량을 키우는데 중요합니다. 이들은 DOM 요소의 속성과 클래스를 다루는 데 있어 강력한 도구이며, 이를 통해 동적인 웹 페이지를 만드는 데 필요한 세부 조작을 가능하게 합니다. 따라서, 이러한 기능들을 잘 이해하고 활용하는 것이 웹 개 발의 효율성과 품질을 높이는데 크게 기여할 것입니다.

반응형