HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
👋🏻
안녕하세요, 개발을 사랑하는 찬민입니다!
/
📝
해외 블로그 번역
/
✈️
useState, useRef와 함께 이벤트 리스너에서 상태에 접근하는 방법
useState, useRef와 함께 이벤트 리스너에서 상태에 접근하는 방법
✈️

useState, useRef와 함께 이벤트 리스너에서 상태에 접근하는 방법

생성일
Jul 16, 2021 08:12 AM
태그
React
원문 링크
https://medium.com/geographit/accessing-react-state-in-event-listeners-with-usestate-and-useref-hooks-8cceee73c559
표지용 스플래시 이미지입니다.
표지용 스플래시 이미지입니다.

목차

역주 : 시작하기 전에useState, useRef와 함께 이벤트 리스너에서 상태에 접근하는 방법

역주 : 시작하기 전에

💡
짧지만 유익했던 글이었습니다! 저도 이런 경험이 있었던 것 같은데, 읽어보시면 도움이 될 수 있을 것 같네요!

useState, useRef와 함께 이벤트 리스너에서 상태에 접근하는 방법

원제 : Accessing React State in Event Listeners with useState and useRef hooks

컴포넌트에서 이벤트 리스너와 함께 리액트 훅을 사용하고 있다면, 해당 이벤트 리스너의 콜백 함수는 최신 상태값을 읽어들일 수 없다는 문제가 있습니다. 이 문제는 useRef 훅을 코드에 포함해 해결할 수 있습니다.
아래의 간단한 예시 코드에서는, 더블 클릭 이벤트가 발생할 때 상태값을 읽으려 시도합니다.

[샌드박스 링크]
import React from "react"; import ReactDOM from "react-dom"; import "./styles.css"; function App() { const [myState, setMyState] = React.useState(0); const listener = () => { console.log(`state in handler: ${myState}`); // state in handler: 0 }; 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);

코드를 실행해보면 이벤트 리스너가 초기 상태값만 읽어들이는 것을 알 수 있는데요, 따라서 스택 오버플로우 글에서 설명된 것처럼 (역주 : 더블 클릭을 할때) 언제나 state in handler : 0 이라는 로그를 확인할 수 있습니다.
이는 이벤트 리스너가 초기 렌더링 상태에 귀속되고 이어지는 리렌더링으로 업데이트되지 않기 때문입니다.

그럼 이 문제는 어떻게 해결할 수 있을까요? this.state.myState 처럼 클래스 컴포넌트를 활용하면 항상 최신 상태값을 사용하도록 할 수 있기는 합니다.
그러나 훅을 사용해 이를 해결하고 싶다면, useRef 훅을 사용하는 방법이 있습니다. 다음 코드는 useRef 훅을 통해 이벤트 리스너가 참조하는 상태값을 업데이트하는 예시입니다.

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);

이 코드에서는 myStateRef 라는 useRef 훅을 useState 로 만든 myState 값으로 초기화하고 있습니다. 그리고 myState 와 myStateRef.current 의 값을 동시에 업데이트하는 함수를 추가했습니다.
이제 이벤트 리스너에서는 myStateRef.current 값을 사용함으로써 최신 값을 읽어들일 수 있습니다.

이 글이 유용했기를 바라겠습니다. 스택오버플로우 포스트 의 자세한 설명에 감사를 표함과 동시에, useRef 에 대한 공식 문서를 참조해보실 수 있겠습니다.