ํ์ฌ React์ SyntheticEvent
๋ํ Typescript 2.0 ์๋ช
์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
interface SyntheticEvent<T> {
currentTarget: EventTarget & T;
target: EventTarget;
}
์ปค๋ฐ a13fa7abf55daedf25b31258b908548f55962c7a ์ ๋ฐ๋ฅด๋ฉด target
๋ ์๋ EventTarget & T
์์ง๋ง์ด ๋ณ๊ฒฝ ์ฌํญ์ ์ปค๋ฐ 5607f54caffce.fce83bc528f4์์ ๋ณํฉํ๋ ๋์ ์ค์๋ก ๋๋๋ ค์ก์ต๋๋ค.
ํ์ฌ ์๊ทธ๋์ฒ๋ 2.0 ์ด์ ์ฝ๋(์์ํ ์ ์๋ฏ์ด React ์ฝ๋๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ก ๊ฐ๋ ์ฐจ ์์)๋ฅผ ๊ฑฐ์ ๋๋ ์ ํ ๋์์ด ๋์ง ์์ต๋๋ค(๋๋ถ๋ถ์ ์ฝ๋๊ฐ event.target
์ ์์กดํ๋ฏ๋ก ์ด๋ ์ฌ์ ํ pre์ ์์กดํ๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค). event.target
๊ฐ ์ ๋ค๋ฆญ์ด ์๋๊ธฐ ๋๋ฌธ์ (event.target as any).value
์ ๊ฐ์ -2.0 ์ฝ๋.
๊ธฐ๊บผ์ด ํจ์น๋ฅผ ์ ๊ณตํ ์ ์์ง๋ง SyntheticEvent.target
์ด ์๋์ ์ผ๋ก de-generateํ๋์ง ์์๋์ง ํ์ธํ๊ณ ์ถ์ต๋๋ค.
์ด๊ฒ์ ์๋ง๋ ๋ณํฉ ์ค์ ๋ฐ์ํ ์ค์์ผ ๊ฒ์ ๋๋ค. ํ๋ณด ๋ถํ๋๋ฆฝ๋๋ค.
#11041, #10784 ๋ฑ์ ์ฐธ์กฐํ์ญ์์ค. ๋ณํฉ ํ์๋ ์์ ๋์ง ์๋ ์ด์ ๋ ๋ฏธ์คํฐ๋ฆฌ์ ๋๋ค.
์ปดํ์ผ ํ์์ ๋์์ ์ ํ์ ํญ์ ์๋ฆด ์๋ ์์ต๋๋ค. ๊ทธ๊ฒ์ ์ผ๋ฐํํ๋ ๊ฒ์ ๊ฑฐ์ ๊ฐ์น๊ฐ ์์ต๋๋ค.
target์ ์ด๋ฒคํธ์ ์์์ ์
๋๋ค.
currentTarget์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ์ฐ๊ฒฐ๋ ์์๋ก, ๋ฐ์ดํฐ ์ธํธ ๋๋ ๊ธฐํ ์์ฑ์ ์ฒจ๋ถํ๊ณ ๋ฐํ์์ ์ก์ธ์คํ๋ ค๋ ๊ฒฝ์ฐ ๋งค์ฐ ์ฃผ์ํ๊ณ ์ ์ ํ๊ฒ ์
๋ ฅํด์ผ ํฉ๋๋ค.
currentTarget ๋์ target์ ์์กดํ๋ ๊ฒ์ ์ด์ฌ์์ ์ค์๋ก ํ์๋ณด๋ค ๋นจ๋ฆฌ ๋ฌผ๋ฆด ๊ฒ์ ๋๋ค.
์๋ฅผ ๋ค์ด:
handleTabClick = (e: React.SyntheticEvent<HTMLLinkElement>) => {
e.preventDefault()
// !!! e.target.dataset is empty if user clicked the <span>, not the <a> !!!
// !!! how can you type e.target? User might also have clicked the <a> if it has padding !!!
// you have to use currentTarget, and it is the element that you know the type for sure
if (e.currentTarget.dataset['closable'] === 'true') {
this.close()
}
}
render() {
return <a onClick={this.handleTabClick} data-closable="true">
<span className="fatty">Click me!</span>
</a>
}
์ด ์ฝ๋๋ ์ปดํ์ผํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
'์์ '์ด ๋ณํฉ๋๋ฉด e.currentTarget
์
๋ ฅํ ์ ์์ผ๋ฉฐ(์ ํ ์ค๋ฅ ์์ด ๋ฐ์ดํฐ ์ธํธ์ ์ก์ธ์คํ ์ ์์) e.target
๊ฐ ์ด์ HTMLLinkElement๋ก ์
๋ ฅ๋์ง๋ง ์ค์ ๋ก๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค. ์ฐ๋ฆฌ๋ ๊ทธ๊ฒ์ ๋ํด ํ์ ํ ์ ์์ต๋๋ค. (์์ ์คํฌ์ ํด๋ฆญํ์ ์ ์์ต๋๋ค.
์ด๋ก ์ ์ผ๋ก ์ฌ์ฉ์๊ฐ ํ์คํ ๋(์ด๋ฒคํธ ํธ๋ค๋ฌ์ ์์์ด ์๊ฑฐ๋ ๋ชจ๋ ๊ฐ์ ์ ํ์ ๊ฐ์ง) SyntheticEvent์ ๋ ๋ฒ์งธ ์ ๋ค๋ฆญ์ ์ถ๊ฐํ์ฌ ๋์์ ์
๋ ฅํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๊ฐ์น๊ฐ ๊ฑฐ์ ์์ผ๋ฉฐ ์ค์ ๋ก ์คํด์ ์์ง๊ฐ ์์ต๋๋ค(์บ์คํ
์ ์ฌ์ฉํ๋ ๊ฒ์ด ํจ์ฌ ๋ ์๋ฏธ๊ฐ ์๋ ํน์ ๊ฒฝ์ฐ์๋ง ์ ์ฉ๋๊ธฐ ๋๋ฌธ์
๋๋ค).
ํนํ ์๋
๊ฐ ์๋ ๊ฒฝ์ฐ currentTarget์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๋ํ DOMAttributes<SomeType>
์์ onClick
: MouseEventHandler<SomeType>
๋ฅผ ์ป์ ๋ค์ EventHandler<MouseEvent<SomeType>>
๋ฅผ ์ป์ต๋๋ค.
interface EventHandler<E extends SyntheticEvent<any>> {
(event: E): void;
}
target์ currentTarget๊ณผ ๋ค๋ฅด๊ฒ ์ ๋ ฅํ ์ ์์ต๋๋ค. onClick์ ์ฒ๋ฆฌ ์ด๋ฒคํธ(currentTarget์ด๋ผ๊ณ ๋ ํจ)๊ฐ ์ ๋ค๋ฆญ์ผ๋ก ์๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์์ํฉ๋๋ค. ๋ค๋ฅธ ๊ฒ์ด ๋ ์ ์์ผ๋ฉฐ ์ปดํ์ผ๋์ง ์์ต๋๋ค.
@bbenezech
handleTabClick = (e: React.SyntheticEvent<HTMLLinkElement>) => { ... }
๋์ ๋ค์์ ์ ์ํฉ๋๋ค.
handleTabClick = (e: React.FormEvent<HTMLLinkElement>) => { ... }
ClipboardEvent<T>
, CompositionEvent<T>
, DragEvent<T>
, FocusEvent<T>
, KeyboardEvent<T>
...
SyntheticEvent๋ ๋ฎ์ ์์ค์ ๊ฒ์
๋๋ค.
์ด๊ฒ์ @types NPM ์ ์ฅ์์์ ์ฌ์ ํ ์ด์ ๊ฐ์ต๋๋ค. ์ด๊ฒ์ด ์ธ์ ๊ฒ์๋๋์ง์ ๋ํ ๋ชจ๋ ์ ๋ฐ์ดํธ
์ด๊ฒ์ ๋ค์ ๋ณ๊ฒฝ๋์์ต๋๋ค. #12239๋ฅผ ์ฐธ์กฐํ์ญ์์ค.
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
์ปดํ์ผ ํ์์ ๋์์ ์ ํ์ ํญ์ ์๋ฆด ์๋ ์์ต๋๋ค. ๊ทธ๊ฒ์ ์ผ๋ฐํํ๋ ๊ฒ์ ๊ฑฐ์ ๊ฐ์น๊ฐ ์์ต๋๋ค.
target์ ์ด๋ฒคํธ์ ์์์ ์ ๋๋ค.
currentTarget์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ์ฐ๊ฒฐ๋ ์์๋ก, ๋ฐ์ดํฐ ์ธํธ ๋๋ ๊ธฐํ ์์ฑ์ ์ฒจ๋ถํ๊ณ ๋ฐํ์์ ์ก์ธ์คํ๋ ค๋ ๊ฒฝ์ฐ ๋งค์ฐ ์ฃผ์ํ๊ณ ์ ์ ํ๊ฒ ์ ๋ ฅํด์ผ ํฉ๋๋ค.
currentTarget ๋์ target์ ์์กดํ๋ ๊ฒ์ ์ด์ฌ์์ ์ค์๋ก ํ์๋ณด๋ค ๋นจ๋ฆฌ ๋ฌผ๋ฆด ๊ฒ์ ๋๋ค.
์๋ฅผ ๋ค์ด:
์ด ์ฝ๋๋ ์ปดํ์ผํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
'์์ '์ด ๋ณํฉ๋๋ฉด
e.currentTarget
์ ๋ ฅํ ์ ์์ผ๋ฉฐ(์ ํ ์ค๋ฅ ์์ด ๋ฐ์ดํฐ ์ธํธ์ ์ก์ธ์คํ ์ ์์)e.target
๊ฐ ์ด์ HTMLLinkElement๋ก ์ ๋ ฅ๋์ง๋ง ์ค์ ๋ก๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค. ์ฐ๋ฆฌ๋ ๊ทธ๊ฒ์ ๋ํด ํ์ ํ ์ ์์ต๋๋ค. (์์ ์คํฌ์ ํด๋ฆญํ์ ์ ์์ต๋๋ค.์ด๋ก ์ ์ผ๋ก ์ฌ์ฉ์๊ฐ ํ์คํ ๋(์ด๋ฒคํธ ํธ๋ค๋ฌ์ ์์์ด ์๊ฑฐ๋ ๋ชจ๋ ๊ฐ์ ์ ํ์ ๊ฐ์ง) SyntheticEvent์ ๋ ๋ฒ์งธ ์ ๋ค๋ฆญ์ ์ถ๊ฐํ์ฌ ๋์์ ์ ๋ ฅํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๊ฐ์น๊ฐ ๊ฑฐ์ ์์ผ๋ฉฐ ์ค์ ๋ก ์คํด์ ์์ง๊ฐ ์์ต๋๋ค(์บ์คํ ์ ์ฌ์ฉํ๋ ๊ฒ์ด ํจ์ฌ ๋ ์๋ฏธ๊ฐ ์๋ ํน์ ๊ฒฝ์ฐ์๋ง ์ ์ฉ๋๊ธฐ ๋๋ฌธ์ ๋๋ค).
ํนํ ์๋ ๊ฐ ์๋ ๊ฒฝ์ฐ currentTarget์ ์ฌ์ฉํ ์ ์์ต๋๋ค.