컴공과컴맹효묘의블로그

React에서의 window event listener 주의점. 본문

개발

React에서의 window event listener 주의점.

효묘 2022. 9. 18. 17:55
반응형

React에서 window event listener 사용할 때 주의점

react에서 window event listener를 사용해야할 일이 생겼다. 그런데, window event listener의 call back함수가 component의 state를 잘 반영하지 못 한다는 사실을 깨달았다.

call back함수는 state의 init값만을 반영한다. component가 업데이트 되어도 update된 state값을 반영하지 않고 init state value만 반영한다.

function App() {
  const [myState, setMyState] = useState(0);

  const listener = () => {
    console.log(`state in handler: ${myState}`);
    // state in handler: 0
  };

  useEffect(() => {
    window.addEventListener("dblclick", listener);
  }, []);

  return (
    <div className="App">
      <h1>State: {myState}</h1>
      <button onClick={() => setMyState(myState + 1)}>update state</button>
    </div>
  );
}
//https://medium.com/geographit/accessing-react-state-in-event-listeners-with-usestate-and-useref-hooks-8cceee73c559

urlStackOverflow에 따르면 listener는 초기 렌더링에만 속하며, 이후 렌더링에 대해서는 업데이트 되지 않는다.

해결 방안

이 문제를 해결하는 방안으로 첫 번째로는 최신state를 항상 포함하는 this.state.myState를 사용하기 위해서 class Component로 구현할 수 있다.

그런데 hook을 사용하고싶다면, useRef를 사용하면 된다.

다음과 같은 방법으로 useRefuseState를 둘 다 업데이트하면서 listener에게도 update된 값을 이용할 수 있게 한다.

import React from "react";
import ReactDOM from "react-dom";

import "./styles.css";

function App() {
  const [myState, _setMyState] = React.useState(0);

  const myStateRef = React.useRef(myState);
  const setMyState = data => {
    myStateRef.current = data;
    _setMyState(data);
  };

  const listener = () => {
    console.log(`state in handler: ${myStateRef.current}`);
    // state in handler: 1
    // state in handler: 2
    // etc...
  };

  React.useEffect(() => {
    window.addEventListener("dblclick", listener);
  }, []);

  return (
    <div className="App">
      <h1>State: {myState}</h1>
      <button onClick={() => setMyState(myState + 1)}>update state</button>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
//https://medium.com/geographit/accessing-react-state-in-event-listeners-with-usestate-and-useref-hooks-8cceee73c559

 

 

참고:

https://stackoverflow.com/questions/55265255/react-usestate-hook-event-handler-using-initial-state

https://medium.com/geographit/accessing-react-state-in-event-listeners-with-usestate-and-useref-hooks-8cceee73c559

반응형

'개발' 카테고리의 다른 글

[Typescript]react-router-dom-v6사용 useParams useLocation  (0) 2022.06.22
Tailwind 설정하기  (0) 2022.06.19
Comments