React에서 하단으로 스크롤

16367 단어 Reactreact-hooks
약간의 일입니다만, 이하와 같은 스크롤로 조금 막혔으므로 각서 정도에. .


하고 싶은 일



컴포넌트 내에서 버튼을 누릅니다.

아코디언 열기

지정된 위치로 스크롤

스크롤 없으면 아래로 조금 나올 뿐이므로 너무 잘 없을까~라고 생각해 보았습니다.

아코디언 열 때까지



App.js

const App = () => {
  const [isOpen, setIsOpen] = useState(false);

  const changeIsOpen = () => {
    setIsOpen(!isOpen);
  };

  return (
    <div className="App">
      <div className="wrapper">
        <button onClick={changeIsOpen}>Click Me!</button>
        <ul id="target" className={isOpen ? "ul open" : "ul close"}>
          <li>list1</li>
          <li>list2</li>
        </ul>
      </div>
    </div>
  );
};

export default App;


(styled-component 사용하고 있었지만 우선 참고로…)

style.css
.ul {
  margin: auto;
  list-style: none;
  max-height: 0;
  overflow: hidden;
}

.open {
  max-height: 500px;
  transition: max-height 0.5s;
}

.close {
  max-height: 0;
  transition: max-height 0.5s;
}


시도한 것 1



const App = () => {
  const [isOpen, setIsOpen] = useState(false);

  const changeIsOpen = () => {
    setIsOpen(!isOpen);
    const target = document.getElementById("target");
    target.scrollIntoView({ behavior: "smooth", block: "end" });
  };

  return (
    <div className="App">
      <div className="wrapper">
        <button onClick={changeIsOpen}>Click Me!</button>
        <ul id="target" className={isOpen ? "ul open" : "ul close"}>
          <li>list1</li>
          <li>list2</li>
        </ul>
      </div>
    </div>
  );
};

export default App;


onClick 때 함께 처리하려고 했지만 isOpen이 바뀌기 전에 처리가 달려 버리기 때문에 잘 안 됐다.

시도한 것 2



그런가… 라고 생각하면서 useEffect를 사용했지만 아직 제대로 움직이지 않는다…

const App = () => {
  const [isOpen, setIsOpen] = useState(false);

  const ScrollBottom = target => {
    if (target) {
      target.scrollIntoView({ behavior: "smooth", block: "end" });
    }
  };

  const changeIsOpen = () => {
    setIsOpen(!isOpen);
  };

  useEffect(() => {
     const target = document.getElementById("target");
     if (target) {
         ScrollBottom(target)
     }
   }, [isOpen]);

  return (
    <div className="App">
      <div className="wrapper">
        <button onClick={changeIsOpen}>Click Me!</button>
        <ul id="target" className={isOpen ? "ul open" : "ul close"}>
          <li>list1</li>
          <li>list2</li>
        </ul>
      </div>
    </div>
  );
};

export default App;


원인은 CSS의 transition이었습니다.
transition에서 0.5s 지정하고 있기 때문에, 아코디언이 열기 전에 js 움직이고 있었던 것 같습니다.

해결



아코디언의 요소에 addEventListener 에서 transitionend 를 가지고 스크롤을 이동했습니다. 그리고 이벤트가 남아 가기 때문에 return에서 removeEventListener

  useEffect(() => {
    const target = document.getElementById("target");
    if (target) {
      target.addEventListener("transitionend", () => {
        ScrollBottom(target);
      });
      return () => {
        target.removeEventListener("transitionend", () => {
          ScrollBottom(target);
        });
      };
    }
  }, [isOpen]);


샘플
h tps : // 코데 씨 d 보 x. 이오 / s / t 란시 치온 - l0 오 2z?ぃぇ=/src/아 p. js

좋은 웹페이지 즐겨찾기