React: ๊ณต๊ฐœ API๋ฅผ ํ†ตํ•ด ๋” ๋งŽ์€ ํ…Œ์ŠคํŠธ ํ‘œํ˜„

์— ๋งŒ๋“  2017๋…„ 10์›” 20์ผ  ยท  133์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: facebook/react

์ด๊ฒƒ์€ ํ›Œ๋ฅญํ•œ ๊ธฐ์—ฌ ๊ธฐํšŒ์ž…๋‹ˆ๋‹ค.
๊ณต๊ฐœ API ์ธก๋ฉด์—์„œ ๋” ๋งŽ์€ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ๋‹ค์‹œ ์ž‘์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ฆ‰, react , react-dom , react-dom/test-utils , react-test-renderer ๋“ฑ๊ณผ ๊ฐ™์€ npm ์ง„์ž…์ ๋งŒ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์ง€๋งŒ SyntheticEvent ๊ฐ™์€ ๋‚ด๋ถ€ ๋ชจ๋“ˆ์€ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ReactDOMComponentTree . "๋‚˜์œ" ์š”๊ตฌ ์‚ฌํ•ญ์€ ์ด๋ฏธ ํ…Œ์ŠคํŠธ์—์„œ TODO๋กœ ํ‘œ์‹œ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ๋†“์น˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด๋ฅผ ๋•๊ธฐ ์œ„ํ•ด:

  1. ์•„๋ž˜์˜ ์ฒญ๊ตฌ๋˜์ง€ ์•Š์€ ํ…Œ์ŠคํŠธ ํŒŒ์ผ์—์„œ // TODO: can we express this test with only public API? ๋ฅผ ์ฐพ์œผ์‹ญ์‹œ์˜ค.
  2. ํŠน์ • ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ํŒŒ์ผ์„ ์ด๋ฆ„๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์ด ๋ฌธ์ œ์— ๋Œ“๊ธ€์„ ๋‚จ๊ฒจ์ฃผ์„ธ์š”.
  3. ๋Œ€์‹  ๊ณต๊ฐœ API๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ํ…Œ์ŠคํŠธ๋ฅผ ๋‹ค์‹œ ์ž‘์„ฑํ•˜๋Š” PR์„ ์ œ์ถœํ•˜์‹ญ์‹œ์˜ค.

3๋‹จ๊ณ„๋Š” ์•ฝ๊ฐ„์˜ ์ƒ๊ฐ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์˜๊ฐ์„ ์–ป๊ธฐ ์œ„ํ•ด ๊ณต๊ฐœ API๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ๋‹ค์‹œ ์ž‘์„ฑํ•œ ์ด์ „ ์˜ˆ์ œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด:

์ผ๋ฐ˜์ ์œผ๋กœ ํ…Œ์ŠคํŠธํ•˜๋Š” ๋™์ž‘์ด React ์•ฑ์—์„œ ์‹ค์ œ๋กœ ์–ด๋–ป๊ฒŒ ์žฌํ˜„๋˜๋Š”์ง€ ์ƒ๊ฐํ•œ ๋‹ค์Œ ํ…Œ์ŠคํŠธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋“œ๋ฌธ ๊ฒฝ์šฐ์ง€๋งŒ ์ผ๋ถ€ API๋ฅผ ๊ณต๊ฐœ๋กœ ๋…ธ์ถœํ•˜๋Š” ๊ฒƒ๊ณผ ๊ด€๋ จ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋ณ„๋„๋กœ ๋…ผ์˜ํ•ด์•ผ ํ•˜๋ฏ€๋กœ ์ฃผ์ €ํ•˜์ง€ ๋ง๊ณ  ํ† ๋ก ์„ ์‹œ์ž‘ํ•˜์‹ญ์‹œ์˜ค! ๊ณต๊ฐœ API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŠน์ • ํ…Œ์ŠคํŠธ๋ฅผ ๋‹ค์‹œ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ ์—ฌ๊ธฐ์— ๋Œ“๊ธ€์„ ๋‚จ๊ฒจ์ฃผ์‹œ๋ฉด ๋ธŒ๋ ˆ์ธ์Šคํ† ๋ฐ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ์€ ๋ณ€๊ฒฝํ•ด์•ผ ํ•˜๋Š” ํ…Œ์ŠคํŠธ์˜ ์ „์ฒด ๋ชฉ๋ก์ž…๋‹ˆ๋‹ค. ๊ทธ ์ค‘ ์ผ๋ถ€๋Š” ๊ฐ„๋‹จํ•œ ํ•œ ์ค„์งœ๋ฆฌ ๋ณ€๊ฒฝ์ผ ์ˆ˜ ์žˆ๊ณ , ์ผ๋ถ€๋Š” ์•ฝ๊ฐ„์˜ ์žฌ์ž‘์„ฑ์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ผ๋ถ€๋Š” ์ฒ˜์Œ๋ถ€ํ„ฐ ๋‹ค์‹œ ์ž‘์„ฑํ•ด์•ผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ถ€๋Š” ๋ถˆ๊ฐ€๋Šฅํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ ๊ทธ ๊ฒฐ๋ก ์— ์ด๋ฅด๋Š” ์—ฐ๊ตฌ๋Š” ์—ฌ์ „ํžˆ ๋งค์šฐ ๊ฐ€์น˜๊ฐ€ ์žˆ์œผ๋ฉฐ ์šฐ๋ฆฌ๋Š” ๊ทธ๊ฒƒ์„ ์•Œ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์„ ์‹œ๋„ํ•˜๊ณ  ์ €ํฌ์—๊ฒŒ ์•Œ๋ ค์ฃผ์‹ญ์‹œ์˜ค:

์—…๋ฐ์ดํŠธ: ๋ชจ๋“  ํ…Œ์ŠคํŠธ๊ฐ€ ์ง€๊ธˆ ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค. ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ์ž‘์—…์„ ๋งˆ์น  ์‹œ๊ฐ„์ด ์—†๋‹ค๋ฉด ๋‚˜์ค‘์— ์—ฌ์œ ๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


์ฒซ ๊ธฐ์—ฌ์ž?

ํŠน์ • ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๋ช…ํ™•ํ•˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ?

์ผ๋ถ€ ํ…Œ์ŠคํŠธ๋ฅผ ํฌ๊ธฐํ•œ ๊ฒฝ์šฐ ๋‹ค์Œ ์ž‘์—…์„ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ๋„๋ก ์˜๊ฒฌ์— ๊ฒฐ๊ณผ๋ฅผ ๊ฒŒ์‹œํ•˜์‹ญ์‹œ์˜ค.


medium good first issue (taken)

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

์ฒซ ๋ฒˆ์งธ ๋ณ‘ํ•ฉ๋œ PR์ด ์žˆ์Šต๋‹ˆ๋‹ค!

๊ทธ๊ฒƒ์„ ์‚ดํŽด๋ณด์‹ญ์‹œ์˜ค : https://github.com/facebook/react/pull/11309

์ด๋ฒคํŠธ์™€ ๊ด€๋ จ๋œ ์ž‘์—…์„ ํ•˜๊ณ  ์žˆ๋‹ค๋ฉด https://github.com/facebook/react/pull/11309 ์˜ ํ† ๋ก ๊ณผ ๋‹ค์Œ ๋ฆฌ๋ทฐ๋ฅผ ๋ชจ๋‘ ์ฝ์–ด๋ณด์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

https://github.com/facebook/react/pull/11316
https://github.com/facebook/react/pull/11317
https://github.com/facebook/react/pull/11327
https://github.com/facebook/react/pull/11332

๋ช‡ ๊ฐ€์ง€ ๊ณตํ†ต ์ฃผ์ œ๊ฐ€ ์žˆ์œผ๋ฉฐ ์ด๋Ÿฌํ•œ ํ† ๋ก ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค๋ฅธ PR์„ ์˜ฌ๋ฐ”๋ฅธ ๋ฐฉํ–ฅ์œผ๋กœ ์ด๋„๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ชจ๋“  133 ๋Œ“๊ธ€

์ฃผ๋ง์— ์ด๊ฒƒ์„ ์‚ดํŽด๋ณด๊ณ  ๋‹จ๊ธฐ๊ฐ„์— ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ข‹์•„์š”, ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ํŠน์ • ํ…Œ์ŠคํŠธ๋ฅผ ์„ ํƒํ•˜๋Š” ๊ฒฝ์šฐ ๋‹ค๋ฅธ ์‚ฌ๋žŒ์ด ๋™์ผํ•œ ํ…Œ์ŠคํŠธ์—์„œ ์ž‘์—…์„ ์‹œ์ž‘ํ•˜์ง€ ์•Š๋„๋ก ์Šค๋ ˆ๋“œ์— ํŒŒ์ผ ์ด๋ฆ„์„ ์ฃผ์„์œผ๋กœ ๋‹ฌ์•„์ฃผ์„ธ์š”.

๋‚˜๋Š” ํ™•์‹คํžˆ ์ด๊ฒƒ์— ๊ธฐ์—ฌํ•˜๋Š” ๋ฐ ๋งค์šฐ ๊ด€์‹ฌ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ์ฃผ๋ง์„ ํ†ตํ•ด ๊ฒ€ํ† ํ•˜๊ณ  ๋ฆฌํŒฉํ† ๋งํ•  ๊ธฐํšŒ๋ฅผ ์ฐพ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค!

์ €๋„ ๊ด€์‹ฌ ๐Ÿ‘

์ฒซ ๋ฒˆ์งธ ๊ฒŒ์‹œ๋ฌผ์— ํ…Œ์ŠคํŠธ ๋ชฉ๋ก์„ ๊ฒŒ์‹œํ–ˆ์Šต๋‹ˆ๋‹ค. ์–ด๋–ค ๊ฒƒ์„ ์„ ํƒํ•˜๊ณ  ์‹ถ์€์ง€ ์•Œ๋ ค์ฃผ์‹œ๋ฉด ๋ฐฐ์ •ํ•ด ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

ReactDOMInput-test ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค :)

@SadPandaBear ์•Œ์•˜ ์Šต๋‹ˆ๋‹ค!

ReactErrorUtils-test ์—์„œ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ˜„

setInnerHTML-test.js ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

getEventCharCode-test.js ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ๐Ÿ˜€

getEventKey-test.js ์—์„œ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

escapeTextContentForBrowser-test.js ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ChangeEventPlugin-test.js ํ•œ ๋ฒˆ ํ•ด๋ณด๊ณ  ์‹ถ์–ด์š” :)

SyntheticEvent-test.js ๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

EnterLeaveEventPlugin-test.js ์—์„œ ์ž‘์—…ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

ReactDOMEventListener-test.js ์—์„œ ์ž‘์—…ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

BeforeInputEventPlugin-test.js ๋ฐ›๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค

SyntheticKeyboardEvent-test.js๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค ๐Ÿ‘

inputValueTracking-test.js ๊ฐ€์ ธ๊ฐ€๊ฒ ์Šต๋‹ˆ๋‹ค

SyntheticWheelEvent-test.js ์—์„œ ์ž‘์—…ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ: ReactBrowserEventEmitter-test.js ?

SelectEventPlugin-test.js ๋ฐ›๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค

ReactDOMComponentTree-test.js ์—์„œ ์ž‘์—…ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

ReactTreeTraversal-test.js์—์„œ ์ž‘์—…ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

์•ˆ๋…•! ๐Ÿ‘‹ ReactCoroutine-test.js ์—์„œ ์ž‘์—…ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

SyntheticClipboardEvent-test.js ๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

validateDOMNesting-test.js ์—์„œ ์ž‘์—…ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

EventPluginRegistry-test.js ๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ReactDOMComponent-test.js ์„(๋ฅผ) ์‹œ๋„ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

์—ฌ๋ณด์„ธ์š”! quoteAttributeValueForBrowser-test.js ์„(๋ฅผ) ์‹œ๋„ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค! :๊ทผ์œก:

์—ฌ๋ณด์„ธ์š”! ReactDOMServerIntegration-test.js ์„(๋ฅผ) ์‹œ๋„ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค!

์ €๋Š” ReactIncrementalPerf-test.js ๋ฅผ ๋ฐ›์Šต๋‹ˆ๋‹ค.

getNodeForCharacterOffset-test.js๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

@burnsbeaver FallbackCompisitionState-test ๋˜๋Š” getNodeForCharacterOffset-test ์ค‘ ์–ด๋Š ๊ฒƒ์ž…๋‹ˆ๊นŒ? 1์ธ๋‹น ํ•˜๋‚˜์˜ ํ…Œ์ŠคํŠธ๋กœ ์‹œ์ž‘ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

getNodeForCharacter ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋Œ“๊ธ€์€ ์ง€์› ์–ด์š” ํ˜ผ๋ž€์„ ๋“œ๋ ค ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค!

์•„์ง FallbackCompositionState-test.js ๋ฐ ReactFiberHostContext-test.js ๊ฐ€ ๋ฌด๋ฃŒ์ž…๋‹ˆ๋‹ค!

FallbackCompisitionState๋ฅผ ์‚ฌ์šฉํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค!

๋‚˜๋Š” ReactFiberHostContext-test.js๋ฅผ ์‹œ๋„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค

์—…๋ฐ์ดํŠธ: ๋ชจ๋“  ํ…Œ์ŠคํŠธ๊ฐ€ ์ง€๊ธˆ ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค. ์ด๋ฒˆ ํ˜ธ๋ฅผ ๊ตฌ๋…ํ•˜์„ธ์š”! ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ์ž‘์—…์„ ๋งˆ์น  ์‹œ๊ฐ„์ด ์—†๋‹ค๋ฉด ๋‚˜์ค‘์— ์—ฌ์œ ๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ถ€ ํ…Œ์ŠคํŠธ๋ฅผ ๋‹ค์‹œ ์‹œ๋„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜๋ฉด ์˜๊ฒฌ์„ ๋งํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์‹œํ—˜์— ์‘์‹œํ•œ ๋ชจ๋“  ์‚ฌ๋žŒ๋“ค์—๊ฒŒ โ€“ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ์†”๋ฃจ์…˜์ด ํ•ญ์ƒ ๋ช…ํ™•ํ•œ ๊ฒƒ์€ ์•„๋‹ˆ๋ฉฐ ์–ด๋–ค ๊ฒฝ์šฐ์—๋Š” React ์†Œ์Šค ์ž์ฒด๋ฅผ ์•ฝ๊ฐ„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ ๋Š” ๋™์ž‘์„ ํ•ฉ๋ฆฌ์ ์œผ๋กœ ํ…Œ์ŠคํŠธํ•˜๋Š” ๊ฒƒ์ด ๋ถˆ๊ฐ€๋Šฅํ•  ์ˆ˜๋„ ์žˆ๋‹ค๋Š” ์ ์„ ๋ฐ˜๋ณตํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๋ง‰ํ˜”๋‹ค๊ณ  ๋Š๋ผ์‹œ๋ฉด ์—ฌ๊ธฐ์— ๋Œ“๊ธ€์„ ๋‚จ๊ฒจ์ฃผ์„ธ์š”. ๊ณ„ํš์„ ์ฐพ๋„๋ก ๋…ธ๋ ฅํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

@adsonpleal ์‹ค๋ง์‹œ์ผœ๋“œ๋ ค ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ๋ฐฉ๊ธˆ ํ™•์ธํ–ˆ๋Š”๋ฐ ๋ถˆํ–‰ํžˆ๋„ ์ด๋ฏธ ReactFiberHostContext-test ์„ ์ˆ˜์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ฒ˜์Œ์—๋Š” ์ด๊ฒƒ์„ ๊นจ๋‹ซ์ง€ ๋ชปํ–ˆ์ง€๋งŒ ๊ทธ TODO๋Š” ๊ตฌ์‹์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ด๋ฏธ ์ˆ˜์ •๋œ ์œ ์ผํ•œ ํ…Œ์ŠคํŠธ์ž…๋‹ˆ๋‹ค.

@gaearon ์™€, ReactDOMInput-test ๋ฆฌํŒฉํ† ๋งํ•˜๋Š”๋ฐ ์‹œ๊ฐ„์ด ์ข€ ๊ฑธ๋ฆฌ๊ฒ ์ง€๋งŒ ์ด๋ฒˆ ์ฃผ๋ง์— ๋‹ค ๋๋‚ด๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ž‘์€ ์˜์‹ฌ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
inputValueTracking setUntrackedValue ํ•จ์ˆ˜์˜ ๋ชจ๋“  ๋™์ž‘์„ ReactTestUtils.Simulate.? ์™€ ๊ฐ™์€ ๊ฒƒ์œผ๋กœ ๊ต์ฒดํ•ด๋„ ๋ ๊นŒ์š”?

๊ทธ๋Ÿฐ๋ฐ ์—ฌ๊ธฐ ์—์„œ ๋‚ด PR์„ ํ™•์ธํ•˜์—ฌ inputValueTracking ๋ฅผ ์ œ๊ฑฐํ•˜๊ธฐ ์œ„ํ•ด ๋ฌด์—‡์„ ํ–ˆ๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ํ…Œ์ŠคํŠธ ์ค‘ ์ผ๋ถ€๋Š” inputValueTracking ์˜ ๋งค์šฐ ๊ตฌ์ฒด์ ์ธ ํ•ญ๋ชฉ์— ์˜์กดํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์ง€๋งŒ ReactTestUtils ๋Œ€์‹  ํšจ๊ณผ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค.

inputValueTracking ์˜ ๊ฒฝ์šฐ @jquense ๋Š” ๊ฐ€์žฅ ์ž˜ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๊ฐ€์žฅ ๋งŽ์€ ์ปจํ…์ŠคํŠธ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ž‘๋™ํ•˜๋Š” ํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์ด ์ž‘๋™ํ•˜๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๊ฒ€ํ† ํ•˜๊ณ  ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ์‚ฌ๋žŒ์—๊ฒŒ ์ฃผ์˜๋ฅผ ๊ธฐ์šธ์ด๋ฉด ์ด์ „ ๋ฒ„์ „์˜ ์›์‚ฌ(0.22)๊ฐ€ ์„ค์น˜๋˜์–ด ์žˆ๊ณ  ๋กœ์ปฌ์—์„œ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๊ณ  ํ–ˆ์œผ๋‚˜ ๋ชจ๋“  ๊ฒƒ์ด ์ค‘๋‹จ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์›์‚ฌ๋ฅผ ์ตœ์‹ (1.2.1)์œผ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜์—ˆ์œผ๋ฉฐ ํ…Œ์ŠคํŠธ๊ฐ€ ํ˜„์žฌ ์ •์ƒ์ ์œผ๋กœ ์‹คํ–‰๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

@sadpandabear ๋‚ด ํ…Œ์ŠคํŠธ ํŒŒ์ผ์— ๋™์ผํ•œ ๋ชจ๋“ˆ์ด ์žˆ์œผ๋ฏ€๋กœ ๊ณง ๊ตฌํ˜„์„ ํ™•์ธํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

@gaearon setInnerHTML ํ…Œ์ŠคํŠธ์˜ ๊ฒฝ์šฐ ํ…Œ์ŠคํŠธ ์Šค์œ„ํŠธ๊ฐ€ ์˜๋ฏธ๋ฅผ ๊ฐ–๊ธฐ ์œ„ํ•ด์„œ๋Š” setInnerHTML ์˜ ์กด์žฌ์— ์˜์กดํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋Š๋‚๋‹ˆ๋‹ค.

๊ธฐ์กด ๊ธฐ๋Šฅ์„ ๋Œ€์ฒดํ•˜๊ธฐ ์œ„ํ•ด ๋ช‡ ๊ฐ€์ง€ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ํ…Œ์ŠคํŠธ ์Šค์œ„ํŠธ๋Š” setInnerHTML ์— ํŠน์ •ํ•œ ๊ฒƒ๊ณผ ๋น„๊ตํ•˜์—ฌ ๋‚ด๋ถ€ html์„ ์„ค์ •ํ•˜๋Š” ๋ผ์ธ์— ๋” ๊ฐ€๊น์Šต๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ ์Šค์œ„ํŠธ์˜ ์ด๋ฆ„์„ ์ง“๋Š” ๋ฐ ์กฐ๊ธˆ ์–ฝ๋งค์ด๋Š” ๊ฒƒ ๊ฐ™์•„์š”.

ํŽธ์ง‘: ๋‚ด๊ฐ€ ์‹ค์ˆ˜ํ•˜์ง€ ์•Š๋Š” ํ•œ ... SVG์—๋Š” innerHTML ์†์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํŒŒ์ผ์˜ ๋‘ ๋ฒˆ์งธ ํ…Œ์ŠคํŠธ ์ฒญํฌ๊ฐ€ ํ•„์š”ํ•œ์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@silvestrijonathan ๊ทธ ํ…Œ์ŠคํŠธ๊ฐ€ ์‹ค์ œ๋กœ ํ™•์ธํ•˜๋ ค๋Š” ๊ฒƒ์€ dangerouslySetInnerHTML ๊ฐ€ React์—์„œ ์˜ˆ์ƒ๋Œ€๋กœ ์ž‘๋™ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด๋Ÿฌํ•œ ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜์ •ํ•˜์—ฌ ReactDOM์„ ์‚ฌ์šฉํ•˜๊ณ  dangerouslySetInnerHTML ๋กœ ๋™์ผํ•œ ์ฝ˜ํ…์ธ ๋ฅผ ๋ Œ๋”๋งํ•˜๋ฉด ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ ์ด๋ฆ„์„ dangerouslySetInnerHTML-test ๋กœ ๋ฐ”๊พธ๋Š” ๊ฒƒ์ด ๋” ์ ์ ˆํ•˜๋‹ค๊ณ  ์ƒ๊ฐ๋˜๋ฉด ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.

๋‚ด ํ…Œ์ŠคํŠธ ํŒŒ์ผ์„ ๊ฐ€์ง€๊ณ  ๋ช‡ ์‹œ๊ฐ„ ๋†€๊ณ  ๋‚œ ํ›„ ๋‚˜๋Š” (๋‚˜์™€ ๊ฐ™์€) ์ดˆ๋ณด์ž๋ฅผ ์œ„ํ•œ ๊ฐ•๋ ฅํ•œ ์ œ์•ˆ์ด ์žˆ์Šต๋‹ˆ๋‹ค: ๊นจ๋—ํ•œ ํ™˜๊ฒฝ(ํŒŒ์ผ)์œผ๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ์‹œ์ž‘ํ•˜์‹ญ์‹œ์˜ค.
๊ธฐ์กด ํŒŒ์ผ์„ ํŽธ์ง‘ํ•˜๋‹ค๊ฐ€ ์ผ๋ถ€ ๋‚ด๋ถ€ ๊ธฐ๋Šฅ์„ ์กฐ๋กฑํ•˜์—ฌ ๋ช‡ ๊ฐœ์˜ ReactTestUtils ๊ธฐ๋Šฅ์ด ๊นจ์กŒ์Šต๋‹ˆ๋‹ค!! ์ผ์ด ์˜๋„ํ•œ ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋ฅผ ๊นจ๋‹ซ๋Š” ๋ฐ ์‹œ๊ฐ„์ด ์ข€ ๊ฑธ๋ ธ์Šต๋‹ˆ๋‹ค.

@gaearon ์ด๋ฒคํŠธ ์‹œ๋ฎฌ๋ ˆ์ด์…˜์„ ํฌํ•จํ•˜์—ฌ ReactTestUtils ๋Š” ๋น„๊ณต๊ฐœ API๋กœ ๊ฐ„์ฃผ๋˜์–ด์•ผ ํ•œ๋‹ค๋Š” ์ ์„ ๋ช…ํ™•ํžˆ ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋‚ด๋ถ€ API์— ๊ฐ„์ ‘์ ์œผ๋กœ ๋„๋‹ฌํ•˜๋ฏ€๋กœ ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ์ œ๋Œ€๋กœ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ํ›„ํฌ๋ฅผ ๋…ธ์ถœํ•˜์ง€ ์•Š๊ณ  ์ปดํŒŒ์ผ๋œ ํŒจํ‚ค์ง€๋ฅผ ํ…Œ์ŠคํŠธํ•˜๋Š” ๋ฐ ๋ฐฉํ•ด๊ฐ€ ๋˜๋ฉฐ ์ƒˆ๋กœ์šด ๋น„ํ•ฉ์„ฑ ์ด๋ฒคํŠธ ์‹œ์Šคํ…œ์„ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

@dphurley , ReactIncrementalPerf-test ์ž‘์—… ์ค‘์ด๋ผ๋Š” ๊ฒƒ์„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋˜ํ•œ ReactCoroutine ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ…Œ์ŠคํŠธ ์Šค์œ„ํŠธ์—์„œ ์ž‘์—…ํ•˜๊ณ  ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด PR์— ๋Œ€ํ•ด ์•Œ๋ ค๋“œ๋ฆฌ๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค: #11338.
์ด๋ฏธ PR์„ ์ œ์ถœํ–ˆ๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์ง€๋งŒ ์•„์ง ์ œ์ถœํ•˜์ง€ ์•Š์•˜๋‹ค๋ฉด #11338(์Šน์ธ๋œ ๊ฒฝ์šฐ)์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

@gaearon ์กฐ์–ธ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด React-DOM with dangerouslySetInnerHTML ๋ฅผ ์‚ฌ์šฉํ•  ์ƒ๊ฐ์„ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋ ‡๊ฒŒ ํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค!

๊ทธ๋ฆฌ๊ณ  ์˜ˆ, ๋‚˜๋Š” ์•„๋งˆ๋„ ๊ทธ ๊ฒฝ์šฐ์— ํ…Œ์ŠคํŠธ ์ด๋ฆ„์„ ๋ฐ”๊ฟ€ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ ๋‚  ์ •๋„์— ๋‚ด PR์„ ์ฐพ์œผ์‹ญ์‹œ์˜ค.

์ฒซ ๋ฒˆ์งธ ๋ณ‘ํ•ฉ๋œ PR์ด ์žˆ์Šต๋‹ˆ๋‹ค!

๊ทธ๊ฒƒ์„ ์‚ดํŽด๋ณด์‹ญ์‹œ์˜ค : https://github.com/facebook/react/pull/11309

์ด๋ฒคํŠธ์™€ ๊ด€๋ จ๋œ ์ž‘์—…์„ ํ•˜๊ณ  ์žˆ๋‹ค๋ฉด https://github.com/facebook/react/pull/11309 ์˜ ํ† ๋ก ๊ณผ ๋‹ค์Œ ๋ฆฌ๋ทฐ๋ฅผ ๋ชจ๋‘ ์ฝ์–ด๋ณด์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

https://github.com/facebook/react/pull/11316
https://github.com/facebook/react/pull/11317
https://github.com/facebook/react/pull/11327
https://github.com/facebook/react/pull/11332

๋ช‡ ๊ฐ€์ง€ ๊ณตํ†ต ์ฃผ์ œ๊ฐ€ ์žˆ์œผ๋ฉฐ ์ด๋Ÿฌํ•œ ํ† ๋ก ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค๋ฅธ PR์„ ์˜ฌ๋ฐ”๋ฅธ ๋ฐฉํ–ฅ์œผ๋กœ ์ด๋„๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฐธ์กฐ์— ๋Œ€ํ•œ ํ›Œ๋ฅญํ•œ ๋Œ€ํ™” - ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

์ผ์ด ์ข€ ๋ฐ”๋นด์ง€๋งŒ ์ด๋ฒˆ ์ฃผ๋ง์— ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด PR์„ ์—ด ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์•„์ง ๋‚ด๊ฐ€ ์ง‘์–ด๋“  ์‹œํ—˜์„ ์‚ดํŽด๋ณด์ง€ ์•Š์•˜๋‹ค. ๋‹ค๋ฅธ ์ผ๋กœ ๋ฐ”๋นด์Šต๋‹ˆ๋‹ค. ๋ฉฐ์น  ํ›„์— PR์„ ์˜ฌ๋ฆฌ๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์‹œ๊ฐ„์„ ๋ฒŒ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

์ž˜ ๋“ค๋ฆฝ๋‹ˆ๋‹ค.

๋‚˜๋Š” ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ๋‹ค

๋˜ ํ•˜๋‚˜์˜ PR์ด ํ•ฉ์ณ์กŒ์Šต๋‹ˆ๋‹ค! https://github.com/facebook/react/pull/11316

๋‚ด๊ฐ€ ํ…Œ์ŠคํŠธ ์ค‘ ํ•˜๋‚˜์— ์ ‘๊ทผํ•œ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ž‘์€ ๋ถ„์„์„ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. https://github.com/facebook/react/pull/11385#issuecomment -341934588

๋‚ด๊ฐ€ ๋งํ•  ์ˆ˜์žˆ๋Š” ํ•œ ๊ทธ๋“ค์€ ๋ชจ๋‘ ๊ฐ€์ ธ ๊ฐ”๊ณ  ์—ฌ์œ ๊ฐ€ ์žˆ์œผ๋ฉด ์—ฌ๊ธฐ์— ๊ฒŒ์‹œํ•˜์‹ญ์‹œ์˜ค. ๊ทธ๋Ÿฌ๋ฉด ๋‚ด๊ฐ€ ๋ณผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ํŠนํžˆ SyntheticEvent ๋ฅผ ๋‹ค๋ฃจ๋Š” 2๊ฐœ์˜ PR์„ ๋” ๋ณ‘ํ•ฉํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ด€๋ จ ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•œ ๊ฒฝ์šฐ https://github.com/facebook/react/pull/11365 ๋ฐ https://github.com/facebook/react/issues/ ์—์„œ ํ™•์ธํ•˜๊ณ  ์Šคํƒ€์ผ๊ณผ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์ผ์น˜์‹œํ‚ค์‹ญ์‹œ์˜ค.

@gaearon EventPluginRegistry-test.js ์˜ ๊ฒฝ์šฐ ๊ณต๊ฐœ API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ…Œ์ŠคํŠธ๋ฅผ ๋‹ค์‹œ ์ž‘์„ฑํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ReactDom.js -> ReactDOMClientInjection.js์— ๊ธฐ๋ณธ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ฃผ์ž…ํ•˜๊ณ  ์žˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
{
๋‹จ์ˆœ ์ด๋ฒคํŠธ ํ”Œ๋Ÿฌ๊ทธ์ธ,
EnterLeaveEventPlugin,
๋ณ€๊ฒฝ ์ด๋ฒคํŠธ ํ”Œ๋Ÿฌ๊ทธ์ธ,
์…€๋ ‰ํŠธ ์ด๋ฒคํŠธ ํ”Œ๋Ÿฌ๊ทธ์ธ,
BeforeInputEventPlugin,
}

ํ…Œ์ŠคํŠธ ๋ชจ์˜ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ •ํ™•ํžˆ ์–ด๋–ป๊ฒŒ ์ฃผ์ž…ํ•˜๊ณ  EventPluginRegistry ๊ธฐ๋Šฅ์„ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?
์‚ฌ์šฉ์ž ์ •์˜ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ๊ฒ€์ƒ‰ํ•˜๊ณ  ์‚ฌ์šฉ์ž ์ •์˜ ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ์ •ํ™•ํžˆ ์ฃผ์ž…๋˜๋Š” ๋ฐฉ๋ฒ•์„ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด react-tap-event-plugin ์„ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค.
์ด๊ฒƒ์ด ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ฃผ์ž…ํ•˜๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๊นŒ?

require('react-dom').__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.EventPluginHub.injection.injectEventPluginsByName({ 'TapEventPlugin': require('./TapEventPlugin.js')(shouldRejectClick) });

ReactTreeTraversal-test.js ์—์„œ ๋„ˆ๋ฌด ๊ณผํ•œ ๊ฒƒ ๊ฐ™์•„
๋‹ค๋ฅธ ์‚ฌ๋žŒ์ด ๊ทธ๊ฒƒ์„ ์‹œ๋„ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์ž์œ ๋กญ๊ฒŒ ๊ทธ๋ ‡๊ฒŒํ•˜์‹ญ์‹œ์˜ค.

@aqumus

EventPluginRegistry ๋Š” ๊นŒ๋‹ค๋กญ์Šต๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ๋‹จ๊ณ„๋Š” ์‹ค์ œ๋กœ ์‚ฌ์šฉ๋˜๋Š” ์œ„์น˜๋ฅผ ํŒŒ์•…ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํƒญ ์ด๋ฒคํŠธ ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ์šฐ๋ฆฌ ๊ฐ€ ์—ฌ์ „ํžˆ ์ง€์›ํ•˜๊ธฐ๋กœ ์•ฝ์†ํ•œ ์œ ์ผํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ์ด๋ผ๋Š” ๋ง์ด ๋งž์Šต๋‹ˆ๋‹ค. ํŽธ๋ฆฌํ•˜๊ฒŒ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์— ๋ฐ”๋กœ ๋ณด๊ด€๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ํŠน๋ณ„ํžˆ ์ž‘๋™ํ•˜๋Š” ํ…Œ์ŠคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”?

๋˜ํ•œ RN์ด EventPluginRegistry ๋ฅผ ์‚ฌ์šฉํ•  ๊ฐ€๋Šฅ์„ฑ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. RN ์ด๋ฒคํŠธ๊ฐ€ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ํ…Œ์ŠคํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ๋ชจ๋ฅด๊ฒ ์–ด์š”. EventPluginRegistry ์˜ ๋‹ค๋ฅธ ๋ถ€๋ถ„์— ์ฃผ์„์„ ๋‹ฌ๊ณ  ํ…Œ์ŠคํŠธ๊ฐ€ ์‹คํŒจํ–ˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๋™์ผํ•œ ์ฝ”๋“œ๊ฐ€ ํ•ด๋‹น ์ฝ”๋“œ ๊ฒฝ๋กœ์— ์ŠคํŠธ๋ ˆ์Šค๋ฅผ ์ฃผ๋Š” ๋‹ค๋ฅธ ํ…Œ์ŠคํŠธ์— ์ด๋ฏธ ํฌํ•จ๋˜์–ด ์žˆ๋Š” ๊ฒฝ์šฐ ๋น„๊ณต๊ฐœ API ํ…Œ์ŠคํŠธ๋ฅผ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒŒ ๋ง์ด ๋˜์š”?

@gdevincenzi ์ข‹์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ํ• ๋‹น์„ ์ œ๊ฑฐํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ, ์ €๋Š” ์ด๋ฒˆ ์ฃผ์— ์ž๋ฆฌ๋ฅผ ๋น„์šธ ์˜ˆ์ •์ด์ง€๋งŒ, ์ด๋กœ ์ธํ•ด ๊ณ„์† ์ง„ํ–‰๋˜๋Š” ๋ฐ ๋ฐฉํ•ด๊ฐ€ ๋˜์ง€ ์•Š๋„๋ก ํ•˜์‹ญ์‹œ์˜ค. ๋‹ค์Œ ์ฃผ์— ์ œ์ถœ๋œ PR์ด ๋ช‡ ๊ฐœ ๋” ๋ณ‘ํ•ฉ๋˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

๋‚˜๋Š” ReactTreeTraversal-test.js ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค - ๊ทธ๊ฒƒ์€ ์ต์ˆ™ํ•˜์ง€ ์•Š์€ API์ง€๋งŒ ๊ทธ๊ฒƒ์„ ๋ฐฐ์šฐ๊ธฐ์— ์ข‹์€ opp์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์กฐ์–ธ ํ™˜์˜ ํ•ฉ๋‹ˆ๋‹ค @gdevincenzi

๋‹ค์†Œ ๋ณต์žกํ•œ ์ž‘์—…์„ ๋งˆ์นœ @gordyd ์—๊ฒŒ ์ถ•ํ•˜์˜ ๋ง์„ ์ „ํ•ฉ๋‹ˆ๋‹ค: https://github.com/facebook/react/pull/11383.

์ด๊ฒƒ์€ ๋ณธ์งˆ์ ์œผ๋กœ ๋™์ผํ•œ ๊ฒƒ์„ ํ…Œ์ŠคํŠธํ•˜๋Š” ๋™์•ˆ ์ฝ”๋“œ๊ฐ€ ์ „ํ›„์— ์–ผ๋งˆ๋‚˜ ๋‹ค๋ฅธ์ง€ ๋ณด์—ฌ์ฃผ๋Š” ์ข‹์€ ์˜ˆ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ฐธ์กฐ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๊ณ , git ๊ธฐ๋ก์„ ๋ณด๊ณ , ๋‹ค๋ฅธ ํ–‰์„ ์ฃผ์„ ์ฒ˜๋ฆฌํ•˜์—ฌ ์ฝ”๋“œ๊ฐ€ ๋ฌด์—‡ ์„ ํ•ด์•ผ ํ•˜๋Š”์ง€ ์•Œ์•„๋‚ผ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•.

๋‹ค์Œ ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ์•„์ง PR์„ ๋ฐ›์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.

@email2vimalraj
@andrevargas
@tranotheron
@๋ฏธ๋„ค๋ผ๋„
@sw-yx
@king0120
@aarboleda1
@danilowoz
@dms1lva
@๋ชจ๋ผ์ž๋น„
@dphurley
@reznord
@aqumus

์ด ์ž‘์—…์„ ์‹œ์ž‘ํ–ˆ๋Š”์ง€ ํ™•์ธํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๋Œ€๊ธฐ์—ด์— ๋„์›€์„ ์ฃผ๊ณ  ์‹ถ์€ ์‚ฌ๋žŒ๋“ค์ด ๋” ๋งŽ๊ธฐ ๋•Œ๋ฌธ์— ์‹œ๊ฐ„์ด ์—†๋‹ค๋ฉด ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ์ด ์ž‘์—…์„ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐํšŒ๋ฅผ ์ฃผ๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

@andrevargas ๋ฐฉ๊ธˆ https://github.com/facebook/react/pull/11331์—์„œ ๊ท€ํ•˜์˜ ํ† ๋ก ์„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ํ†ตํ•ฉ๋œ ์ƒํƒœ๋กœ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ด ํ•ฉ๋ฆฌ์ ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ €๋ฅผ ๋Œ€๊ธฐ์—ด์— ์ถ”๊ฐ€ํ•ด์ฃผ์„ธ์š” @gaearon

@gaearon ๋„ค ๋งž์Šต๋‹ˆ๋‹ค. ํ™•์ธ์„ ์œ„ํ•ด @jeremenichelli ๋Š” #11331์—์„œ quoteAttributeValueForBrowser-test.js ์ž‘์—…์„ ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ์ด ์‚ฌ์‹ค์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋‹น์‹ ์ด ๊ทธ์˜ ์‚ฌ์šฉ์ž ์ด๋ฆ„๊ณผ PR์˜ ๋งํฌ๋กœ ์ด ์Šค๋ ˆ๋“œ๋ฅผ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ €๋ฅผ ๋Œ€๊ธฐ์—ด @gaearon ์—๋„ ์ถ”๊ฐ€ํ•ด์ฃผ์„ธ์š”.

@gaearon ์ž‘์—…์„ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ์ฃผ์— ๋‚ด ์—ฐ๊ตฌ ๊ฒฐ๊ณผ๋‚˜ PR์„ ๊ฒŒ์‹œํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค.

@gaearon SyntheticKeyboardEvent.js ์ž‘์—…์„ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ์ฃผ๋ง์— PR์„ ํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค.

@gaearon ์›๋ž˜ ๋ฐฐ์ •๋œ ์‚ฌ๋žŒ๋“ค์ด ์ž‘์—…ํ•  ์‹œ๊ฐ„์ด ์—†์„ ๊ฒฝ์šฐ๋ฅผ ๋Œ€๋น„ํ•˜์—ฌ ์–ด๋–ค ํ…Œ์ŠคํŠธ๋„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@gaearon ๋Šฆ์–ด์„œ ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค ์ง€๊ธˆ WIP PR์„ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์—…๋ฐ์ดํŠธ: ๋น„๊ณต๊ฐœ API์— ์˜์กดํ•˜์ง€ ์•Š์œผ๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ•˜๋Š”์ง€ ๊ฐ„๋‹จํžˆ ์„ค๋ช…ํ•ด์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๋˜ํ•œ top<EventName> ์— ๋Œ€ํ•ด ์ž˜ ๋ชจ๋ฆ…๋‹ˆ๋‹ค. ๊ฐ์‚ฌ ํ•ด์š”.

https://github.com/facebook/react/blob/92b7b172cce9958b846844f0b46fd7bbd8c5140d/packages/react-dom/src/events/__tests__/SelectEventPlugin-test.js > extract ํ•จ์ˆ˜

@gaearon ๋Šฆ์–ด์„œ ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค ๐Ÿ˜‚. ๋‚˜๋Š” ์˜ค๋Š˜ ์ด๊ฒƒ์— ๋Œ€ํ•ด ์ž‘์—…ํ•  ๊ฒƒ์ด๊ณ  ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ์•ฝ๊ฐ„์˜ ์˜์‹ฌ์ด ์žˆ์œผ๋ฉด ๋‹น์‹ ์—๊ฒŒ ํ•‘์„ ๋ณด๋‚ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@morajabi ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ํ•œ ๊ฐ€์ง€ ์ž ์žฌ์ ์ธ ๋ฐฉ๋ฒ•

  • SelectEventPlugin ๋ฅผ ๋ณด๊ณ  ์‚ฌ์šฉ์ž์—๊ฒŒ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค.
  • ํ•ด๋‹น ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ ์ž‘์„ฑ
  • SelectEventPlugin ๋กœ๋“œ๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•˜๊ณ (์ฃผ์„ ์ฒ˜๋ฆฌ) ๋ฌด์—‡์ด ์ค‘๋‹จ๋˜๋Š”์ง€ ํ™•์ธ(๋ฌด์—‡์ด ์ค‘๋‹จ๋˜๋Š”์ง€ ํ™•์ธ)
  • ์ž‘์„ฑํ•œ ์ฝ”๋“œ๋Š” ์ด์ œ ํ…Œ์ŠคํŠธ์˜ ์ฒซ ๋ฒˆ์งธ ๋ฒ„์ „์ด๋ฏ€๋กœ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค์— ๋„ฃ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • SelectEventPlugin ๋กœ๋“œ๋ฅผ ๋‹ค์‹œ ํ™œ์„ฑํ™”ํ•˜๊ณ  ํ…Œ์ŠคํŠธ๊ฐ€ ํ†ต๊ณผํ•˜๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.
  • ์ฝ”๋“œ ์ตœ์ ํ™”

@gaearon ์ง€์—ฐ ์‚ฌ๊ณผ
๊ท€ํ•˜์˜ ์ œ์•ˆ์— ๋”ฐ๋ผ EventPluginRegistry.js ์˜ ๋ช‡ ๊ฐ€์ง€ ๋ถ€๋ถ„์— ๋Œ€ํ•ด ์ฃผ์„์„ ๋‹ฌ์•˜๊ณ  ๋งŽ์€ ํ…Œ์ŠคํŠธ ์‚ฌ๋ก€๊ฐ€ ์‹คํŒจํ–ˆ์Œ์„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค( SyntheticWheelEvent , ReactDOMComponentTree , SyntheticClipboardEvent , SyntheticWheelEvent , inputValueTracking , SimpleEventPlugin , ChangeEventPlugin , ReactDOMComponentTree ๋“ฑ),
ReactBrowserEventEmitter.js ๊ฐ€ EventPluginRegistry.js registrationNameDependencies ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์ฃผ์„์„ ๋‹ฌ ๋•Œ์—๋„

ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ์ค‘ ์‹คํŒจํ•˜์ง€ ์•Š์Œ( EventPluginRegistry ํ…Œ์ŠคํŠธ๋งŒ ์‹คํŒจ)
์ด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ EventPluginRegistry ๋Š” ์ด๋ฏธ ๋‹ค๋ฅธ ํ…Œ์ŠคํŠธ ์Šค์œ„ํŠธ์—์„œ ๋‹ค๋ฃจ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

ํŽธ๋ฆฌํ•˜๊ฒŒ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์— ๋ฐ”๋กœ ๋ณด๊ด€๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋‹น์‹ ์ด ์ด๊ฒƒ์„ ์˜๋ฏธํ•˜๋Š” ๊ฒƒ์„ ์ดํ•ดํ•˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค

๊ณต๊ฐœ API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ EventPluginRegistry ๋ฅผ ๋‹ค์‹œ ์ž‘์„ฑํ•˜๊ธฐ ์œ„ํ•ด ์ž‘์—…ํ•  ์ˆ˜ ์žˆ๋Š” ๋‹ค๋ฅธ ์ œ์•ˆ ์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ๋Š”(์ด๊ฒƒ์ด ์ด์ „์— ๋ฐฉ์†ก๋˜์—ˆ๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Œ) @kentcdodds ๋น„๋””์˜ค ํŒŸ์บ์ŠคํŠธ - Ben Alpert์˜ ๋ฐ˜์‘ ์ด๋ฒคํŠธ ์ฝ”๋“œ ์—ฐ์Šต์ด ๋งค์šฐ ์œ ์šฉํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค.

@gaearon ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค ํ•˜๋ ค๊ณ  ํ–ˆ๋Š”๋ฐ ์ด์ œ ๋๋‚ผ ์‹œ๊ฐ„์ด ์—†๋„ค์š”
๋”ฐ๋ผ์„œ ๋‹ค๋ฅธ ์‚ฌ๋žŒ์ด ๋‚ด ๋ฌธ์ œ๋ฅผ ์–ป๊ณ  ์‹ถ๋‹ค๋ฉด ์ž์œ ๋กญ๊ฒŒ ๋Š๋ผ์‹ญ์‹œ์˜ค. :)

@danilowoz @gaearon ๊ดœ์ฐฎ๋‹ค ๋ฉด BeforeInputEventPlugin-test.js๋ฅผ ๊ฐ€์ ธ๊ฐˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@timjacobi ReactDOMComponentTree.getInstanceFromNode ์˜ ๋Œ€์ฒดํ’ˆ์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

๋˜ํ•œ ์–ด๋””์—์„œ ๋น„ํ™œ์„ฑํ™”ํ•ด์•ผํ•ฉ๋‹ˆ๊นŒ?

SelectEventPlugin ๋กœ๋“œ๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•˜๊ณ (์ฃผ์„ ์ฒ˜๋ฆฌ) ์ค‘๋‹จ๋œ ํ•ญ๋ชฉ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค(๋ฌธ์ œ๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธ).

@morajabi ์ ์ ˆํ•œ ์ˆ˜์ค€์—์„œ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ  ์žˆ๋Š”์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ๊นŒ์ง€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฒƒ์œผ๋กœ WIP PR์„ ์—ด ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ์ด ์Šค๋ ˆ๋“œ๋ฅผ ๋„ˆ๋ฌด ๋”๋Ÿฝํžˆ๊ณ  ์‹ถ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@timjacobi ๋‚˜๋Š” ์ƒˆ๋กœ์šด ๊ฒƒ์„ ์ปค๋ฐ‹ํ•˜์ง€ ์•Š์œผ๋ฉด ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์š”์ฆ˜ ์ข€ ๋ฐ”๋น ์„œ SelectEventPlugin-test ๋ฐ›์•„์ค„ ์ˆ˜ ์žˆ๋Š” ์‚ฌ๋žŒ์ด ์žˆ์–ด์„œ ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ๋ณ€๊ฒฝ ์‚ฌํ•ญ๊ณผ ํ•จ๊ป˜ ๋‹ค๋ฃจ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋” ์ด์ƒ ReactDOMServerIntegration-test (cc @minerado)๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

@aqumus ๊ท€ํ•˜์˜ ๋ถ„์„์— ๋”ฐ๋ผ ์ด ๋ชฉ๋ก์—์„œ EventPluginRegistry-test.js ์„ ์ œ๊ฑฐํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด๊ฒƒ์„ ํŠน์ • ๋‚ด๋ถ€์˜ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋กœ ์œ ์ง€ํ•  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ ์‹ค์ œ ๋…ผ๋ฆฌ๊ฐ€ ๋‹ค๋ฅธ ํ…Œ์ŠคํŠธ์— ํฌํ•จ๋œ๋‹ค๋Š” ๊ฒƒ์„ ์•„๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

@king0120 @aarboleda1 ์ด https://github.com/facebook/react/pull/11631 ์—์„œ ๋งค์šฐ ๊ด€๋ จ๋œ ํ…Œ์ŠคํŠธ๋ฅผ ํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— getEventCharCode-test ๋ฅผ ๋‹ค์‹œ ํ• ๋‹นํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ํ•จ๊ป˜ ํ•˜๋Š” ๊ฒƒ์ด ๋” ์‰ฌ์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@morajabi @gaearon SelectEventPlugin-test.js๋„ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

@email2vimalraj ์ฐธ๊ณ ๋กœ inputValueTracking-test ๋ฅผ ๋‹ค์‹œ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด ํ…Œ์ŠคํŠธ์—๋Š” ํ˜„์žฌ ์†Œ์œ ์ž๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

  • [ ] getNodeForCharacterOffset-test.js (3/5) @accordeiro ์ดฌ์˜
  • [ ] ReactBrowserEventEmitter-test.js (5/5) @madeinfree ์ดฌ์˜
  • [ ] BeforeInputEventPlugin-test.js + FallbackCompositionState-test.js (5/5, ๊ฒฐํ•ฉ๋˜์–ด์•ผ ํ•จ) @GordyD๊ฐ€ ๊ฐ€์ ธ์˜ด
  • [x] SelectEventPlugin-test (2/5) @skiritsis ์ดฌ์˜
  • [x] ReactTreeTraversal-test.js (4/5) @timjacobi ์ดฌ์˜

๋‚˜๋Š” ๊ทธ๋“ค์˜ ์–ด๋ ค์›€์— ๋Œ€ํ•œ ๋‚˜์˜ ์ธ์‹์— ๋”ฐ๋ผ ๊ทธ๊ฒƒ๋“ค์„ ๋ถ„๋ฅ˜ํ–ˆ๋‹ค.

@timjacobi @kwnccc @skiritsis ๊ฐ€ ์žˆ๋Š” ๋Œ€๊ธฐ์—ด์ด ์žˆ์œผ๋ฏ€๋กœ ์ด ํ…Œ์ŠคํŠธ ์ค‘ ํ•˜๋‚˜๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ณ  ์‹ถ์€์ง€ ์„ธ ๋ถ„ ์ค‘ 3๋ช…์—๊ฒŒ ์•Œ๋ ค์ฃผ์‹ญ์‹œ์˜ค. ๋‹น์‹ ์€ ๋˜ํ•œ ํ†ต๊ณผํ•  ์ˆ˜ ์žˆ๊ณ  ์šฐ๋ฆฌ๋Š” ๋‹ค๋ฅธ ์‚ฌ๋žŒ์ด ์‹œ๋„ํ•˜๋„๋ก ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด๊ฒƒ๋“ค์€ ๊ฝค ๋ณต์žกํ•ด์ง€๊ธฐ ๋•Œ๋ฌธ์— ์ดˆ๋ณด์ž์—๊ฒŒ ์นœ์ˆ™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ๋“ค์€ ๊ธฐ๊ณ„์  ๋Œ€์ฒดํ’ˆ์ด ์•„๋‹™๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ๊ฐ€ ๋ฌด์—‡ ์„ ํ™•์ธํ•˜๋ ค๊ณ  ํ•˜๋Š”์ง€ ์ดํ•ดํ•˜๊ณ  ๊ทธ์— ์ƒ์‘ํ•˜๋Š” ๊ณต๊ฐœ API ํ…Œ์ŠคํŠธ(๋งค์šฐ ๋‹ค๋ฅด๊ฒŒ ๋ณด์ผ ์ˆ˜ ์žˆ์Œ)๋ฅผ ์ œ์‹œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด๋ฅผ ๊ฐ€์ ธ์˜ค๋ ค๋ฉด https://github.com/facebook/react/pull/11383 ์—์„œ @GordyD ๊ฐ€ ํ–ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ ์Šค์Šค๋กœ ํŽธ์•ˆํ•˜๊ฒŒ ์กฐ์‚ฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์‹ค @GordyD ๊ฐ€ ์ด ์ค‘ ํ•˜๋‚˜๋ฅผ ๊ฐ€์ง€๊ณ  ์‹ถ์–ดํ•œ๋‹ค๋ฉด ๊ธฐ๊บผ์ด ๊ทธ์—๊ฒŒ ์ค„ ๊ฒƒ์ž…๋‹ˆ๋‹ค!

@skiritsis ๊ด€์‹ฌ์„ ๊ฐ€์ ธ์ฃผ์…”์„œ SelectEventPlugin-test ์„ ๋‹ค์‹œ ํ• ๋‹นํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ReactBrowerEventEmitter-test.js์—์„œ ์ผํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค ๐Ÿ’ช

@gaearon : ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค, ์ œ๋•Œ ์‘๋‹ตํ•˜์ง€ ๋ชปํ•ด ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์ผ๋กœ ๋ฐ”๋นด๋‹ค. ์ดํ•ด๋ฅผ ๋•๊ธฐ ์œ„ํ•ด ์–ด๋–ป๊ฒŒ ๋‹ค์‹œ ์ž‘์„ฑํ–ˆ๋Š”์ง€ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

ReactTreeTraversal-test.internal.js ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@madeinfree @kwnccc ๊ฐ€ ์ด๋ฏธ ๋Œ€๊ธฐ์—ด์— ์žˆ์œผ๋ฏ€๋กœ ๋จผ์ € ์‘๋‹ตํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ฉฐ์น ์„ ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฐ€ ๊ด€์‹ฌ์ด ์—†๋‹ค๋ฉด ๋‚˜์ค‘์— ๋‹น์‹ ์—๊ฒŒ ํ• ๋‹นํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

@gaearon OK! ์•Œ๊ฒ ์Šต๋‹ˆ๋‹ค~ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค

@gaearon ๋‹ค๋ฅธ ํ…Œ์ด์ปค ๊ฐ€ ์—†์œผ๋ฉด BeforeInputEventPlugin + FallbackCompositionState ์กฐํ•ฉ์„ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์ข‹์€ ์†Œ๋ฆฌ, ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค @GordyD!

๊ทธ๊ฑด ๊ทธ๋ ‡๊ณ , ์ด ์ฝ”๋“œ๊ฐ€ ์ผ๋ฐ˜์ ์œผ๋กœ ์–ด๋–ป๊ฒŒ ๋˜๋Š”์ง€์— ๋Œ€ํ•œ ์•„์ด๋””์–ด๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ๋ณ€ํ™˜๋œ ๋ช‡ ๊ฐ€์ง€ ์ด๋ฒคํŠธ ํ…Œ์ŠคํŠธ๊ฐ€ ๋” ์žˆ์Šต๋‹ˆ๋‹ค. https://github.com/facebook/react/pull/11631 https://github. com/facebook/react/pull/11525

@gaearon ๋‹ค๋ฅธ ์‚ฌ๋žŒ์ด ์›ํ•˜์ง€ ์•Š์œผ๋ฉด ReactBrowserEventEmitter-test.js ๋„ ๊ฐ€์ ธ๊ฐ€๊ฒŒ ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค.

@madeinfree

์—ฌ์ „ํžˆ ReactBrowerEventEmitter ์— ๊ด€์‹ฌ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๊ทธ๋ ‡๋‹ค๋ฉด, ๊ทธ๊ฒƒ์„ ๊ฐ€์ง€๊ณ  ์šฐ๋ฆฌ์—๊ฒŒ ์ตœ์‹  ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜์‹ญ์‹œ์˜ค!

@gaearon OK! ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ๊ฐ€์ง€๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

๋งž์•„์š”.

๋‚˜๋จธ์ง€ getNodeForCharacterOffset-test ๊ฐ€์ ธ๊ฐ€์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

์ด ๋ฌธ์ œ๋ฅผ ๋„์™€๋“œ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค( getNodeForCharacterOffset-test ) :)

@gaearon ์ƒ๊ฐํ–ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ ReactIncrementalPerf-test.js ์— ๋›ฐ์–ด๋“ค ์‹œ๊ฐ„์ด ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๋„ˆ๋ฌด ์˜ค๋ž˜ ๋ถ™์žก์•„์„œ ๋ฏธ์•ˆํ•˜์ง€๋งŒ ์›ํ•˜๋Š” ์‚ฌ๋žŒ์ด ์žˆ๋‹ค๋ฉด ์žก์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!

@accordeiro ์•Œ์•˜ ์Šต๋‹ˆ๋‹ค!

@gaearon ์ •๋ง ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค, ์•Œ๋ฆผ์„๋ฐ›์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ์•„์ง ์ฒ˜๋ฆฌํ•ด์•ผ ํ•  ๋ช‡ ๊ฐ€์ง€ ํ…Œ์ŠคํŠธ๊ฐ€ ์žˆ์œผ๋ฉด ์•Œ๋ ค์ฃผ์‹ญ์‹œ์˜ค. ์‹œ์ž‘ํ•˜๊ธฐ ์‰ฌ์šด ๊ฒƒ์ด ๋‚จ์•„ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

@kwnccc ReactIncrementalPerf-test.js ๋ฅผ ์‚ดํŽด๋ณด๊ณ  ์‹ถ์Šต๋‹ˆ๊นŒ?

ReactIncrementalPerf-test.js ์„(๋ฅผ) ์กฐ์‚ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๋˜๋Š” ํ•„์š”ํ•œ ๊ฒฝ์šฐ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐ @kwnccc ๋ฅผ ๋„์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ReactIncrementalPerf.js ๋ผ๋Š” ํŒŒ์ผ์ด ํ‘œ์‹œ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ReactPortal.js ์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

ReactIncrementalPerf-test.js ์˜ ๋ฌธ์ œ๋ฅผ ์กฐ๊ธˆ์ด๋ผ๋„ ์ดํ•ดํ–ˆ๋‹ค๋ฉด(์ž˜๋ชป๋œ ๊ฒฝ์šฐ ์ˆ˜์ •) ReactPortal.createPortal(...)์—์„œ ReactDOM์ด ์žˆ๋Š” react-dom๊ณผ ๊ฐ™์€ ๊ณต๊ฐœ API๋กœ ์ „ํ™˜ํ•ด์•ผ ํ•จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. .createPortal(...) ? @gaearon

@gaearon ์ •๋ง ReactIncrementalPerf-test.js ํ•ด๋ณด๊ณ  ์‹ถ์–ด์š”. @abiduzz420 ์ด ํ™•์ธ์„ ์‹œ์ž‘ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ํ•„์š”ํ•œ ๊ฒฝ์šฐ ํŒ€์„ ๊ตฌ์„ฑํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

๋„ค ๋ฌผ๋ก  @kwnccc ํ•จ๊ป˜ ์ผํ•˜๊ฒŒ ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค. ๋‹น์‹ ์€ ๋‚˜๋ณด๋‹ค ๋จผ์ € ๋Œ€๊ธฐ์—ด์— ์žˆ์—ˆ๊ณ , ๊ทธ๋ž˜์„œ ๋ชจ๋‘ ๋‹น์‹ ์˜ ๊ฒƒ์ž…๋‹ˆ๋‹ค!

@kwnccc yarn test ์—์„œ ํ•˜๋‚˜์˜ ํ…Œ์ŠคํŠธ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ  $ yarn flow ์‹คํ–‰ํ•  ๋•Œ Flow ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋‹น์‹ ์ด ์ž‘์—…ํ•  ์ˆ˜ ์žˆ๋„๋ก https://github.com/abiduzz420/react ๋‚ด fork repo์— ์ฝ”๋“œ๋ฅผ ํ‘ธ์‹œํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 FAIL  packages\react-reconciler\src\__tests__\ReactIncrementalPerf-test.internal.js (11.191s)
  โ— ReactDebugFiberPerf โ€บ supports portals

    Invariant Violation: Target container is not a DOM element.

      at invariant (node_modules/fbjs/lib/invariant.js:42:15)
      at Object.createPortal (packages/react-dom/src/client/ReactDOM.js:1112:70)
      at Object.<anonymous> (packages/react-reconciler/src/__tests__/ReactIncrementalPerf-test.internal.js:510:116)
$ yarn flow
yarn run v1.3.2
$ node ./scripts/tasks/flow.js
Error: packages/react-reconciler/src/ReactFiberHostContext.js:87
 87:     const nextContext = getChildHostContext(context, fiber.type, rootInstance);
                                                 ^^^^^^^ NoContextT. This type is incompatible with the expected param type of
                    v---------------------------------------------
 31: export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
 32:   config: HostConfig<T, P, I, TI, HI, PI, C, CC, CX, PL>,
 33: ): HostContext<C, CX> {
     --------------------^ some incompatible instantiation of `CX`

Error: packages/react-reconciler/src/ReactFiberHostContext.js:87
 87:     const nextContext = getChildHostContext(context, fiber.type, rootInstance);
                                                                      ^^^^^^^^^^^^ NoContextT. This type is incompatible with the expected param type of
                    v---------------------------------------------
 31: export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
 32:   config: HostConfig<T, P, I, TI, HI, PI, C, CC, CX, PL>,
 33: ): HostContext<C, CX> {
     --------------------^ some incompatible instantiation of `C`
Found 2 errors
Flow failed
error Command failed with exit code 2.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

@abiduzz420 ํ๋ฆ„ ๋ฌธ์ œ๋Š” Windows์—์„œ ์•Œ๋ ค์ง„ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ๊ด€๋ จ์ด ์—†์Šต๋‹ˆ๋‹ค(๊ทธ๋Ÿฌ๋‚˜ ์šฐ๋ฆฌ๋Š” ๊ทธ๊ฒƒ์ด ์™œ ์ผ์–ด๋‚˜๋Š”์ง€ ์•Œ์•„๋‚ด์•ผ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค). https://github.com/facebook/react/issues/11703์„ ์ฐธ์กฐํ•˜์„ธ์š”.

@kwnccc ReactIncrementalPerf-test ์˜ ๊ฒฝ์šฐ ์˜ˆ, ์•ฝ๊ฐ„์˜ ์ƒ๊ฐ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด ์‹œ์ ์—์„œ ์ผ์‹œ์ ์œผ๋กœ ReactPortal ์„ shared ๋กœ ์ด๋™ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ข‹์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ReactNoop ๊ฐ€ ์ž์ฒด createPortal() ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค( ReactDOM ์ฒ˜๋Ÿผ).

ํ•˜๋‚˜ ๋” ๋‹ค์šด! https://github.com/facebook/react/issues/11299

@gaearon ReactPortal์„ ๊ณต์œ  ๋””๋ ‰ํ† ๋ฆฌ๋กœ ์˜ฎ๊ฒผ๊ณ  ๋ชจ๋“  ํ…Œ์ŠคํŠธ๋ฅผ ํ†ต๊ณผํ–ˆ์Šต๋‹ˆ๋‹ค. ReactNoop $์— ๋Œ€ํ•œ ๋‚ด ์ž์‹ ์˜ ๋ฐฉ๋ฒ• createPortal() ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ ์•ฝ๊ฐ„์˜ ๋„์›€์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. createPortal() ๊ฐ€ ReactDOM ์— ์–ด๋–ป๊ฒŒ ์“ฐ์—ฌ ์žˆ๋Š”์ง€์—์„œ ์˜๊ฐ์„ ๋ฐ›์•„ ReactPortal.createPortal(children,container,null,key) ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.
๋‚˜๋Š” ๋‹ค์Œ ๋ผ์ธ์— ๋Œ€ํ•ด ์ƒ๊ฐํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

function createPortal( children: ReactNodeList, container: Container, key: ?string = null) {
invariant( 
// TODO: Need to figure out this part of the code
);
return ReactPortal.createPortal(children, container, null, key);
}

๋‚ด๊ฐ€ ์ œ๋Œ€๋กœ ํ•˜๊ณ  ์žˆ๋Š”์ง€ ์•Œ๋ ค์ฃผ์„ธ์š”?

@gaearon ๋‚ด ์ฝ”๋“œ๋Š” ์—ฌ์ „ํžˆ wip์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋‚ด๊ฐ€ ์˜ฌ๋ฐ”๋ฅธ ๊ธธ์„ ๊ฐ€๊ณ  ์žˆ๋Š”์ง€ ๋‹ค์‹œ ํ™•์ธํ•˜๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค. ๋‚ด ์ฝ”๋“œ๋ฅผ ๋น ๋ฅด๊ฒŒ ์‚ดํŽด๋ณด๊ณ  ๋ช‡ ๊ฐ€์ง€ ์˜์‹ฌ์„ ๋ช…ํ™•ํžˆ ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ •๋ง ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

  1. ๋‚ด๊ฐ€ ์ทจํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์ด ์˜ฌ๋ฐ”๋ฅธ๊ฐ€์š”?
  2. ํ…Œ์ŠคํŠธ๊ฐ€ ๊ธฐ์กด์—์„œ ํ…Œ์ŠคํŠธ๋œ ๋ชจ๋“  ํƒœ๊ทธ์™€ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ๋‹ค๋ฃจ์–ด์•ผ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.
    ํ…Œ์ŠคํŠธ ์ปค๋ฒ„๋ฆฌ์ง€๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ํ…Œ์ŠคํŠธ. ์ด๋Ÿฌํ•œ ํŠน์ˆ˜ ๋ฐ ํ˜•์‹ ์ง€์ • ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋™์ ์œผ๋กœ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์„ ๋‹ฌ์„ฑํ•˜๋Š” ํšจ์œจ์ ์ธ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๋ช‡ ๊ฐ€์ง€ ์ง€์นจ์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?
  3. isTagValidInContext() ๋ฉ”์„œ๋“œ๊ฐ€ ํ…Œ์ŠคํŠธ ํŒŒ์ผ ์ด์™ธ์˜ ๋‹ค๋ฅธ ๊ณณ์—์„œ๋Š” ์‚ฌ์šฉ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๊ณต๊ฐœ API๋กœ '๋ชจ๋“  ํƒœ๊ทธ ์—†์Œ ์ปจํ…์ŠคํŠธ' ํ…Œ์ŠคํŠธ์˜ '์ปจํ…์ŠคํŠธ ์—†์Œ' ๋ถ€๋ถ„์„ ํ…Œ์ŠคํŠธํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ์–ด๋–ค ์•„์ด๋””์–ด?

@abiduzz420 ๋„ค ๋งž์•„์š”

@anushreesubramani

๋‚ด๊ฐ€ ์ทจํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์ด ์˜ฌ๋ฐ”๋ฅธ๊ฐ€์š”?

์ผ๋ฐ˜์ ์œผ๋กœ ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์šฐ๋ฆฌ๋Š” ๊ฑฐ๊ธฐ์—์„œ ์ค‘๋ณต์„ ํ”ผํ•˜๊ธฐ๋ฅผ ์›ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด์ƒ์ ์œผ๋กœ๋Š” ์ผ๋ จ์˜

expect(isTagStackValid(['a', 'a'])).toBe(false);

์ผ๋ จ์˜

expectInvalidNestingWarning(true, ['a', 'a']);

์—ฌ๊ธฐ์„œ expectInvalidNestingWarning ๋Š” ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์ƒ์„ฑํ•œ ๋‹ค์Œ ์ด๋ฅผ ๋ Œ๋”๋งํ•˜๋ฉด ๊ฒฝ๊ณ ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค๊ณ  ์ฃผ์žฅํ•˜๋Š” ์‚ฌ์šฉ์ž ์ •์˜ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ํŠน์ˆ˜ ๋ฐ ํ˜•์‹ ์ง€์ • ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋™์ ์œผ๋กœ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์„ ๋‹ฌ์„ฑํ•˜๋Š” ํšจ์œจ์ ์ธ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๋ช‡ ๊ฐ€์ง€ ์ง€์นจ์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

์˜ˆ, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ƒ๊ฐํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

function expectInvalidNestingWarning(shouldWarn, tags) {
  let element = null;
  tags = [...tags];
  while (tags.length) {
    element = React.createElement(tags.pop(), null, element);
  }
  const container = document.createElement('div');
  ReactDOM.render(element, container);
  // assert either a warning or lack of one based on shouldWarn
}

๋ฐฐ์—ด์„ ์‚ดํŽด๋ณด๊ณ  ๋งˆ์ง€๋ง‰ ํ•ญ๋ชฉ์„ ์„ ํƒํ•˜๊ณ  ํ˜„์žฌ ์š”์†Œ๋ฅผ ํ•ด๋‹น ํƒœ๊ทธ๊ฐ€ ์žˆ๋Š” ์ƒ์œ„ ์š”์†Œ๋กœ ๋ž˜ํ•‘ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ฒฐ๊ตญ ํ•ด๋‹น ํŠธ๋ฆฌ๊ฐ€ ์™„์„ฑ๋ฉ๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ๋ญ”๊ฐ€๋ฅผ ์ž˜๋ชป ์ผ์„ ์ˆ˜๋„ ์žˆ์ง€๋งŒ ๊ทธ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ธ ์ƒ๊ฐ์ž…๋‹ˆ๋‹ค.

๋‹น์‹ ์€ ๋˜ํ•œ ์•„๋งˆ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒƒ์„ ๋„ฃ๊ณ  ์‹ถ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค

jest.resetModules();
React = require('react');
ReactDOM = require('react-dom');

๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๊ฒฝ๊ณ ๊ฐ€ ์ค‘๋ณต ์ œ๊ฑฐ๋  ์ˆ˜ ์žˆ๊ณ  ์•ˆ์ •์ ์œผ๋กœ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

isTagValidInContext() ๋ฉ”์„œ๋“œ๊ฐ€ ํ…Œ์ŠคํŠธ ํŒŒ์ผ ์ด์™ธ์˜ ๋‹ค๋ฅธ ๊ณณ์—์„œ๋Š” ์‚ฌ์šฉ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๊ณต๊ฐœ API๋กœ '๋ชจ๋“  ํƒœ๊ทธ ์—†์Œ ์ปจํ…์ŠคํŠธ' ํ…Œ์ŠคํŠธ์˜ '์ปจํ…์ŠคํŠธ ์—†์Œ' ๋ถ€๋ถ„์„ ํ…Œ์ŠคํŠธํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋น„๋‚œ์„ ๋ณด๋ฉด https://github.com/facebook/react/commit/76bb96ef21b7c665e1b51b6bb90e64ec40c0f16a ์— ์ถ”๊ฐ€๋˜์—ˆ๊ณ  ๊ทธ ์‹œ์ ์—์„œ ํ…Œ์ŠคํŠธ ์™ธ๋ถ€์—์„œ๋„ ํ˜ธ์ถœ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ฏธ๋ž˜์˜ ์–ด๋Š ์‹œ์ ์—์„œ ๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ๋Š” ์„œ๋ฒ„ ๋ Œ๋”๋ง์„ ์–ธ๊ธ‰ํ•ฉ๋‹ˆ๋‹ค.

https://github.com/facebook/react/blob/8cbc16f0faedafe4f7424b286af52dafd7a79587/packages/react-dom/src/__tests__/validateDOMNesting-test.internal.js#L144 -L145

๊ทธ๋Ÿฌ๋‚˜ ์ด ๊ธฐ๋Šฅ์€ ๋” ์ด์ƒ ์„œ๋ฒ„ ๋ Œ๋”๋ง์—์„œ๋„ ์‚ฌ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด ์˜๊ฒฌ์—์„œ ๋‚˜๋Š” ๋ชฉํ‘œ๊ฐ€ ์กฐ์ƒ์„ ๋ชจ๋ฅผ ๋•Œ ๊ฒฐ์ฝ” ๊ฒฝ๊ณ ํ•˜์ง€ ์•Š๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ null ๋ฅผ ancestorInfo ๋กœ validateDOMNesting ๋กœ ์ „๋‹ฌํ•˜๋Š” ์ฝ”๋“œ ๊ฒฝ๋กœ๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ ์šฐ๋ฆฌ๋Š” ์•„๋งˆ๋„ ํ•ญ์ƒ ํ˜„์žฌ ๋ฒ„์ „์˜ ์กฐ์ƒ์„ ์•Œ๊ณ  ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด ํ…Œ์ŠคํŠธ๋ฅผ ์™„์ „ํžˆ ์‚ญ์ œํ•˜๋Š” ๊ฒƒ์ด ์•ˆ์ „ํ•˜๋‹ค๊ณ  ๋งํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

@gaearon ReactNoop.js createPortal() ๋ฉ”์†Œ๋“œ๋ฅผ ์ƒ์„ฑํ–ˆ๊ณ  ๊ทธ ์ „์— ์ œ์•ˆํ•œ ๋Œ€๋กœ ReactPortal.js ํŒŒ์ผ๋„ ๊ณต์œ  ๋””๋ ‰ํ† ๋ฆฌ๋กœ ์ด๋™ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚ด ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด๊ณ  ์ˆ˜์ •ํ•˜๊ฑฐ๋‚˜ ์ถ”๊ฐ€ํ•ด์•ผ ํ•  ์‚ฌํ•ญ์ด ์žˆ์œผ๋ฉด ์ˆ˜์ •ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

PR ์ข€ ๋ณด๋‚ด์ฃผ์‹ค ์ˆ˜ ์žˆ๋‚˜์š”? ๋ฆฌ๋ทฐ์—์„œ ๋…ผ์˜ํ•˜๋Š” ๊ฒƒ์ด ๋” ์‰ฝ์Šต๋‹ˆ๋‹ค.

@abiduzz420 ์ •๋ง ์ž˜ํ•˜์‹  ๊ฒƒ ๊ฐ™์€๋ฐ์š”, ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค๋งŒ ์˜ค๋Š˜๊นŒ์ง€ ์ž‘์—…์„ ์‹œ์ž‘ํ•  ์‹œ๊ฐ„์ด ์—†์—ˆ์Šต๋‹ˆ๋‹ค! ํ…Œ์ŠคํŠธ๋ฅผ ์™„๋ฃŒํ•  ์ˆ˜ ์žˆ์–ด์„œ ์ •๋ง ๊ธฐ๋ปค์Šต๋‹ˆ๋‹ค! ๐Ÿ‘๐Ÿ‘
@gaearon next ๊ผญ ์ข‹์€ ๋งค๋ฌผ ํ™•๋ณดํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค

@gaearon ๋น ๋ฅธ ์—…๋ฐ์ดํŠธ: BeforeInputEventPlugin + FallbackCompositionState ํ…Œ์ŠคํŠธ๋ฅผ ๋ฆฌํŒฉํ† ๋ง/๊ฒฐํ•ฉํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ณต๊ฐœ API๋ฅผ ํ†ตํ•ด ๊ตฌํ˜„์„ ํ…Œ์ŠคํŠธํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ž˜ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ์€ ๋‹ค๋ฅธ ์‹คํ–‰ ํ™˜๊ฒฝ/๋ธŒ๋ผ์šฐ์ € ์—”์ง„์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ์ฝ”๋“œ ๊ฒฝ๋กœ๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋ฅผ ๋งŒ๋“œ๋Š” ์ž‘์—…์„ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ์ฃผ ๋ง์— ์ฒซ ๋ฒˆ์งธ PR์ด ์žˆ์„ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•ฉ๋‹ˆ๋‹ค(12์›” 10์ผ๊นŒ์ง€ ์—…๋ฐ์ดํŠธ๋จ - ์‹œ๊ฐ„์ด ์กฐ๊ธˆ ๋” ํ•„์š”ํ•จ - 12์›” 12์ผ ๊ธฐ์ค€).

์ข‹์•„์š”, ์—…๋ฐ์ดํŠธํ•ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

@gaearon ๋น ๋ฅธ ์—…๋ฐ์ดํŠธ: ์ด๋ฏธ getNodeForCharacterOffset-test ์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ๋ฅผ ๋‹ค์‹œ ์ž‘์„ฑํ•˜๋Š” ์ž‘์—…์„ ์‹œ์ž‘ํ–ˆ์œผ๋ฉฐ ๋ชฉ์š”์ผ๊นŒ์ง€ PR์„ ํ‘ธ์‹œํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ดœ์ฐฎ์Šต๋‹ˆ๊นŒ?

์ข‹์€ ์†Œ๋ฆฌ

ํ•˜๋‚˜ ๋” ๋‹ค์šด! https://github.com/facebook/react/pull/11742

@reznord ์•„์ง ์†Œ์‹์ด ์—†์Šต๋‹ˆ๋‹ค. ์‹œ์ž‘ํ•˜์…จ๋‚˜์š”? ๋„ˆ๋ฌด ๋ฐ”์˜๋‹ค๋ฉด ๋‹ค๋ฅธ ์‚ฌ๋žŒ์—๊ฒŒ ์‹œ๋„ํ•ด ๋ณผ ๊ธฐํšŒ๋ฅผ ์ฃผ๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

ํ•‘ @reznord

@gaearon๋‹˜ , ์ฒซ ๊ธฐ๋ถ€๋กœ ReactErrorUtils-test.js ๋ฅผ ๋ฐ›์•„๋„ ๋ ๊นŒ์š”?

์•ˆ๋…•ํ•˜์„ธ์š” @gaearon ReactErrorUtils-test.js ๋กœ ํ•  ์ˆ˜ ์žˆ๋Š” ์ผ์ด ์žˆ๋‚˜์š”?

์•ˆ๋…•ํ•˜์„ธ์š”, ์•„๋ฌด๋„ ์ œ๊ฐ€ ReactBrowserEventEmitter-test.js ํ…Œ์ŠคํŠธ๋ฅผ ๊ณ„์†ํ•˜๋„๋ก ๋„์™€์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ์ง€๊ธˆ์€ ๋ฐ”๋น ์„œ ๊ณ„์†ํ•  ์‹œ๊ฐ„์ด ์—†์œผ๋‹ˆ PR์€ https://github.com/facebook/react/pull/11713 ์ž…๋‹ˆ๋‹ค. ์ •๋ง ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!!

๋‹ค์‹œ ํ•œ ๋ฒˆ ๋ชจ๋“  ๋ถ„๋“ค๊ป˜ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค! ์•„์ง ๋ช‡ ๊ฐ€์ง€ ๋ฏธํ•ด๊ฒฐ ํ…Œ์ŠคํŠธ๊ฐ€ ์žˆ์ง€๋งŒ ์ข…๋ฃŒํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

@gaearon : ReactErrorUtils-test.js ์ž‘์—…ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ํ”ฝ์—…ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธํ•ด ์ค„ ์ˆ˜ ์žˆ๋‹ˆ?

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰