리액트 16 이전 버전에서 발생합니다.

문제 상황

event.currentTarget.value가 undefined로 나오는 현상 발생.

const [state, setState] = useState("Init") ;

return (

<input
  type="text"
  value={state}
  onChange{(event) => {

    setState(prevState => {

      return event.currentTarget.value // undefined

    });

  }}

/>

);

이유

SyntheticEvent의 Pooling과 setState에 전달된 콜백 실행 시점의 차이 때문에 발생하는 문제였습니다.

React의 SyntheticEvent는 이벤트 핸들러가 종료된 직후에 pool로 반환되어, event가 모두 null로 초기화됩니다. 그런데 setState의 함수형 업데이트(콜백)나 비동기 코드(setTimeout, Promise등)는 이벤트 핸들러 실행 이후에 동작합니다. 따라서 setState 콜백에서 event를 참조하면, 이미 event 객체가 pool로 반환되어 null이 됩니다.

해결방법

const [state, setState] = useState("Init") ;

return (

<input
  type="text"
  value={state}
  onChange{(event) => {

    const newState = event.currentTarget.value // 미리 값을 추출

    setState(prevState => {

      return newState;

    });

  }}

/>

);

값을 미리 추출하여 변수 저장하고 클로저를 이용하면 됩니다.

추가적으로 event를 사용해야 할 경우 event.persist()를 사용하여 이벤트 pooling을 막을 수 있습니다.

하지만, event를 사용해야 하는 경우가 아니라면 권장하지 않습니다.

Event Pooling

Leave a Reply

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다