0. 글을 작성하는 이유
- 채팅 입력창을 구현하다
requestSubmit
을 알게되어서 정리 - react는
stopImmediatePropagation
이 없다?
**TL;DR**
- Form.requestSubmit으로 submit handler를 호출
- React에서
stopImmediatePropagation
를 쓰고 싶다면e.nativeEvent.stopImmediatePropagation()
- React 이벤트 시스템은 EventPlugin, EventPluginHub으로 구성
- Native Event처럼 동작되는것 같지만, 아니다
- 이벤트에 대한 콜백들의 결과(배열)로 받아와 실행
1. 문제의 상황
-
채팅 입력창을 구현 중
Enter
를 누르면 handleSubmit tigger 구현중.. -
문제 : 당연히
Enter
키를 누르면… handleSubmit 함수를 tirgger 할줄 알았지만, 새로고침..-
form태그의 submit 함수가 내가 알고 있던 기능대로 동작하지 않는다
const formRef = useRef<HTMLFormElement>(null) const handleSubmit = (e: FormEvent<HTMLFormElement>) => { e.preventDefault() console.log('submit') } const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => { if (e.code === 'Enter') { formRef.current!.submit() } } return ( <form ref={formRef} onSubmit={handleSubmit}> <input onKeyDown={handleKeyDown} /> </form> )
-
2. HTMLFormElement.requestSubmit()
MDN에서 친절하게 설명해주고 있었다…
1. HTMLFormElement.submit()
-
sumit 메소드는 submit 이벤트를 발생하지 않는다(즉 onSubmit함수를 trigger 하지 않음)
-
Constraint validation가 작동하지 않는다. (type=”URL | email”, pattern, min)
<input type="email" onKeyDown={handleKeyDown} /> // email 형식을 체크하는 validation이 작동하지 않는다.
2. HTMLFormElement.requestSubmit()
-
submit이벤트를 발생한다!
const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => { if (e.code === 'Enter') { formRef.current!.requestSubmit() } }
3. React는 NativeEvent가 아니라 SyntheticEvent ??
1.리엑트의 SyntheticEvent란?
-
리엑트는 모든 브라우저에서 동일한 이벤트를 구현하기 위해 **SyntheticEvent 객체를 이용해서 NativeEvent를 감싸는 방식으로 한다.**
-
nativeEvent를 사용하고 싶다면?
e.nativeEvent.stopImmediatePropagation()
interface BaseSyntheticEvent<E = object, C = any, T = any> { nativeEvent: E currentTarget: C target: T bubbles: boolean cancelable: boolean defaultPrevented: boolean eventPhase: number isTrusted: boolean preventDefault(): void isDefaultPrevented(): boolean stopPropagation(): void isPropagationStopped(): boolean persist(): void timeStamp: number type: string }
2. 리엑트의 이벤트 전파 방
- 리엑트 17부터 RootElement에서 모든 이벤트를 감지한다(18은 root별로 지원..?)
4. 리엑트의 이벤트 시스템은 EventPlugin, EventPluginHub
1. EventPlugin
-
컴포넌트에 등록된 이벤트와 이벤트 콜백
<button onClick={handleClick}/> //types onClick?: MouseEventHandler<T> | undefined; type MouseEventHandler<T = Element> = EventHandler<MouseEvent<T>>; type EventHandler<E extends SyntheticEvent<any>> = { bivarianceHack(event: E): void }["bivarianceHack"];
2. EventPluginHub
-
앱/웹이 실행될때, 컴포넌트에 등록된 EventPlugine들이 주입되며 이벤트 대기열을 관리(수집, 저장, 삭제)
-
이벤트가 수신되면, 노드를 순회하면서 (버블링, 캡처링)
-
각 플러그인에 대해 SyntheticEvent를 수집하여 대기열에 저장하고 실행후 삭제한다.
3. stopPropagation
- 이벤트의 전파를 막는게 아니다. SyntheticEvent Array를 비워주는것 뿐이다.