textarea에 onChange로 이벤트 핸들러를 등록해서 창의 텍스트가 변경될 때마다 이벤트를 발생시키고 값을 가져오는 식으로 구현을 했었다.
하지만 onChnage는 너무 많은 이벤트를 연속적으로 발생시키고 리렌더링 횟수가 굉장히 많아질 수 있다는 생각이 들어서(실제론 리액트의 자체적인 최적화 로직 덕분에 그렇게 성능이 떨어지진 않는다고 함), Dobunce를 구현해 이벤트가 Delay time 이상 연속되지 않을 때에만 값을 가져오도록 했었다.
그런데, 디바운스도 좋은 해결책은 아니었다. 코드 상으로 디바운스 딜레이 타임 이후에 setState 함수가 실행이 됐는데, 만약에 딜레이 타임이 끝나기 전에 변경된 상태를 활용해야 하는 동작이 처리되는 요청이 들어온다면 당연하게도 setState가 실행되기 전 상태이기 때문에(setState 실행 코드는 이벤트 루프 태스크 큐에 들어가있을 것이다) 원하는 동작이 안 될 것이다.
해당 문제를 아래와 같은 접근으로 개선했다.
textarea에 onChange가 아닌 onBlur로 이벤트 핸들러를 등록했다. onBlur는 input 창에 아웃포커스 될 시 이벤트를 발생시킨다.
기획 상 textarea에서 마우스로 외부에 있는 버튼을 클릭해야만 input창에 있는 내용이 제출되는 형태였기 때문에, onBlur로 이벤트를 캐치하는 것으로도 충분했다. 만약에 enter 키로 제출 이벤트가 동작하도록 한다면 form 태그로 감싸 onSubmit 이벤트를 캐치하는 방법이 있을 것 같고, 아니면 onKeydown 이벤트로 key==='Enter'를 조건에 추가해주는 식으로도 구현이 가능할 것 같다.
textarea 창에 초기 설정된 값이 보여지도록 화면을 바로 그려주기 위해 vaule={value}로 값을 전달했었는데, 확인해보니 textarea의 값을 지속적으로 상태로 관리해야 하는 경우가 아니라면 defaultValue라는 속성을 사용할 수 있다. defaultValue는 말 그대로 초기에만 값이 전달되고, 그 이후부턴 리액트가 해당 값의 관리에 관여하지 않게 된다.
반면, value로 초기값을 주면 리액트가 지속적으로 해당 창의 상태 변화를 관리해야 하기 때문에, 타이핑하는 모든 요소에 대해 onChange로 이벤트를 다뤄야 한다는 문제가 있다(그러면, 많은 리렌더링과 함께 성능 문제로 이어질 수 있다고 생각했다). 그래서, '수정'을 위한 페이지에서만 선택적으로 초기 값을 넣어줘야 하는 내 경우에선 value보단 defaultValue를 사용하는 게 조금 더 좋지 않을까 생각했다.
input type='date'로 만든 Date picker에 min 또는 max값을 설정하면 날짜를 선택할 수 있는 기간을 특정할 수 있다. 예를 들어 min='2024-11-25'라고 지정하면 날짜 선택은 24년 11월 25일부터 가능하며, 11월 24일 이전 날짜는 선택이 불가능하다. 반대로, max='2024-11-25'로 설정하면 24년 11월 25일 이후 날짜는 선택이 불가능하다. 해당 속성을 통해 원하는 구간으로 날짜 선택을 유도할 수 있다.
input type='date'로 설정한 Date picker는 속성(value, min, max 등)에 날짜 타입을 yyyy-mm-dd로 전달해야만 한다. yyyy-m-dd 형식이어도 안된다. 따라서, Date picker를 잘 활용해야 하는 경우엔 날짜 포맷을 원하는 형식으로 변환해주는 유틸 함수를 만들어두고 사용하는 게 유리할 수 있다.
HTML 태그 요소의 디테일한 활용 부분에서 헤매게 되는 경우가 종종 생기는 것 같다. 거기에 리액트에서는 좀 더 특수하게 속성 사용이 유도되는 경우가 많은 것 같아 더 헷갈린다. 많은 내용을 한 번에 다 공부하기 어렵기 때문에, 모르는 내용이 나오면 그때그때 잘 정리해둬야겠다.