์ด๊ฒ์ ์ฃผ์ #7249๋ฅผ ์๋ฏธํฉ๋๋ค. ์ด ๋ฌธ์๋ React๊ฐ ์ฌ์ฉ์ ์ ์ ์์์ ์์ฑ๊ณผ ์์ฑ์ ์ฒ๋ฆฌํ๋ ๋ฐ ์ฌ์ฉํ ์ ์๋ ๋ค์ํ ์ ๊ทผ ๋ฐฉ์์ ์ฅ๋จ์ ์ ์ค๋ช ํฉ๋๋ค.
React๋ ์ฌ์ฉ์ ์ ์ ์์์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ค๊ณ ํ ๋ ํญ์ HTML ์์ฑ์ ์ฌ์ฉํ์ฌ ์ ๋ฌํฉ๋๋ค.
<x-foo bar={baz}> // same as setAttribute('bar', baz)
์์ฑ์ ๋ฌธ์์ด๋ก ์ง๋ ฌํ๋์ด์ผ ํ๋ฏ๋ก ์ด ์ ๊ทผ ๋ฐฉ์์ ์ ๋ฌ๋๋ ๋ฐ์ดํฐ๊ฐ ๊ฐ์ฒด ๋๋ ๋ฐฐ์ด์ธ ๊ฒฝ์ฐ ๋ฌธ์ ๋ฅผ ์์ฑํฉ๋๋ค. ์ด ์๋๋ฆฌ์ค์์๋ ๋ค์๊ณผ ๊ฐ์ด ๋๋ฉ๋๋ค.
<x-foo bar="[object Object]">
์ด์ ๋ํ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ref
๋ฅผ ์ฌ์ฉํ์ฌ ์์ฑ์ ์๋์ผ๋ก ์ค์ ํ๋ ๊ฒ์
๋๋ค.
<x-foo ref={el => el.bar = baz}>
์ด ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ค๋๋ ์ ๊ณต๋๋ ๋๋ถ๋ถ์ ์ฌ์ฉ์ ์ง์ ์์๊ฐ ๋ ธ์ถ๋ ๋ชจ๋ ์์ฑ์ ์ง์ํ๋ JavaScript ์์ฑ์ ์๋์ผ๋ก ์์ฑํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก ์์ฑ๋์๊ธฐ ๋๋ฌธ์ ์ฝ๊ฐ ๋ถํ์ํ๊ฒ ๋๊ปด์ง๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ฐ๋๋ผ ์ฌ์ฉ์ ์ ์ ์์๋ฅผ ์๋์ผ๋ก ์์ฑํ๋ ์ฌ๋๋ ์ด ๋ฐฉ๋ฒ์ ๋ฐ๋ฅด๋ ๊ฒ์ด
์ด ๋ฌธ์๋ ์ด๋ฅผ ๊ฐ๋ฅํ๊ฒ ํ๊ธฐ ์ํด ์ด๋ป๊ฒ React๋ฅผ ์ ๋ฐ์ดํธํ ์ ์๋์ง์ ๋ํ ๋ช ๊ฐ์ง ์ ์์ ๊ฐ๋ตํ๊ฒ ์ค๋ช ํฉ๋๋ค.
์์ฑ์ด๋ ์์ฑ์ ์ค์ ํด์ผ ํ๋์ง ๊ฒฐ์ ํ๋ ๋์ React๋ ํญ์ ์ฌ์ฉ์ ์ ์ ์์์ ์์ฑ์ ์ค์ ํ ์ ์์ต๋๋ค. React๋ ์์ฑ์ด ์์์ ๋ฏธ๋ฆฌ ์กด์ฌํ๋์ง ํ์ธ ํ์ง ์์ต๋๋ค .
์์:
<x-foo bar={baz}>
์์ ์ฝ๋๋ React๊ฐ x-foo
์์์ .bar
์์ฑ์ baz
๊ฐ๊ณผ ๋์ผํ๊ฒ ์ค์ ํ๋๋ก ํฉ๋๋ค.
camelCased ์์ฑ ์ด๋ฆ์ ๊ฒฝ์ฐ React๋ ํ์ฌ tabIndex
๊ฐ์ ์์ฑ์ ์ฌ์ฉํ๋ ๊ฒ๊ณผ ๋์ผํ ์คํ์ผ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
<x-foo squidInk={pasta}> // sets .squidInk = pasta
์ด ๋ชจ๋ธ์ ๋จ์ํ๊ณ ๋ช ์์ ์ด๋ฉฐ React์ "JavaScript-centric API to DOM" ๊ณผ ๋ฐ์ ํ๊ฒ ์ฐ๊ด
Polymer ๋๋ Skate์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก ์์ฑ๋ ๋ชจ๋ ์์๋ ๋
ธ์ถ๋ ์์ฑ์ ๋ท๋ฐ์นจํ๋ ์์ฑ์ ์๋์ผ๋ก ์์ฑํฉ๋๋ค. ์ด๋ฌํ ์์๋ ๋ชจ๋ ์์ ์ ๊ทผ ๋ฐฉ์์ผ๋ก "์ ์ ์๋"ํด์ผ ํฉ๋๋ค. ๋ฐ๋๋ผ ๊ตฌ์ฑ ์์๋ฅผ ์ง์ ์์ฑํ๋ ๊ฐ๋ฐ์๋ ์์ฑ์ ์ฌ์ฉํ์ฌ ์์ฑ ์ ์ง์ํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ์ด๋ HTML5 ์์( <video>
, <audio>
๋ฑ)๊ฐ ์ผ๋ง๋ ํ๋์ ์ธ์ง (์ฆ, <input>
์ ๊ฐ์ ์ด์ํ ๊ฒ์ด ์๋)์ ๋ฐ์ํ๊ธฐ ๋๋ฌธ์
๋๋ค. ๊ตฌํ๋์์ต๋๋ค.
React๊ฐ ์ฌ์ฉ์ ์ ์ ์์์ ์์ฑ์ ์ค์ ํ๋ฉด HTML์ ํฅํ ๋ฒ์ ์ด ๋น์ทํ ์ด๋ฆ์ ์์ฑ์ ์ ๊ณตํ์ฌ ๋ฌธ์ ๋ฅผ ์ผ์ผํฌ ์ํ์ด ํญ์ ์์ต๋๋ค. ์ด ๋ฌธ์ ๋ ์ฌ์ ์์ฑ์์ ๋
ผ์ ๋์์ง๋ง ๋ฌธ์ ์ ๋ํ ๋ช
ํํ ํด๊ฒฐ์ฑ
์ ์์ต๋๋ค. ์์ฑ์ ์์ ํ ํผํ๋ฉด(๊ฐ๋ฐ์๊ฐ ref
์ฌ์ฉํ์ฌ ๋ช
์์ ์ผ๋ก ์์ฑ์ ์ค์ ํ๋ ๊ฒฝ์ฐ ์ ์ธ) ๋ธ๋ผ์ฐ์ ๊ฐ ๋ ๋์ ์๋ฃจ์
์ ์ ๊ณตํ ๋๊น์ง ์ด ๋ฌธ์ ๋ฅผ ํผํ ์ ์์ต๋๋ค.
์ฌ์ฉ์ ์ ์ ์์๋ ํ์ด์ง์์ ๋๋ฆฌ๊ฒ ์ ๊ทธ๋ ์ด๋ ๋ ์ ์์ผ๋ฉฐ ์ผ๋ถ PRPL ํจํด์ ์ด ๊ธฐ์ ์ ์์กดํฉ๋๋ค. ์ ๊ทธ๋ ์ด๋ ํ๋ก์ธ์ค ๋์ ์ฌ์ฉ์ ์ ์ ์์๋ React์ ์ํด ์ ๋ฌ๋ ์์ฑ์ ์ก์ธ์คํ ์ ์์ผ๋ฉฐ(ํด๋น ์์ฑ์ด ์ ์๊ฐ ๋ก๋๋๊ธฐ ์ ์ ์ค์ ๋์๋๋ผ๋) ์ด๋ฅผ ์ฌ์ฉํ์ฌ ์ด๊ธฐ ์ํ๋ฅผ ๋ ๋๋งํ ์ ์์ต๋๋ค.
React ๊ตฌ์ฑ ์์๊ฐ ๋ฐ์ดํฐ๋ฅผ ์๋ก ์ ๋ฌํ ๋ ์ด๋ฏธ ์์ฑ์ ์ฌ์ฉํฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์ฌ์ฉ์ ์ง์ ์์๊ฐ ๋์ผํ ๋ฐฉ์์ผ๋ก ์๋ํฉ๋๋ค.
๊ฐ๋ฐ์๊ฐ ์์ฑ API๋ง ์๋ ๋ฐ๋๋ผ ์ฌ์ฉ์ ์ ์ ์์๋ฅผ ์๋์ผ๋ก ์์ฑํ๋ค๋ฉด ์ฝ๋๋ฅผ ์
๋ฐ์ดํธํด์ผ ํ๋ฉฐ ๊ทธ๋ ์ง ์์ผ๋ฉด ์ฑ์ด ์ค๋จ๋ฉ๋๋ค. ์์ ์ฌํญ์ ref
๋ฅผ ์ฌ์ฉํ์ฌ ์์ฑ์ ์ค์ ํ๋ ๊ฒ์
๋๋ค(์๋ ์ค๋ช
์ฐธ์กฐ).
์์ฑ์ด ์ ํธ๋๋๋ก ๋์์ ๋ณ๊ฒฝํ๋ฉด ๊ฐ๋ฐ์๊ฐ ์ฌ์ฉ์ ์ ์ ์์์ ์์ฑ์ ๋ช
์์ ์ผ๋ก ์ค์ ํ๊ธฐ ์ํด ref
๋ฅผ ์ฌ์ฉํด์ผ ํจ์ ์๋ฏธํฉ๋๋ค.
<custom-element ref={el => el.setAttribute('my-attr', val)} />
์ด๊ฒ์ ๊ฐ๋ฐ์๊ฐ ์์ฑ์ ์ค์ ํ๊ธฐ ์ํด ref
๊ฐ ํ์ํ ํ์ฌ ๋์์ ๋ฐ์ ์
๋๋ค. ๊ฐ๋ฐ์๋ ์ฌ์ฉ์ ์ ์ ์์์ ์์ฑ์ ์ค์ ํ ํ์๊ฐ ๊ฑฐ์ ์์ด์ผ ํ๋ฏ๋ก ์ด๋ ํฉ๋ฆฌ์ ์ธ ์ ์ถฉ์์ผ๋ก ๋ณด์
๋๋ค.
์ด ๋ชจ๋ธ์ด ์๋ฒ ์ธก ๋ ๋๋ง ์ฌ์ฉ์ ์ ์ ์์์ ์ด๋ป๊ฒ ๋งคํ๋๋์ง๋ ํ์คํ์ง ์์ต๋๋ค. React๋ ์์ฑ์ด ์ ์ฌํ ์ด๋ฆ์ ์์ฑ์ ๋งคํ๋๋ค๊ณ ๊ฐ์ ํ๊ณ ์๋ฒ์์ ์ค์ ์ ์๋ํ ์ ์์ง๋ง ์ด๊ฒ์ ๋ฐฉํ์ด ์๋๋ฉฐ camelCased ์์ฑ -> dash-cased ์์ฑ๊ณผ ๊ฐ์ ๊ฒ์ ๋ํ ๊ฒฝํ์ ๋ฐฉ๋ฒ์ด ํ์ํ ์ ์์ต๋๋ค.
๋ฐํ์์ React๋ ์ฌ์ฉ์ ์ ์ ์์์ ์์ฑ์ด ์๋์ง ๊ฐ์งํ๋ ค๊ณ ์๋ํ ์ ์์ต๋๋ค. ์์ฑ์ด ์์ผ๋ฉด React๊ฐ ์ด๋ฅผ ์ฌ์ฉํ๊ณ , ๊ทธ๋ ์ง ์์ผ๋ฉด ์์ฑ ์ค์ ์ผ๋ก ๋์ฒดํฉ๋๋ค. ์ด๊ฒ์ Preact๊ฐ ์ฌ์ฉ์ ์ ์ ์์๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐ ์ฌ์ฉํ๋ ๋ชจ๋ธ์ ๋๋ค.
์์ฌ ์ฝ๋ ๊ตฌํ:
if (propName in element) {
element[propName] = value;
} else {
element.setAttribute(propName.toLowerCase(), value);
}
๊ฐ๋ฅํ ๋จ๊ณ:
์์์ ์ ์๋ ์์ฑ์ด ์์ผ๋ฉด React๊ฐ ์ด๋ฅผ ์ฌ์ฉํฉ๋๋ค.
์์์ ์ ์๋์ง ์์ ์์ฑ์ด ์๊ณ React๊ฐ ๊ธฐ๋ณธ ๋ฐ์ดํฐ(๋ฌธ์์ด/์ซ์/๋ถ์ธ)๋ฅผ ์ ๋ฌํ๋ ค๊ณ ํ๋ฉด ์์ฑ์ ์ฌ์ฉํฉ๋๋ค.
์์์ ์ ์๋์ง ์์ ์์ฑ์ด ์๊ณ React๊ฐ ๊ฐ์ฒด/๋ฐฐ์ด์ ์ ๋ฌํ๋ ค๊ณ ํ๋ฉด ์์ฑ์ผ๋ก ์ค์ ๋ฉ๋๋ค. ์ด๊ฒ์ some-attr="[object Object]"๊ฐ ์ ์ฉํ์ง ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
์์๊ฐ ์๋ฒ์์ ๋ ๋๋ง๋๊ณ React๊ฐ ๋ฌธ์์ด/์ซ์/๋ถ์ธ์ ์ ๋ฌํ๋ ค๊ณ ํ๋ฉด ์์ฑ์ ์ฌ์ฉํฉ๋๋ค.
์์๊ฐ ์๋ฒ์์ ๋ ๋๋ง๋๊ณ React๊ฐ ๊ฐ์ฒด/๋ฐฐ์ด์ ์ ๋ฌํ๋ ค๊ณ ํ๋ฉด ์๋ฌด ์์ ๋ ์ํํ์ง ์์ต๋๋ค.
์์ฑ๋ง ์ธํฐํ์ด์ค๋ก ์ฌ์ฉํ๋ ์ฌ์ฉ์ ์ ์ ์์๋ฅผ ์์ฑํ ์ ์์ต๋๋ค. ์ด ์์ฑ ์คํ์ผ์ ๊ถ์ฅ ๋์ง ์์ง๋ง ๊ด๊ณ์์ด ๋ฐ์ํ ์ ์์ต๋๋ค. ์ฌ์ฉ์ ์ ์ ์์ ์์ฑ์๊ฐ ์ด ๋์์ ์์กดํ๋ ๊ฒฝ์ฐ ์ด ๋ณ๊ฒฝ ์ฌํญ์ ์ค์ํ์ง ์์ต๋๋ค.
๊ฐ๋ฐ์๋ React๊ฐ ์์๋ฅผ ๋ก๋ํ๊ธฐ ์ํด ์ ํํ ๋ฐฉ๋ฒ์ ๋ฐ๋ผ ์์ฑ ๋์ ์์ฑ์ ์ค์ ํ ๋ ํผ๋์ค๋ฌ์ธ ์ ์์ต๋๋ค.
Sebastian ์ in
๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์ ์ง์ ์์์ ์์ฑ์ด ์๋์ง ํ์ธํ๋ ๋ฐ ์ค์๋ก ์ํผํด๋์ค(HTMLElement)์ ์์ฑ์ ๊ฐ์งํ ์ ์๋ค๋ ์ฐ๋ ค ๋ฅผ
์ด ๋ฌธ์์ ์ด์ ์
React๋ ์ฌ์ฉ์ ์ ์ ์์์ ๋ํ ์์ฑ์ ๊ณ์ ์ค์ ํ ์ ์์ง๋ง ๊ฐ๋ฐ์๊ฐ ๋์ ๋ช ์์ ์ผ๋ก ์์ฑ์ ์ค์ ํ๋ ๋ฐ ์ฌ์ฉํ ์ ์๋ ์ธ์ฅ์ ์ ๊ณตํฉ๋๋ค. ์ด๊ฒ์ Glimmer.js์์ ์ฌ์ฉํ๋ ์ ๊ทผ ๋ฐฉ์ ๊ณผ ์ ์ฌํฉ๋๋ค.
ํฌ๋ฏธํ ์:
<custom-img @src="corgi.jpg" @hiResSrc="[email protected]" width="100%">
์์ ์์์ @ sigil์ src
๋ฐ hiResSrc
๊ฐ ์์ฑ์ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์ ์ ์ ์์์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๊ณ width
๊ฐ ์์ฑ ๋ฌธ์์ด๋ก ์ง๋ ฌํ๋์ด์ผ ํจ์ ๋ํ๋
๋๋ค.
React ๊ตฌ์ฑ ์์๋ ์ด๋ฏธ ์์ฑ์ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์๋ก ์ ๋ฌํ๊ธฐ ๋๋ฌธ์ sigil์ ์ฌ์ฉํ ํ์๊ฐ ์์ต๋๋ค(๊ทธ๋ ๋ค๋ฉด ์๋ํ์ง๋ง ์ค๋ณต๋ ๋ฟ์ ๋๋ค). ๋์ JavaScript ์์ฑ์ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์ ์ ์ ์์์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๊ธฐ ์ํ ๋ช ์์ ๋ช ๋ น์ผ๋ก ์ฃผ๋ก ์ฌ์ฉ๋ฉ๋๋ค.
์ด ์ ๊ทผ ๋ฐฉ์์ ์ ์ํ Preact ์ @developit์๊ฒ h/t๋ฅผ
๊ธฐ์กด์ ๋ชจ๋ React + ์ฌ์ฉ์ ์ ์ ์์ ์ฑ์ ๊ทธ๋๋ก ๊ณ์ ์๋ํฉ๋๋ค. ๊ฐ๋ฐ์๋ ์๋ก์ด sigil ์คํ์ผ์ ์ฌ์ฉํ๋๋ก ์ฝ๋๋ฅผ ์ ๋ฐ์ดํธํ ์ง ์ฌ๋ถ๋ฅผ ์ ํํ ์ ์์ต๋๋ค.
Glimmer์ ์ ์ฌํ๊ฒ Angular์ Vue ๋ชจ๋ ์์ฑ๊ณผ ์์ฑ์ ๊ตฌ๋ณํ๊ธฐ ์ํด ์์ ์๋ฅผ ์ฌ์ฉํฉ๋๋ค.
๋ทฐ ์์:
<!-- Vue will serialize `foo` to an attribute string, and set `squid` using a JavaScript property -->
<custom-element :foo="barโ :squid.prop=โinkโ>
๊ฐ๋ ์:
<!-- Angular will serialize `foo` to an attribute string, and set `squid` using a JavaScript property -->
<custom-element [attr.foo]="barโ [squid]=โinkโ>
๊ฐ๋ฐ์๋ properties-if-available ์ ๊ทผ ๋ฐฉ์๊ณผ ๊ฐ์ ๊ฒฝํ์ ๋ฐฉ๋ฒ์ ์์กดํ๋ ๋์ ์ํ๋ ๊ฒ์ ์ ํํ React์ ๋งํ ์ ์์ต๋๋ค.
๊ฐ๋ฐ์๋ ์ฌ์ฉ ๋ฐฉ๋ฒ์ ๋ฐฐ์์ผ ํ๋ฉฐ ์ด์ ๋ฒ์ ๊ณผ์ ํธํ์ฑ์ ํ์ธํ๊ธฐ ์ํด ์ฒ ์ ํ ํ ์คํธํด์ผ ํฉ๋๋ค.
sigil์ด ๋น์ทํ ์ด๋ฆ์ ์์ฑ์ ์ฌ์ฉํ๋๋ก ์ ํํด์ผ ํฉ๋๊น?
React๋ ์์ฑ์๊ฐ ๋ช ์์ ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์์ฑ์ผ๋ก ์ ๋ฌํ ์ ์๋๋ก ํ๋ ์ถ๊ฐ ๊ตฌ๋ฌธ์ ์ถ๊ฐํ ์ ์์ต๋๋ค. ๊ฐ๋ฐ์๊ฐ ์ด ์์ฑ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ์ง ์๋ ๊ฒฝ์ฐ ํด๋น ๋ฐ์ดํฐ๋ JavaScript ์์ฑ์ ์ฌ์ฉํ์ฌ ์ ๋ฌ๋ฉ๋๋ค.
์์:
const bar = 'baz';
const hello = 'World';
const width = '100%';
const ReactElement = <Test
foo={bar} // uses JavaScript property
attrs={{ hello, width }} // serialized to attributes
/>;
์ด ์์ด๋์ด๋ ์๋ Skate.js ์ ์์ฑ์์ธ @treshugart๊ฐ ์ ์ ํ์ผ๋ฉฐ val ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ๊ตฌํ๋์์ต๋๋ค.
๊ฐ๋ฐ์๋ properties-if-available ์ ๊ทผ ๋ฐฉ์๊ณผ ๊ฐ์ ๊ฒฝํ์ ๋ฐฉ๋ฒ์ ์์กดํ๋ ๋์ ์ํ๋ ๊ฒ์ ์ ํํ React์ ๋งํ ์ ์์ต๋๋ค.
์ฐธ๊ณ : ์ด๊ฒ์ ์ด ๋ฌธ์์ ๋ฒ์๋ฅผ ๋ฒ์ด๋์ง๋ง ์ธ๊ธํ ๊ฐ์น๊ฐ ์์ต๋๋ค. :)
๋ฌธ์ #7901 ์ ์ ์ธ์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ์ฌ์ฉ์ ์ ์ ์์์ ์ถ๊ฐ๋ ๋ React๊ฐ ํฉ์ฑ ์ด๋ฒคํธ ์์คํ
์ ์ฐํํ๋๋ก ์์ฒญํฉ๋๋ค. ์ฌ์ฉ์ ์ ์ ์์ ์ด๋ฒคํธ ์ด๋ฆ์ ์์์ ๋ฌธ์์ด์ด๋ฏ๋ก ์ด๋ค ๋ฐฉ์์ผ๋ก๋ ๋๋ฌธ์๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ค๋๋ ํฉ์ฑ ์ด๋ฒคํธ ์์คํ
์ ์ฐํํ๋ ค๋ฉด JSX์์ addEventListener
์ด๋ฒคํธ ์ด๋ฆ์ ๋งคํํ๊ธฐ ์ํ ๊ฒฝํ์ ๋ฐฉ๋ฒ์ ์ฐพ์์ผ ํฉ๋๋ค.
// should this listen for: 'foobar', 'FooBar', or 'fooBar'?
onFooBar={handleFooBar}
๊ทธ๋ฌ๋ ์์ฑ์ ํ์ฉํ๋๋ก ๊ตฌ๋ฌธ์ด ํ์ฅ๋๋ฉด ์ด๋ฒคํธ๋ ํ์ฉํ๋๋ก ํ์ฅ๋ ์ ์์ต๋๋ค.
const bar = 'baz';
const hello = 'World';
const SquidChanged = e => console.log('yo');
const ReactElement = <Test
foo={bar}
attrs={{ hello }}
events={{ SquidChanged}} // addEventListener('SquidChanged', โฆ)
/>;
์ด ๋ชจ๋ธ์์ ๋ณ์ ์ด๋ฆ์ ์ด๋ฒคํธ ์ด๋ฆ์ผ๋ก ์ฌ์ฉ๋ฉ๋๋ค. ํด๋ฆฌ์คํฑ์ด ํ์ํ์ง ์์ต๋๋ค.
๊ฐ๋ฐ์๋ ์ฌ์ฉ ๋ฐฉ๋ฒ์ ๋ฐฐ์์ผ ํ๋ฉฐ ์ด์ ๋ฒ์ ๊ณผ์ ํธํ์ฑ์ ํ์ธํ๊ธฐ ์ํด ์ฒ ์ ํ ํ ์คํธํด์ผ ํฉ๋๋ค.
๊ตฌ์ฑ ์์๊ฐ ์ด๋ฏธ attrs
๋๋ events
๋ผ๋ ์์ฑ์ ์์กดํ๋ ๊ฒฝ์ฐ ์์๋ ์ ์์ต๋๋ค.
React 17์ ๊ฒฝ์ฐ (์ด์ ์ ์ ์ค ํ๋์ ๊ฐ์ด) ์ ์ง์ ์ธ ๋ณ๊ฒฝ์ ์ํํ๊ณ ์ด ์ ์์ ๋์ค์ ๋ ํฐ ๋ฆฌํฉํฐ๋ง์ ์ํด ๊ณ ๋ คํด์ผ ํ ์ฌํญ์ผ๋ก ๋ฐฐ์นํ๋ ๊ฒ์ด ๋ ์ฌ์ธ ์ ์์ต๋๋ค.
์ด ์ ์์ React ํ์ @sophiebits ์ @gaearon ์ด ์ ์ํ์ต๋๋ค.
React๋ ์์์ ๋์์ ๊ตฌ์ฑ ๊ฐ์ฒด์ ๋งคํํ๋ ์ฌ์ฉ์ ์ ์ ์์๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํ ์ API๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค.
์์ฌ ์ฝ๋ ์:
const XFoo = ReactDOM.createCustomElementType({
element: โx-fooโ,
โmy-attrโ: // something that tells React what to do with it
someRichDataProp: // something that tells React what to do with it
});
์์ ์ฝ๋๋ ์ ๊ณตํ๋ ๊ตฌ์ฑ์ ๋ฐ๋ผ ์ฌ์ฉ์ ์ง์ ์์์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ๋ฐฉ๋ฒ์ ์๊ณ ์๋ ํ๋ก์ ๊ตฌ์ฑ ์์ XFoo
๋ฅผ ๋ฐํํฉ๋๋ค. ์ฌ์ฉ์ ์ง์ ์์๋ฅผ ์ง์ ์ฌ์ฉํ๋ ๋์ ์ฑ์์ ์ด ํ๋ก์ ๊ตฌ์ฑ ์์๋ฅผ ์ฌ์ฉํฉ๋๋ค.
์ฌ์ฉ ์:
<XFoo someRichDataProp={...} />
๊ฐ๋ฐ์๋ React์๊ฒ ๊ทธ๋ค์ด ์ํ๋ ์ ํํ ๋์์ ๋งํ ์ ์์ต๋๋ค.
๊ฐ๋ฐ์๋ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋๋ก ์ ํํ๊ฑฐ๋ ํ์ฌ ์์คํ ์ ๊ณ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ด ๋ณ๊ฒฝ์ ์๋ก์ด JSX ๊ตฌ๋ฌธ์ ํ์๋ก ํ์ง ์์ผ๋ฉฐ React์ ๋ค๋ฅธ API์ฒ๋ผ ๋๊ปด์ง๋๋ค. ์๋ฅผ ๋ค์ด, PropTypes(์์ฒด ํจํค์ง๋ก ์ด๋๋๋๋ผ๋)๋ ๋ค์ ์ ์ฌํ ์ ๊ทผ ๋ฐฉ์์ ์ฌ์ฉํฉ๋๋ค.
Polymer์ paper-input ์์์๋ 37๊ฐ์ ์์ฑ์ด ์์ผ๋ฏ๋ก ๋งค์ฐ ํฐ ๊ตฌ์ฑ์ ์์ฑํฉ๋๋ค. ๊ฐ๋ฐ์๊ฐ ์ฑ์์ ๋ง์ ์ฌ์ฉ์ ์ง์ ์์๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ์์ฑํด์ผ ํ๋ ๊ตฌ์ฑ์ด ๋ง์ ์ ์์ต๋๋ค.
์์ ์์ ๊ณผ ๊ด๋ จํ์ฌ ๊ฐ ์ฌ์ฉ์ ์ ์ ์์ ํด๋์ค๋ ์ด์ ์ ์ ๋น์ฉ + ๊ตฌ์ฑ ๊ฐ์ฒด ํฌ๊ธฐ๋ฅผ ๋ฐ์์ํต๋๋ค.
์ฐธ๊ณ : ์ด๊ฒ์ด ์ฌ์ค์ธ์ง 100% ํ์ ํ ์ ์์ต๋๋ค.
๊ตฌ์ฑ ์์๊ฐ ์ ์์ฑ์ ์ถ๊ฐํ๋ ๋ง์ด๋ ๋ฒ์ ๊ฐ์ ์ ์ํํ ๋๋ง๋ค ๊ตฌ์ฑ๋ ์ ๋ฐ์ดํธํด์ผ ํฉ๋๋ค. ์ด๋ ต์ง๋ ์์ง๋ง ์ ์ง ๊ด๋ฆฌ๊ฐ ์ถ๊ฐ๋ฉ๋๋ค. ์์ค์์ ๊ตฌ์ฑ์ ์์ฑํ๋ ๊ฒฝ์ฐ ๋ถ๋ด์ด ๋ํ ์ ์์ง๋ง ์ด๋ ๊ฐ ์น ๊ตฌ์ฑ ์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ํ ๊ตฌ์ฑ์ ์์ฑํ๊ธฐ ์ํด ์ ๋๊ตฌ๋ฅผ ์์ฑํด์ผ ํจ์ ์๋ฏธํ ์ ์์ต๋๋ค.
cc @sebmarkbage @gaearon @developit @treshugart @justinfagnani
๊ธด ๊ธ์ ์ฝ์ด์ ์ฃ์กํ์ง๋ง ๊ฐ ์ต์ ์ ์ฒ ์ ํ ์กฐ์ฌํ๊ณ ์๋์ง ํ์ธํ๊ณ ์ถ์์ต๋๋ค. ์ ์๊ฒฌ์ผ๋ก ๋๋ฌด ํธํฅ๋๊ณ ์ถ์ง๋ ์์ง๋ง, ๋ง์ฝ ์ ๊ฐ ์ ํ์ ์ฌ์ง๊ฐ ์๋ค๋ฉด 3๋ฒ์ ํํ ๊ฒ ๊ฐ์์.
์ต์ 3์ ์ด์ ๋ฒ์ ๊ณผ ํธํ๋๊ณ ์ ์ธ์ ์ด๋ฉฐ ๋ช ์์ ์ ๋๋ค. ๋์ฒด ํด๋ฆฌ์คํฑ์ ์ ์งํ ํ์๊ฐ ์์ผ๋ฉฐ ๋ค๋ฅธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ด๋ฏธ ์ ์ฌํ ๊ธฐํธ/์์ ์๋ฅผ ์ ๊ณตํฉ๋๋ค.
๊ธด ๊ธ์ ์ฝ์ด์ ์ฃ์กํ์ง๋ง ๊ฐ ์ต์
์ ์ฒ ์ ํ ์กฐ์ฌํ๊ณ ์๋์ง ํ์ธํ๊ณ ์ถ์์ต๋๋ค. ์ ์๊ฒฌ์ผ๋ก ๋๋ฌด ํธํฅ๋๊ณ ์ถ์ง๋ ์์ง๋ง, ๋ง์ฝ ์ ๊ฐ ์ ํ์ ์ฌ์ง๊ฐ ์๋ค๋ฉด 3๋ฒ์ ํํ ๊ฒ ๊ฐ์์.
์ต์
3์ ์ด์ ๋ฒ์ ๊ณผ ํธํ๋๊ณ ์ ์ธ์ ์ด๋ฉฐ ๋ช
์์ ์
๋๋ค. ๋์ฒด ํด๋ฆฌ์คํฑ์ ์ ์งํ ํ์๊ฐ ์์ผ๋ฉฐ ๋ค๋ฅธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ด๋ฏธ ์ ์ฌํ ๊ธฐํธ/์์ ์๋ฅผ ์ ๊ณตํฉ๋๋ค.
์ ๋ ์ต์ 2์ ์ต์ 3 ์ฌ์ด์ ์์ต๋๋ค. React๋ ๊ณผ๊ฑฐ์ ๋์๊ณผ API ๋ณ๊ฒฝ ์ฌํญ์ ๋งค์ฐ ์ ์ฒ๋ฆฌํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ๊ฒฝ๊ณ ๋ฐ ๋ฌธ์ ๋งํฌ๋ฅผ ๋์ ํ๋ฉด ๊ฐ๋ฐ์๊ฐ ๋ด๋ถ์์ ์ผ์ด๋๋ ์ผ์ ์ดํดํ๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค.
์ต์ 3์ ์ ์ธ์ ํน์ฑ์ผ๋ก ์ธํด ๋งค๋ ฅ์ ์ผ๋ก ๋ณด์ด์ง๋ง JSX ์ฝ๋๋ฅผ ์ฝ๋ ๋์ ์๋ก ์ค๋ ๊ฐ๋ฐ์๋ ์์๋ฅผ ๋ ๋๋งํ ๋ React๊ฐ ์ํํ๋ ์์ ์ ์ฆ์ ์ ์ ์์ต๋๋ค.
๊ฐ๋ฐ์๋ React๊ฐ ์์๋ฅผ ๋ก๋ํ๊ธฐ ์ํด ์ ํํ ๋ฐฉ๋ฒ์ ๋ฐ๋ผ ์์ฑ ๋์ ์์ฑ์ ์ค์ ํ ๋ ํผ๋์ค๋ฌ์ธ ์ ์์ต๋๋ค.
์ฌ์ฉ์ ์ ์ ์์์ ์๋น์๋ ์ด ๊ตฌ๋ถ์ ์ดํดํ ํ์๊ฐ ์์ต๋๊น? ์๋๋ฉด ์ปค์คํ ์์์ ์์ฑ์์๊ฒ๋ง ์ค์ํ๊ฐ์? DOM์์ ๋ณต์กํ ๊ฐ์ด๋ ์์ฑ ๊ฐ์ ธ์ค๊ธฐ/์ค์ ์ ์ง์ํ๋ ค๋ฉด ์์ ์์ฑ์๊ฐ HTML(HTML ์ฌ์ฉ์์ ๋ฐ์ดํฐ๊ฐ ์ ๋ฌ๋๋ ์ ์ผํ ๋ฐฉ๋ฒ์ด๊ธฐ ๋๋ฌธ์) ๋ฐ ์์ฑ์ ์ฌ์ฉ๋๋ ๋ชจ๋ ์์ฑ์ ์ฒ๋ฆฌํด์ผ ํ ๊ฒ ๊ฐ์ต๋๋ค. ์์ฑ์๊ฐ ์ฒ์์ ์์ฑ์ผ๋ก ๊ตฌํํ ๋ค์ ๋์ค์ ๋์ผํ ์ด๋ฆ์ ์์ฑ์ ์ถ๊ฐํ์ฌ ๋ณด๋ค ์ ์ฐํ ๋ฐ์ดํฐ ์ ํ์ ์ง์ํ๊ณ ์์ฑ์ ์ ์ฅ๋ ๊ฐ์ผ๋ก ์์ฑ์ ๋ฐฑ์ ํ ์๋ ์์ต๋๋ค.
๋ฏธ๋์ HTMLElement ์์ฑ ๋ฐ ์์ฑ๊ณผ์ ์ด๋ฆ ์ถฉ๋์ ๋ฐ์ธ๋ฉ ์ ๊ทผ ๋ฐฉ์์ ๊ด๊ณ์์ด ์ค๋ฅ๋ฅผ ์ ๋ฐํ ์ ์๊ธฐ ๋๋ฌธ์ ์ผ๋ฐ์ ์ผ๋ก ์น ๊ตฌ์ฑ ์์ ํ์ค์ ์ฝ์ ์ผ๋ก ๋ณด์ ๋๋ค.
์์์ ์ ์๋์ง ์์ ์์ฑ์ด ์๊ณ React๊ฐ ๊ฐ์ฒด/๋ฐฐ์ด์ ์ ๋ฌํ๋ ค๊ณ ํ๋ฉด ์์ฑ์ผ๋ก ์ค์ ๋ฉ๋๋ค. ์ด๊ฒ์ some-attr="[object Object]"๊ฐ ์ ์ฉํ์ง ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
๊ฐ์ ๋ฐ๋ผ ๋ค๋ฅด๊ฒ ๋ฐ์ธ๋ฉํ๋ ๊ฒ์ ํผ๋์ค๋ฌ์ธ ๊ฒ ๊ฐ์ต๋๋ค. ์์ ์์ฑ์๊ฐ ๊ฐ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์์ฑ getter/setter๋ฅผ ์ง์ ํ์ง ์์ ๊ฒฝ์ฐ ์์ฑ์ ์ค์ ํ๋ฉด ์์๊ฐ ๊ฐ์ด ์ง์ ๋์ง ์์ ๊ฒ์ฒ๋ผ ์๋ํ์ฌ ๋๋ฒ๊ทธํ๊ธฐ ๋ ์ด๋ ค์ธ ์ ์์ต๋๋ค.
์ต์ 3์ ๋ ๋ค๋ฅธ ์ ์ฌ์ ์ธ ๋จ์ ์ ์ฌ์ฉ์ ์ง์ ์์์ ์๋น์๊ฐ ์์๊ฐ ์์ฑ ๋๋ ์์ฑ์ผ๋ก ๊ตฌํํ๋์ง ์ฌ๋ถ๋ฅผ ์์์ผ ํ๋ค๋ ๊ฒ์ ๋๋ค. React ๊ตฌ์ฑ ์์์ ์ฌ์ฉ์ ์ ์ ์์๋ฅผ ํผํฉํ์ฌ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ํ๋์ ๊ตฌ๋ฌธ์ ์ฌ์ฉํ์ฌ React ์ํ์ ์ค์ ํ๊ณ ๋ค๋ฅธ ๊ตฌ๋ฌธ์ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์ ์ ์ ์์ ์์ฑ์ ์ค์ ํ๋ ๊ฒ์ด ํผ๋์ค๋ฌ์ธ ์ ์์ต๋๋ค.
์ฌ์ฉ์ ์ ์ ์์์ ์๋น์๋ ์ด ๊ตฌ๋ถ์ ์ดํดํ ํ์๊ฐ ์์ต๋๊น? ์๋๋ฉด ์ปค์คํ ์์์ ์์ฑ์์๊ฒ๋ง ์ค์ํ๊ฐ์?
๋น์ ์ด ์ง์ ํ๋ฏ์ด ์์ ์์ฑ์๊ฐ ๊ธฐ๋ณธ ๊ฐ์ ๋ํ ์์ฑ๊ณผ ์์ฑ์ ์ ์ํ๊ณ ๋ ๋ค์ ๋ฐ์ดํฐ๋ฅผ ์๋ฝํด์ผ ํ๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ด ์ค์ ๋ก ํฐ ๋ฌธ์ ์ธ์ง ์์ฌ์ค๋ฝ์ต๋๋ค. ๋ํ ์์ฑ๊ณผ ์์ฑ์ ๋๊ธฐํ ์ํ๋ก ์ ์งํด์ผ ํ๋ค๊ณ ๋ง๋ถ์์ต๋๋ค(ํ๋๋ฅผ ์ค์ ํ๋ฉด ๋ค๋ฅธ ํ๋๊ฐ ์ค์ ๋จ).
๋ฏธ๋์ HTMLElement ์์ฑ ๋ฐ ์์ฑ๊ณผ์ ์ด๋ฆ ์ถฉ๋์ ๋ฐ์ธ๋ฉ ์ ๊ทผ ๋ฐฉ์์ ๊ด๊ณ์์ด ์ค๋ฅ๋ฅผ ์ ๋ฐํ ์ ์๊ธฐ ๋๋ฌธ์ ์ผ๋ฐ์ ์ผ๋ก ์น ๊ตฌ์ฑ ์์ ํ์ค์ ์ฝ์ ์ผ๋ก ๋ณด์ ๋๋ค.
๋์ํ์ง๋ง ์ด๊ฒ์ด React๊ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ํด๊ฒฐํด์ผ ํ ์ฌํญ์ธ์ง ํ์คํ์ง ์์ต๋๋ค. ์ปค์คํ ์์ ์ฌ์์ ์ผ๋ถ๋ก ํด๊ฒฐํด์ผ ํ ๋ฌธ์ ์ฒ๋ผ ๋๊ปด์ง๋๋ค. ๋ค๊ฐ์ค๋ TPAC ํ์ค ํ์์ ์ผ๋ถ๋ก ์ด์ ๋ํด ๋ ผ์ํ ์ ์๋์ง ์ ์ ์์ต๋๋ค.
์์ ์ ์ ์์ฑ์ด HTMLElement์ ์ถ๊ฐ๋๋ ๋ฏธ๋ ์์ฑ์ ๊ฐ๋ฆฌ๊ธฐ ๋๋ฌธ์ ์์ฑ์ ๊ฒฝ์ฐ ์ด๊ฒ์ ๋์์ง ์์ต๋๋ค. ๋ฐ๋ผ์ js ์์ฑ์ผ๋ก ์ฌ์ฉ์ ์ ์ ์์์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ๊ฒฝ์ฐ ๊ณ์ ์๋ํฉ๋๋ค. ์ฃผ์ ๋ฌธ์ ๋ ์์ฑ์ด ์ ์ญ์ ์ด๊ธฐ ๋๋ฌธ์ ์์ฑ๊ณผ ๊ด๋ จ๋ ๊ฒ ๊ฐ์ต๋๋ค.
๊ฐ์ ๋ฐ๋ผ ๋ค๋ฅด๊ฒ ๋ฐ์ธ๋ฉํ๋ ๊ฒ์ ํผ๋์ค๋ฌ์ธ ๊ฒ ๊ฐ์ต๋๋ค. ์์ ์์ฑ์๊ฐ ๊ฐ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์์ฑ getter/setter๋ฅผ ์ง์ ํ์ง ์์ ๊ฒฝ์ฐ ์์ฑ์ ์ค์ ํ๋ฉด ์์๊ฐ ๊ฐ์ด ์ง์ ๋์ง ์์ ๊ฒ์ฒ๋ผ ์๋ํ์ฌ ๋๋ฒ๊ทธํ๊ธฐ ๋ ์ด๋ ค์ธ ์ ์์ต๋๋ค.
์ฌ์ฉ์ ์ ์ ์์๊ฐ ์ง์ฐ ๋ก๋๋๊ณ "์ ๊ทธ๋ ์ด๋"๋ ๊ฒฝ์ฐ ์ฒ์์๋ ์ ์๋์ง ์์ ์์ฑ์ด ์์ต๋๋ค. ์ด๋ ํด๋น ์์๊ฐ ์ฌ์ ํ ๋ฐ์ดํฐ๋ฅผ ์์ ํ๊ณ ์ ๊ทธ๋ ์ด๋ ํ์๋ ์ฌ์ฉํ ์ ์๋๋ก ํ์ฌ ํด๋น ์ฌ์ฉ ์ฌ๋ก๋ฅผ ํด๊ฒฐํฉ๋๋ค.
์์ฑ์๊ฐ ๊ฐ์ ๋ํ getter/setter๋ฅผ ์ ์ํ์ง ์์ผ๋ฉด ์ด๊ฒ์ ๋งค์ฐ ์ ์ฉํ์ง ์์ ๊ฒ์
๋๋ค. ๊ทธ๋ฌ๋ my-attr=[object Object]
๊ฐ ์๋ ๊ฒ๋ ์ ์ฉํ์ง ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ์์ฑ์ด ์ ๋ง๋ก ์ ์๋์ง ์์ ๊ฒ์ธ์ง ์๋๋ฉด ์ ์๊ฐ ์ง์ฐ ๋ก๋๋๋์ง ์ ์ ์์ผ๋ฏ๋ก ์์ฑ์ ์ค์ ํ๋ ๊ฒ์ด ๊ฐ์ฅ ์์ ํด ๋ณด์
๋๋ค.
์ต์ 3์ ๋ ๋ค๋ฅธ ์ ์ฌ์ ์ธ ๋จ์ ์ ์ฌ์ฉ์ ์ง์ ์์์ ์๋น์๊ฐ ์์๊ฐ ์์ฑ ๋๋ ์์ฑ์ผ๋ก ๊ตฌํํ๋์ง ์ฌ๋ถ๋ฅผ ์์์ผ ํ๋ค๋ ๊ฒ์ ๋๋ค.
์ฌ์ฉ์ ์ ์ ์์ ์์ฑ์๊ฐ ์์ฑ ๋์ ์์ฑ์ ์ ์ํ๋๋ก ๊ฐ์ ํ๋ ๊ฒ์ด ์๊ธฐ ๋๋ฌธ์ ๊ทํ๋ ์ค๋๋ ๋ณธ์ง์ ์ผ๋ก ๊ฐ์ ๋ฐฐ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ๋ฐ๋ผ์ React์ ํ์ฌ ์์คํ
์์ ๋ฐ์ดํฐ๋ฅผ ์์ ํ์ง ์๋ ์์ฑ ์ ์ฉ API๊ฐ ์๋ ์์๋ฅผ ๊ฐ์ง ์ ์์ผ๋ฉฐ ref
๋ฅผ ์ฌ์ฉํ์ฌ js ์์ฑ์ ์ง์ ์ค์ ํ๋ ๋ฐฉ๋ฒ์ ์์์ผ ํฉ๋๋ค.
์ฌ์ฉ์ ์ ์ ์์๋ ๊ธฐ๋ณธ ์์์ด๋ฏ๋ก ํด๋น ์์ฑ ๋ฐ ์์ฑ์ ๊ฐ์ ๋ก ์์ฑํ๋ ๊ฒ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ฐ๋ฆฌ๋ ๊ทธ๋ ๊ฒ ํ๋ ๊ฒ์ ๋ชจ๋ฒ ์ฌ๋ก๋ก ์ฅ๋ คํ๊ธฐ ์ํด ๋งค์ฐ ์ด์ฌํ ๋ ธ๋ ฅํ๊ณ ์์ผ๋ฉฐ, ์ค๋๋ ๋ด๊ฐ ์๊ณ ์๋ ๋ชจ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ํด๋น ์์ฑ์ ๋ํ ์ง์ ์์ฑ์ ์์ฑํฉ๋๋ค.
[ํธ์งํ๋ค]
์ด์ ์์ ์์ ์ธ๊ธํ๋ฏ์ด:
DOM์์ ๋ณต์กํ ๊ฐ์ด๋ ์์ฑ ๊ฐ์ ธ์ค๊ธฐ/์ค์ ์ ์ง์ํ๋ ค๋ฉด ์์ ์์ฑ์๊ฐ HTML(HTML ์ฌ์ฉ์์ ๋ฐ์ดํฐ๊ฐ ์ ๋ฌ๋๋ ์ ์ผํ ๋ฐฉ๋ฒ์ด๊ธฐ ๋๋ฌธ์) ๋ฐ ์์ฑ์ ์ฌ์ฉ๋๋ ๋ชจ๋ ์์ฑ์ ์ฒ๋ฆฌํด์ผ ํ ๊ฒ ๊ฐ์ต๋๋ค.
์ฌ์ฉ์๊ฐ ์์์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ๋ฐฉ๋ฒ์ ์ ์ ์๊ธฐ ๋๋ฌธ์ ๊ฒฐ๊ตญ ์์ฑ-์์ฑ ๋์์ด ํ์ํ๊ฒ ๋ฉ๋๋ค. ์ต์
3์ด ์ ๊ณต๋๋ฉด ๋๋ถ๋ถ์ ์ฌ๋๋ค์ด @
์ฌ์ฉํ์ฌ ๋ชจ๋ ๊ฒ์ ๋ฌถ์ ๊ฒ์
๋๋ค. ์๋ํ๋ฉด ๊ทธ๊ฒ์ด ๊ฐ์ฅ ์ฝ๊ธฐ ๋๋ฌธ์
๋๋ค. ๊ทธ๊ฒ์ด .prop
์์์ด๋ฅผ ๋
ธ์ถํ๊ธฐ ๋๋ฌธ์ ์ค๋๋ Vue์์ ์ฌ์ฉ์ ์ ์ ์์๋ก ์์
ํ๋ ๋ฐฉ๋ฒ์
๋๋ค.
์ฌ์ฉ์ ์ ์ ์์์ ์๋น์๋ ์์๊ฐ ์์ฑ ๋๋ ์์ฑ์ผ๋ก ๊ตฌํํ๋์ง ์ฌ๋ถ๋ฅผ ์์์ผ ํฉ๋๋ค.
๋ด ์๊ฐ์๋ Rob์ด ๋งํ๋ฏ์ด React๊ฐ ๊ฑฑ์ ํด์ผ ํ ๋ถ๋ถ์ด ์๋๋๋ค. ์ฌ์ฉ์์๊ฒ ์์๊ฐ ์๋ํ๋ ๋ฐฉ์์ ์๋ ค์ฃผ๋ ๊ฒ์ ์ฌ์ฉ์ ์ ์ ์์ ์์ฑ์์ ์ฑ ์์ ๋๋ค.
๊ทธ๋ฆฌ๊ณ ์ด๊ฒ์ ์ค์ ๋ก ์ค๋๋ ์ฐ๋ฆฌ๊ฐ ํด์ผ ํ๋ ๋ฐฉ์์
๋๋ค. ์๋ฅผ ๋ค์ด <video>
์์์ ๋ํด ์๊ฐํด ๋ณด์ญ์์ค. ์ด๋ฅผ ์์๊ฑฐํ๊ฑฐ๋ ๊ตฌ์ฑ ์์ ๋ด๋ถ์ ํ์ฌ ์๊ฐ์ ๋ณ๊ฒฝํด์ผ ํ๋ค๊ณ ๊ฐ์ ํด ๋ณด๊ฒ ์ต๋๋ค.
muted
๋ ๋ถ์ธ ์์ฑ์ผ๋ก ์๋ํฉ๋๋ค.
render() {
return (
<div className="video--wrapper">
<video muted={ this.state.muted } />
</div>
);
}
ํ์ฌ๋ก์๋ video ์์๋ฅผ ๊ฐ๋ฆฌํค๋ ref
๋ฅผ ๋ง๋ค๊ณ ์์ฑ์ ๋ณ๊ฒฝํด์ผ ํฉ๋๋ค.
render() {
return (
<div className="video--wrapper">
<video ref={ el => this.video = el } muted={ this.state.muted } />
</div>
);
}
๊ทธ๋ฐ ๋ค์ ์ธ์คํด์ค ๋ฉ์๋์ธ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ง๋ค๊ณ ์์ฑ์ DOM ์์๋ก ์๋์ผ๋ก ์ค์ ํฉ๋๋ค.
onCurrenTimeChange(e) {
this.video.currentTime = e.value;
}
currentTime
๊ฐ ๋ํผ ๊ตฌ์ฑ ์์์ ์ํ์์ด ๋ถ๋ช
ํ๊ธฐ ๋๋ฌธ์ React ์์ฒด๊ฐ API ๋ฐ JSX ์ถ์ ๋ ์ด์ด๋ก ๋ถ๊ณผํ๋ ์ ์ธ์ ๋ชจ๋ธ์ ๊นจ๋จ๋ฆฝ๋๋ค. ์์ฑ ๋ฐ์ธ๋ฉ์ ์ฌ์ฉํ๋ฉด ์ฌ์ ํ ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ํ์ํ์ง๋ง JSX ์ถ์ํ ๋ชจ๋ธ์ ๋ ์ ์ธ์ ์ด๋ฉฐ refs๋ ๋ค์๊ณผ ๊ฐ์ ๊ฒฝ์ฐ์๋ง ํ์ํ์ง ์์ต๋๋ค.
render() {
return (
<div className="video--wrapper">
<video muted={ this.state.muted } @currentTime={ this.state.currentTime } />
</div>
);
}
๋ด ์์ ์ ๋ค์ดํฐ๋ธ ๋๋ ์ฌ์ฉ์ ์ ์ ์์์ ์์กดํ๋์ง ์ฌ๋ถ์ ๊ด๊ณ์์ด ๋ฌธ์๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํด๋น ์์๋ฅผ ์ฐํํ๋ ๋ฐฉ๋ฒ์ ์์์ผ ํ๋ค๋ ๊ฒ์ ๋๋ค. ๋ ๋ฒ์งธ ๊ฒฝ์ฐ์๋ ์ฌ์ฉ์ ์ ์ ์์์ ์์ฑ์๊ฐ ์ ๊ณตํด์ผ ํ๋ค๋ ์ฐจ์ด์ ์ด ์์ต๋๋ค.
@cjorasch ๋ด ๋ ์ผํธ :)
์ด์ ๋ฒ์ ๊ณผ์ ํธํ์ฑ์ ๊ณ ๋ คํ ํ์ ์์ด ์ฒ์๋ถํฐ ์ด๊ฒ์ ์ค๊ณํ๋ค๋ฉด React์ "JavaScript-centric API to DOM"์ ๋ฐ๋ผ ์ต์ 1์ด ๊ฐ์ฅ ๊ด์ฉ์ ์ผ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
์๋ฒ ์ธก ๋ ๋๋ง๊ณผ ๊ด๋ จํ์ฌ ์ฌ์ฉ์ ์ ์ ์์ ์์ฑ์ ์์ฑ์ ๋งคํํ๋ ๋ฐฉ๋ฒ์ React์ ์๋ฆฌ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ฝ๋์ฉ API๋ฅผ ์ ๊ณตํ์ฌ ํด๋น ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์ต๋๊น? ํ๋ซํผ ์ ์ ์์ฑ์ ๋ํด React๊ฐ ์ด๋ฏธ ์ ์ง ๊ด๋ฆฌํ๋ ๋งต๊ณผ ์ ์ฌํฉ๋๊น? ์ด API๋ ์ฌ์ฉ์ ์ ์ ์์ ์ด๋ฆ๋น ํ ๋ฒ๋ง ํธ์ถํ๋ฉด ๋๋ฉฐ(๊ฐ ์ธ์คํด์ค์ ๋ํด๊ฐ ์๋) ์์ฑ๊ณผ์ ์ง์ ์ ์ธ 1:1 ๋์์ ๋ฐ๋ฅด์ง ์๋ ์์ฑ์ ๋ํด์๋ง ํธ์ถํด์ผ ํฉ๋๋ค.
์ฐ๋ฆฌ๊ฐ ์ด๊ฒ์ด ๋๋ฌด ๋ง์ ์ฃผ์ ๋ณ๊ฒฝ ์ฌํญ์ด๋ผ๊ณ ์ฐ๋ คํ๋ค๋ฉด ์ต์ 3๋ ๊ฝค ๋งค๋ ฅ์ ์ด๋ผ๊ณ โโ์๊ฐํฉ๋๋ค. sigil์ด ์์ฑ์ ์๋ฏธํ๋ ๊ฒฝ์ฐ "."๋ฅผ ์ ์ํฉ๋๋ค. ์ด๋ฏธ JavaScript์ ์์ฑ ์ ๊ทผ์์ด๊ธฐ ๋๋ฌธ์ ๋๋ค. ๊ทธ๋ฌ๋ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ฌ์ฉ์ ์ ์ ์์๊ฐ ์ฌ์ฉ๋๋ ๋ชจ๋ ์ธ์คํด์ค๊ฐ ์์ฑ์ ์ฌ์ฉํ ๋์ ์์ฑ์ ์ฌ์ฉํ ๋๋ฅผ ์๋ ์ฑ ์์ ์ง๊ฒ ํ๋ ๊ฒ์ ๋ถํํ ์ผ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ์ต์ 1์ ๋ํด ๋ด๊ฐ ์ ํธํ๋ ๊ฒ์ ์์ฑ ๋งต์ ๋ํ ์์ฑ์ด ํ์ํ๋๋ผ๋ ํด๋น ๋งคํ ์ฝ๋๋ฅผ ๋ชจ๋ JSX ์ฌ์ฉ์์ ๊ฒฉ๋ฆฌํ ์ ์๋ค๋ ๊ฒ์ ๋๋ค.
์ฌ์ฉ์ ์ ์ ์์๊ฐ ์ง์ฐ ๋ก๋๋๊ณ "์ ๊ทธ๋ ์ด๋"๋ ๊ฒฝ์ฐ ์ฒ์์๋ ์ ์๋์ง ์์ ์์ฑ์ด ์์ต๋๋ค. ์ด๋ ํด๋น ์์๊ฐ ์ฌ์ ํ ๋ฐ์ดํฐ๋ฅผ ์์ ํ๊ณ ์ ๊ทธ๋ ์ด๋ ํ์๋ ์ฌ์ฉํ ์ ์๋๋ก ํ์ฌ ํด๋น ์ฌ์ฉ ์ฌ๋ก๋ฅผ ํด๊ฒฐํฉ๋๋ค.
์
๊ทธ๋ ์ด๋ ๊ณผ์ ์ ์ดํดํ์ง ๋ชปํ๋ ๊ฒ์ผ ์๋ ์์ต๋๋ค. ์์๋ ์ผ๋ฐ์ ์ผ๋ก ํด๋์ค ํ๋กํ ํ์
์์ getter/setter๋ก ์ ์๋ ์์ฑ์ ๊ฐ์ต๋๋ค. propName in element
ํ์ธํ๋ฉด ์์ฑ ๊ฐ์ด ์์ง ์ ์๋์ง ์์ ๊ฒฝ์ฐ์๋ getter/setter๊ฐ ์๊ธฐ ๋๋ฌธ์ true๋ฅผ ๋ฐํํฉ๋๋ค. ์
๊ทธ๋ ์ด๋ํ๋ ๋์ ์์ฑ ๊ฐ์ด ์ผ๋ถ ์์ ์ธ์คํด์ค์ ์ค์ ๋๊ณ ๋์ค์ ์ง์ฐ ๋ก๋๊ฐ ์๋ฃ๋๋ฉด ์ค์ ์ธ์คํด์ค์ ๋ณต์ฌ๋ฉ๋๊น?
์ ๊ทธ๋ ์ด๋๋ ์ฌ์ฉ์ ์ ์ ์์๊ฐ ํด๋น ํด๋์ค๋ฅผ ์์ ํ๋ ํ๋ก์ธ์ค์ ๋๋ค. ๊ทธ ์ ์๋ ํด๋น ํด๋์ค์ ์ธ์คํด์ค๊ฐ ์๋๋ฏ๋ก ์์ฑ getter/setters๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
@jeremenichelli
์์๊ฑฐ๋ ๋ถ์ธ ์์ฑ์ผ๋ก ์๋ํฉ๋๋ค.
๋ฐฉ๊ธ ํ์ธํ์ผ๋ฉฐ MDN์ ๋ฌธ์ํ๋์ด ์์ง ์์ ๊ฒ ๊ฐ์ง๋ง ํด๋น ์์ฑ๋ ์์ต๋๋ค.
ํ์ฌ๋ก์๋ ๋น๋์ค ์์๋ฅผ ๊ฐ๋ฆฌํค๋ ์ฐธ์กฐ๋ฅผ ๋ง๋ค๊ณ ์์ฑ์ ๋ณ๊ฒฝํด์ผ ํฉ๋๋ค.
์, ๋๋๋ก ํ๋ HTML ์์์์ ์์ฑ ์ ์ฉ API๋ฅผ ์ ํ๊ฒ ๋ฉ๋๋ค. currentTime
๋ ๋์ ๋น๋๋ก ์
๋ฐ์ดํธ๋๋ฏ๋ก HTML ์์ฑ์ ๋ฐ์ํ๋ ๊ฒ์ ์๋ฏธ๊ฐ ์์ต๋๋ค.
๋ด ์์ ์ ๊ธฐ๋ณธ ์์ ๋๋ ์ฌ์ฉ์ ์ ์ ์์์ ์์กดํ๋ ๋ฌธ์๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ๋ ๋ฐฉ๋ฒ์ ์ฌ์ ํ ์์์ผ ํ๋ค๋ ๊ฒ์ ๋๋ค.
๋ค, ๋ถํํ๋ ๋ง๋ฅ ์์ฑ/์์ฑ ๊ท์น์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ผ๋ฐ์ ์ผ๋ก ์์ฑ์ ํฌ๊ฒ ์์กดํ๊ณ ๊ฐ๋ฐ์๊ฐ ํน์ํ ๊ฒฝ์ฐ์ ์์ฑ์ ์ฌ์ฉํ ์ ์๋๋ก ๊ตฌ๋ฌธ์ ์ ๊ณตํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
@robdodson yeap, ๋๋ ์์๊ฑฐ๋ ์์ฑ์ ๋ํด ์๊ณ ์์์ต๋๋ค ๐ ๋ฐฉ๊ธ ์ด ๋ ๊ฐ์ง๋ฅผ ์ฌ์ฉํ์ฌ ์ด๋ฏธ _์ผ์์์_ ๋น์ ์ด ์ธ๊ธํ ๊ฒ๊ณผ ๊ฐ์ด ํ์ผ์ ์ธ ๊ท์น์ด ์๋ค๋ ๊ฒ์ ์ฆ๋ช ํ์ต๋๋ค.
์ฐ๋ฆฌ๋ ๊ธฐ๋ณธ ์์์ ์ฌ์ฉ์ ์ ์ ์์ ๋ชจ๋์ ๋ํ ๋ฌธ์์ ์์กดํด์ผ ํ๋ฏ๋ก ์ด ๊ฒฐ์ ์ ๋ํด ์ ๊ฒฝ ์ฐ์ง ์์ ๊ฒ์ ๋๋ค.
๋ง์ง๋ง ์ฝ๋ ์ค๋ํซ์ ์์ฑํ๋ ๋์ ์์ฑ ๋ฐ์ธ๋ฉ์ด ๋ง์์ ๋ค์์ต๋๋ค. ๐
@effulgentsia
๊ทธ๋ฌ๋ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ฌ์ฉ์ ์ ์ ์์๊ฐ ์ฌ์ฉ๋๋ ๋ชจ๋ ์ธ์คํด์ค๊ฐ ์์ฑ์ ์ฌ์ฉํ ๋์ ์์ฑ์ ์ฌ์ฉํ ๋๋ฅผ ์๋ ์ฑ ์์ ์ง๊ฒ ํ๋ ๊ฒ์ ๋ถํํ ์ผ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
๋๋ ์ด๊ฒ์ด ์ค๋๋ ์๋ ์ด๋ฏธ ๊ทธ๋ฌํ๋ค๊ณ ์๊ฐํ๋ค. ์ฃผ์ ์ฌ์ฉ์ ์ ์ ์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ(ํด๋ฆฌ๋จธ, ์ค์ผ์ดํธ, ์๋ง๋ ๊ธฐํ?)๋ ๋ ธ์ถ๋ ๋ชจ๋ ์์ฑ์ ๋ํ ์ง์ ์์ฑ์ ์๋์ผ๋ก ์์ฑํ๋ฏ๋ก ๊ฐ๋ฐ์๋ ์ฌ์ฉ์ ์ ์ ์์์ ๋ชจ๋ ์์ฑ์ ๋ํด sigil์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์์ฑ ์ฌ์ฉ์ผ๋ก ์ ํํด์ผ ํ๋ ๊ฒฝ์ฐ๋ ๋๋ฌผ ๊ฒ์ ๋๋ค.
@cjorasch
RE: ์
๊ทธ๋ ์ด๋. @effulgentsia๊ฐ ์ธ๊ธํ๋ฏ์ด ํ์ด์ง์ ์ฌ์ฉ์ ์ ์ ์์๋ฅผ ๊ฐ์ง ์ ์์ง๋ง ๋์ค์ ํด๋น ์ ์๋ฅผ ๋ก๋ํ ์ ์์ต๋๋ค. <x-foo>
๋ ์ฒ์์ HTMLElement
์ ์ธ์คํด์ค๊ฐ ๋๊ณ ๋์ค์ ์ ์๋ฅผ ๋ก๋ํ๋ฉด "์
๊ทธ๋ ์ด๋"๋์ด XFoo
ํด๋์ค์ ์ธ์คํด์ค๊ฐ ๋ฉ๋๋ค. ์ด ์์ ์์ ๋ชจ๋ ์๋ช
์ฃผ๊ธฐ ์ฝ๋ฐฑ์ด ์คํ๋ฉ๋๋ค. ํด๋ฆฌ๋จธ ์คํํฐ ํคํธ ํ๋ก์ ํธ์์ ์ด ๊ธฐ์ ์ ์ฌ์ฉํฉ๋๋ค. ๋ค์๊ณผ ๊ฐ์ ์ข
๋ฅ:
<app-router>
<my-view1></my-view1>
<my-view2></my-view2>
</app-router>
์์ ์์์ ๋ผ์ฐํฐ๊ฐ ๋ณ๊ฒฝ๋ ๋๊น์ง my-view2
๋ํ ์ ์๋ฅผ ๋ก๋ํ์ง ์์ต๋๋ค.
์์๊ฐ ์ ๊ทธ๋ ์ด๋๋๊ธฐ ์ ์ ์์์ ์์ฑ์ ์ค์ ํ๋ ๊ฒ์ ์ ์ ์ผ๋ก ๊ฐ๋ฅํ๋ฉฐ, ์ ์๊ฐ ๋ก๋๋๋ฉด ์์๋ ์๋ช ์ฃผ๊ธฐ ์ฝ๋ฐฑ ์ค ํ๋์์ ํด๋น ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.
๊ฐ๋ฐ์๋ ์ฌ์ฉ์ ์ ์ ์์์ ๋ชจ๋ ์์ฑ์ ๋ํด sigil์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๊ฐ๋ฐ์๊ฐ ๊ทธ๋ ๊ฒ ํ๊ธฐ ์์ํ๋ค๋ฉด "ํ ์ ์๊ธฐ" ๋๋ฌธ์ ์์ฑ์ ์ฌ์ฉํ๋ ๊ฒ๊ณผ "๋ฐ๋์" ํด์ผ ํ๊ธฐ ๋๋ฌธ์ ์์ฑ์ ์ฌ์ฉํ๋ ๊ฒ์ ์ด๋ป๊ฒ ๊ตฌ๋ณํ ๊น์? ๊ทธ๋ฆฌ๊ณ ๊ทธ๊ฒ์ด ์๋ฒ ์ธก ๋ ๋๋ง์ ํ์ํ ์ฐจ๋ณํ๊ฐ ์๋๊น์?
๊ฐ๋ฐ์๊ฐ ๊ทธ๋ ๊ฒ ํ๊ธฐ ์์ํ๋ค๋ฉด "ํ ์ ์๊ธฐ" ๋๋ฌธ์ ์์ฑ์ ์ฌ์ฉํ๋ ๊ฒ๊ณผ "๋ฐ๋์" ํด์ผ ํ๊ธฐ ๋๋ฌธ์ ์์ฑ์ ์ฌ์ฉํ๋ ๊ฒ์ ์ด๋ป๊ฒ ๊ตฌ๋ณํ ๊น์?
์ฃ์กํฉ๋๋ค. ์ ๊ฐ ํํ์ ์๋ชปํ์ ์๋ ์์ต๋๋ค. ๋๋ ๊ทธ๊ฒ์ด ๊ฐ์ฅ ์ผ๊ด๋ ๊ฒฐ๊ณผ๋ฅผ ์ค ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ๊ฐ๋ฐ์๋ค์ด sigil์ ์ฌ์ฉํ ๊ฐ๋ฅ์ฑ์ด ์๋ค๋ ๊ฒ์ ์๋ฏธํ์ต๋๋ค. ๊ฐ์ฒด ๋ฐ ๋ฐฐ์ด๊ณผ ๊ฐ์ ๊ธฐ๋ณธ ๋ฐ์ดํฐ ๋๋ ํ๋ถํ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ๋ฐ ์ฌ์ฉํ ์ ์์ผ๋ฉฐ ํญ์ ์๋ํฉ๋๋ค. ์์ฑ์ ์ด๊ธฐ ๊ตฌ์ฑ์ ๋ ๋ง์ด ์ฌ์ฉ๋๋ ๊ฒฝํฅ์ด ์๊ธฐ ๋๋ฌธ์ ๋ฐํ์์ ์์ฑ์ผ๋ก ์์ ํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์ผ๋ก ์์ฑ์ผ๋ก ์์ ํ๋ ๊ฒ๋ณด๋ค ์ ํธ๋๋ค๊ณ ์๊ฐํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ ๊ทธ๊ฒ์ด ์๋ฒ ์ธก ๋ ๋๋ง์ ํ์ํ ์ฐจ๋ณํ๊ฐ ์๋๊น์?
์๋ฒ์์ sigil์ด ์์ฑ์ ์ค์ ํ๋ ๊ฒ์ผ๋ก ๋์ฒด๋๋ ๊ฒฝ์ฐ์ผ ์ ์์ต๋๋ค.
์๋ฒ์์ sigil์ด ์์ฑ์ ์ค์ ํ๋ ๊ฒ์ผ๋ก ๋์ฒด๋๋ ๊ฒฝ์ฐ์ผ ์ ์์ต๋๋ค.
sigil์ ์ด์ ๊ฐ ๋น๋์ค์ currentTime ๊ณผ ๊ฐ์ ์์ฑ์ผ๋ก ์กด์ฌํ์ง ์๋ ์์ฑ์ธ ๊ฒฝ์ฐ ์๋ํ์ง ์์ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
"ํ ์ ์๊ธฐ ๋๋ฌธ์" ์์ฑ์ ์ฌ์ฉํ๋ ๊ฒ๊ณผ "ํด์ผ"ํ๊ธฐ ๋๋ฌธ์ ์์ฑ์ ์ฌ์ฉํ๋ ๊ฒ์ ๊ตฌ๋ณํฉ๋๋ค.
์์ฑ์ด๋ ์์ฑ์ ์ต์ ํ๋ก ์ฌ์ฉํ๊ธฐ๋ก ์ ํํ๋ ์ด์ (์: ์์ฑ์ ์ ํธํ๋ SSR ๋ ์์ฑ์ ์ ํธํ๋ ํด๋ผ์ด์ธํธ ์ธก ๋ ๋๋ง)์ ์์ฑ์ผ๋ก๋ง ์กด์ฌํ๊ฑฐ๋ ์์ฑ์ผ๋ก๋ง ์กด์ฌํ๋ ๊ฒ์๋ ์์ ํ ๋ค๋ฅธ ์ด์ ๊ฐ ์๊ธฐ ๋๋ฌธ์ ์ด ์ฐจ๋ณํ๊ฐ ์ค์ํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ฌ์ฐ.
์๋ฒ ์ธก ๋ ๋๋ง๊ณผ ๊ด๋ จํ์ฌ ์ฌ์ฉ์ ์ ์ ์์ ์์ฑ์ ์์ฑ์ ๋งคํํ๋ ๋ฐฉ๋ฒ์ React์ ์๋ฆฌ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ฝ๋์ฉ API๋ฅผ ์ ๊ณตํ์ฌ ํด๋น ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์ต๋๊น?
๋ ๊ตฌ์ฒด์ ์ผ๋ก ๋งํ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์ ์ํฉ๋๋ค.
ReactDOM.defineCustomElementProp(elementName, propName, domPropertyName, htmlAttributeName, attributeSerializer)
์:
// 'muted' can be set as either a property or an attribute.
ReactDOM.defineCustomElementProp('x-foo', 'muted', 'muted', 'muted')
// 'currentTime' can only be set as a property.
ReactDOM.defineCustomElementProp('x-foo', 'currentTime', 'currentTime', null)
// 'my-attribute' can only be set as an attribute.
ReactDOM.defineCustomElementProp('x-foo', 'my-attribute', null, 'my-attribute')
// 'richData' can be set as either a property or an attribute.
// When setting as an attribute, set it as a JSON string rather than "[object Object]".
ReactDOM.defineCustomElementProp('x-foo', 'richData', 'richData', 'richdata', JSON.stringify)
์์ฑ( htmlAttributeName
์ด null์ธ ๊ฒฝ์ฐ)์ผ ์ ์๋ ํญ๋ชฉ์ ๊ฒฝ์ฐ SSR์ ๋ ๋๋ง์ ๊ฑด๋๋ฐ๊ณ ํด๋ผ์ด์ธํธ์์ ์ํํฉ๋๋ค.
์์ฑ( domPropertyName
์ด null์ธ ๊ฒฝ์ฐ)์ผ ์ ์๋ ํญ๋ชฉ์ ๊ฒฝ์ฐ React๋ ํ์ฌ v16์์์ ๊ฐ์ด setAttribute()
๋ฅผ ํธ์ถํฉ๋๋ค.
๋ ๋ค์ผ ์ ์๋ ๊ฒฝ์ฐ React๋ ๊ฐ์ฅ ์ต์ ์ ์ ๋ต์ ์ ํํ ์ ์์ต๋๋ค. ์๋ง๋ ๊ทธ๊ฒ์ ํญ์ ํด๋ผ์ด์ธํธ ์ธก์์ ์์ฑ์ผ๋ก ์ค์ ํ์ง๋ง ์๋ฒ ์ธก ์์ฑ์ผ๋ก ์ค์ ํ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค. ์๋ง๋ ์ฒ์์๋ ์์๋ฅผ ์์ฑํ ๋ ์์ฑ์ผ๋ก ์ค์ ํ์ง๋ง ๋์ค์ vdom์์ ํจ์นํ ๋ ์์ฑ์ผ๋ก ์ค์ ํ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค. ์๋ง๋ ๊ฐ์ด ์์ ์ ํ์ผ ๋ ์์ฑ์ผ๋ก๋ง ์ค์ ํ๋ค๋ ์๋ฏธ์ผ ๊ฒ์ ๋๋ค. ์ด์์ ์ผ๋ก React๋ ๋ด๋ถ ๊ตฌํ ์ธ๋ถ ์ฌํญ์ผ๋ก ์ํ ๋๋ง๋ค ์ ๋ต์ ๋ณ๊ฒฝํ ์ ์์ด์ผ ํฉ๋๋ค.
React๊ฐ defineCustomElementProp()
๊ฐ ํธ์ถ๋์ง ์๊ณ HTML ์ฌ์์ ์ ์ญ ์์ฑ ๋๋ ์์ฑ์ผ๋ก ์ ์๋์ง ์์ prop์ ๋ฐ๊ฒฌํ๋ฉด React๋ ์ผ๋ถ ๊ธฐ๋ณธ ๋
ผ๋ฆฌ๋ฅผ ๊ตฌํํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์๋ง๋:
๊ทธ๋ฌ๋ ์ด์จ๋ ์ด๊ฒ์ ๋ณ๋์ API๋ก ์ ์งํจ์ผ๋ก์จ JSX ๋ฐ props
๊ฐ์ฒด๋ React ๊ตฌ์ฑ ์์ ๋ฐ ์ฌ์ฉ์ ์ ์๊ฐ ์๋ HTML ์์์ ๋ง์ฐฌ๊ฐ์ง๋ก ๋จ์ผ ๋ค์์คํ์ด์ค ๋ด์์ ๊นจ๋ํ๊ฒ ์ ์ง๋ฉ๋๋ค.
๊ณผ๋ํ ์๊ฒฌ์ ๋ํด ์ ๊ฐ์ค๋ฝ๊ฒ ์๊ฐํ์ง๋ง ์์ ์ ์์ ๋ํด ๊ณต์ ํ๊ณ ์ถ์ ๋ ๋ค๋ฅธ ์ด์ ์ด ์์ต๋๋ค.
์ด๋ฌํ ReactDOM.defineCustomElementProp()
ํธ์ถ์ ์ฌ์ฉ์ ์ ์ ์์ ์์ฑ์๊ฐ ์ ์ง ๊ด๋ฆฌํ๋ JS ํ์ผ์์ ์ ๊ณต๋ ์ ์์ต๋๋ค(์ฌ์ฉ์ ์ ์ ์์๊ฐ ์ ์ง/๋ฐฐํฌ๋๋ ์์น์ ๋์ผํ ์ ์ฅ์). ์์ฑ/์์ฑ์ด ์๊ฒฉํ๊ฒ 1:1๋ก ์ผ์นํ๋ ์ฌ์ฉ์ ์ง์ ์์์๋ ํ์ํ์ง ์์ต๋๋ค. ๋ฐ๋ผ์ ์ด ๊ถ์ฅ ์ฌํญ์ ๋ฐ๋ฅด์ง ์๋ ์ฌ์ฉ์ ์ง์ ์์ ์์ฑ์๋ง React ํตํฉ ํ์ผ์ ์ ๊ณตํด์ผ ํฉ๋๋ค. ์์ฑ์๊ฐ ์ ๊ณตํ์ง ์๋ ๊ฒฝ์ฐ(์: ์ฌ์ฉ์ ์ ์ ์์ ์์ฑ์๊ฐ React์ ๊ด์ฌ์ด ์๊ธฐ ๋๋ฌธ์) React ์ฑ ๋ด์์ ํด๋น ์ฌ์ฉ์ ์ ์ ์์๋ฅผ ์ฌ์ฉํ๋ ์ฌ๋๋ค์ ์ปค๋ฎค๋ํฐ๋ ํด๋น ํตํฉ ํ์ผ์ ์์ฉํ๊ธฐ ์ํด ์ค์ ์ ์ฅ์๋ฅผ ์์ฒด ๊ตฌ์ฑํ ์ ์์ต๋๋ค.
์ด๋ฌํ ์ค์ ์ง์คํ์ ๊ฐ๋ฅ์ฑ์ ์ฌ์ฉ์ ์ ์ ์์์ ๋ชจ๋ ์ฌ์ฉ์๊ฐ ํญ์ sigil์ ์ฌ์ฉํ์ฌ ๋ช ์์ ์ด์ด์ผ ํ๋ ์๋ฃจ์ ๋ณด๋ค ๋ฐ๋์งํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
์ต์ 3์ด ์ ํธ๋์ง๋ง ์ด๋ ์์ฒญ๋ ๋ณํ์ ๋๋ค... ๋ฐ๋์ ๊ฒฝ์ฐ๋ ์ด๋ป์ต๋๊น? ์์ฑ์ props๊ฐ ์๋ ์ ๋์ฌ๊ฐ ์์ต๋๊น?
React์ Sigils, ๋๋ ๊ทธ๊ฒ์ ๋ํด ์ด๋ป๊ฒ ๋๋ผ๋์ง ๋ชจ๋ฆ
๋๋ค. JSX ์ฌ์์ ๋ธ๋ผ์ฐ์ ์ฌ์์ ์ง๋์น๊ฒ ์์กดํ๊ฑฐ๋ ์์กดํ์ง ์๋ ๋ณดํธ์ ์ธ ๊ฒ์ผ๋ก ๊ฐ์ฃผ๋์ด์ผ ํฉ๋๋ค. ํนํ ์ด์ ๋ฒ์ ๊ณผ์ ํธํ์ฑ์ผ๋ก ์ธํ ๋ถ๊ท์น์ฑ์ ๋ํด์๋ ๋ ๊ทธ๋ ์ต๋๋ค. obj[prop] = value
์ obj.setAttributes(props, value)
๋ค๋ฅด๊ฒ ๋์ํ๋ ๊ฒ์ ๋ถํํ ์ผ์ด์ง๋ง ๋ธ๋ผ์ฐ์ API๋ฅผ ์ ์ฒด์ ์ผ๋ก ๋ณด๋ฉด ๋๋ผ์ด ์ผ์ด ์๋๋๋ค. @ : []
๋ ๊ตฌํ ์ธ๋ถ ์ฌํญ์ ํ๋ฉด์ผ๋ก ์ ์ถํ๊ณ ์๋ฐ์คํฌ๋ฆฝํธ ์ค์ฌ ์ ๊ทผ ๋ฐฉ์๊ณผ ๋ชจ์๋ฉ๋๋ค. ๋ฐ๋ผ์ ๋ค์์ ์ํํ๋ ์ฌ์์ด ์์ผ๋ฉด ์๋ชป๋ ์๊ฐ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. const data = <strong i="8">@myFunction</strong> // -> "[object Object]"
์น ๊ตฌ์ฑ ์์์ ์์กดํด์ผ ํ๋ ๊ฒฝ์ฐ ์๋ฏธ ์ฒด๊ณ๊ฐ React ๋ฐ JSX์์ ์จ๊ฒจ์ง๊ณ ์ฃผ์ ๋ณ๊ฒฝ ์ฌํญ์ด ๋์
๋์ง ์๋๋ก ํ๋ฉด ๊ธฐ์ ๊ฒ์
๋๋ค. ๋ชจ๋ ์ต์
์์ ref => ...
๋ฅผ ๊ทธ๋๋ก ๋๋ ๊ฒ์ด ๋์๊ฒ ์ ๋ฆฌํ ๊ฒ ๊ฐ์ต๋๋ค. ref
๋ ๊ฐ์ฒด์ ์ก์ธ์คํ๋๋ก ํน๋ณํ ์ค๊ณ๋์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ ์ด๋ ๊ฐ๋ฐ์๋ ๋ฌด์จ ์ผ์ด ์ผ์ด๋๊ณ ์๋์ง ์ ํํ ์๊ณ ์๊ณ , ์ธ์ฅ ๋์ถ๋ ์๊ณ ๊ธฐ์กด ํ๋ก์ ํธ๋ฅผ ๊นจ๋จ๋ฆด ์ ์๋ ์๋ก์ด ์์ฑ๋ ์์ต๋๋ค.
@LeeCheneler
์ต์ 3์ด ์ ํธ๋์ง๋ง ์ด๋ ์์ฒญ๋ ๋ณํ์ ๋๋ค... ๋ฐ๋์ ๊ฒฝ์ฐ๋ ์ด๋ป์ต๋๊น? ์์ฑ์ props๊ฐ ์๋ ์ ๋์ฌ๊ฐ ์์ต๋๊น?
์ ํ๊ธฐ์ ์ธ ๋ณํ๊ฐ ๋ ๊น์? ๊ธฐ๋ณธ๊ฐ์ธ ์์ฑ์ ํ์ฌ ๋์์ ๊ทธ๋๋ก ์ ์ง๋ฉ๋๋ค. sigil์ ์ตํธ์ธ์ด๋ฉฐ ๊ฐ๋ฐ์๋ ํ์ฌ ref
๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์ ์ ์ ์์์ JS ์์ฑ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ์ฝ๋์ ๋ถ๋ถ์ ๋์ฒดํ๋ ๋ฐ ์ฌ์ฉํ ๊ฒ์
๋๋ค.
@drcmda
๊ธฐ์กด ํ๋ก์ ํธ๋ฅผ ์ค๋จ์ํฌ ์ ์๋ ์๋ก์ด ์์ฑ๋ ์์ต๋๋ค.
์ด๊ฒ์ด ๋ฌด์์ ์๋ฏธํ๋์ง ๋ช ํํ ํ ์ ์์ต๋๊น?
์ฐธ๊ณ ๋ก ํ ๋ก ์ ๋ฐ๋ฅด๋ ์ฌ๋์ ์ํด React ํ ๊ตฌ์ฑ์์ด ์ ์ํ ๋ค์ฏ ๋ฒ์งธ ์ต์ ์ผ๋ก RFC๋ฅผ ์ ๋ฐ์ดํธํ์ต๋๋ค.
@robdodson
๋๋ ์ด๊ฒ์ ์ธ๊ธํ๊ณ ์์๋ค:
์ต์ 4: ์์ฑ ๊ฐ์ฒด ์ถ๊ฐ
๋จ์
ํ๊ธฐ์ ์ธ ๋ณํ์ผ ์ ์์ต๋๋ค
์ต์ 5๊ฐ ๊ฐ์ฅ ์์ ํ ๊ฒ ๊ฐ์ต๋๋ค. ์ํ๊ณ๊ฐ ์์ง "ํ์ " ๋จ๊ณ์ ์๊ธฐ ๋๋ฌธ์ "์์์ " API์ ๋ํ ๊ฒฐ์ ์ ๋ด๋ฆด ํ์ ์์ด ๊ธฐ๋ฅ์ ์ถ๊ฐํ ์ ์์ต๋๋ค. ์ฐ๋ฆฌ๋ ํญ์ ๋ช ๋ ์์ ๊ทธ๊ฒ์ ๋ค์ ๋ฐฉ๋ฌธํ ์ ์์ต๋๋ค.
Polymer์ paper-input ์์์๋ 37๊ฐ์ ์์ฑ์ด ์์ผ๋ฏ๋ก ๋งค์ฐ ํฐ ๊ตฌ์ฑ์ ์์ฑํฉ๋๋ค. ๊ฐ๋ฐ์๊ฐ ์ฑ์์ ๋ง์ ์ฌ์ฉ์ ์ง์ ์์๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ์์ฑํด์ผ ํ๋ ๊ตฌ์ฑ์ด ๋ง์ ์ ์์ต๋๋ค.
๋ด ์ธ์์ React์ ์ฌ์ฉ์ ์ ์ ์์ ์ฌ์ฉ์๊ฐ ๊ฒฐ๊ตญ ์ฑ๋ณ ๋์/์ฌ์ฉ์ ์ ์๋ฅผ ์ํด ์ผ๋ถ ์ฌ์ฉ์ ์ ์ ์์๋ฅผ React ๊ตฌ์ฑ ์์๋ก ๋ํํ๊ธฐ๋ฅผ ์ํ๋ค๋ ๊ฒ์ ๋๋ค. ๋ชจ๋๊ฐ ์ด๋ฏธ ์ผ์ ธ์๋ ๊ฒฝ์ฐ๋์ด ๊ฒฝ์ฐ์ ๋ ์ข์ ๋ง์ด๊ทธ๋ ์ด์ ์ ๋ต ๊ตฌ์ฑ ์์, ์๋ฅผ ๋ค๋ฉด ๋ฐ์์ฉ
import XButton from './XButton';
์ ์ํด ์์ฑ๋ฉ๋๋ค.
export default ReactDOM.createCustomElementType(...)
์ด๋ฅผ ํตํด React ๊ตฌ์ฑ ์์๋ฅผ ํน์ ์์ ์ ์ฌ์ฉ์ ์ ์ ์์๋ฅผ ์ฌ์ฉํ๋(๋๋ ์ฌ์ฉํ์ง ์๋) ์ฌ์ฉ์ ์ ์ ๊ตฌ์ฑ ์์๋ก ๊ต์ฒดํ ์ ์์ต๋๋ค.
๋ฐ๋ผ์ ์ฌ๋๋ค์ด ์ํธ ์ด์ฉ์ฑ ์ง์ ์์ React ๊ตฌ์ฑ ์์๋ฅผ ๋ง๋ค๋ ค๋ ๊ฒฝ์ฐ ๊ฐ๋ ฅํ ๋์ฐ๋ฏธ๋ฅผ ์ ๊ณตํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ๋ํ ์ฌ๋๋ค์ด ์ฌ์ฉํ๋ ์ฌ์ฉ์ ์ง์ ์์์ ๋ํ ๊ตฌ์ฑ์ ๊ณต์ ํ ๊ฐ๋ฅ์ฑ๋ ์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ๊ถ๊ทน์ ์ผ๋ก ์ํ๊ณ๊ฐ ์์ ํ๋๋ฉด ๊ตฌ์ฑ ์๋ ์ ๊ทผ ๋ฐฉ์์ ์ฑํํ ์ ์์ต๋๋ค.
์ฌ๊ธฐ์์ ๋ค์ ๋จ๊ณ๋ ๋ชจ๋ ์ผ๋ฐ์ ์ธ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ์ถฉ์กฑํ๊ธฐ ์ํด ๊ตฌ์ฑ์ด ์ด๋ป๊ฒ ๋ณด์ฌ์ผ ํ๋์ง์ ๋ํ ์์ธํ ์ ์์ ์์ฑํ๋ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ์ฌ์ฉ์ ์ ์ ์์ + React ์ฌ์ฉ์์๊ฒ ์ถฉ๋ถํ ๋งค๋ ฅ์ ์ด์ด์ผ ํฉ๋๋ค. ์๋ํ๋ฉด ๊ทธ๊ฒ์ด ์ผ๋ฐ์ ์ธ ์ฌ์ฉ ์ฌ๋ก(์: ์ด๋ฒคํธ ์ฒ๋ฆฌ)์ ์๋ตํ์ง ์์ผ๋ฉด ๊ธฐ๋ฅ์ด ์ฅํฉํจ์ ์์ํ ์ถฉ๋ถํ ์ด์ ์ ์ ๊ณตํ์ง ๋ชปํ๋ ๋ฆผ๋ณด์ ๋น ์ง๊ฒ ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ๋๋ค. .
๋ด ์ด์ ์๊ฒฌ์ ๋ฐํ์ผ๋ก ์์ฑํ๋ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
const XFoo = ReactDOM.createCustomElementType('x-foo', {
propName1: {
propertyName: string | null,
attributeName: string | null,
attributeSerializer: function | null,
eventName: string | null,
}
propName2: {
}
...
});
๊ทธ๋ฌ๋ฉด ๋ ผ๋ฆฌ๋ XFoo ์ธ์คํด์ค์ ๊ฐ React ์ํ์ ๋ํด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
eventName
๊ฐ null์ด ์๋ ๊ฒฝ์ฐ prop ๊ฐ(ํจ์๋ก ๊ฐ์ )์ ํธ์ถํ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ก ๋ฑ๋กํฉ๋๋ค.propertyName
๊ฐ null์ด ์๋ ๊ฒฝ์ฐ ์์ ์์ฑ์ prop ๊ฐ์ผ๋ก ์ค์ ํฉ๋๋ค.attributeName
๊ฐ null์ด ์๋ ๊ฒฝ์ฐ ์์ ์์ฑ์ ๋ฌธ์์ดํ๋ prop ๊ฐ์ผ๋ก ์ค์ ํฉ๋๋ค. attributeSerializer
๊ฐ null์ด ์๋ ๊ฒฝ์ฐ ์ด๋ฅผ ์ฌ์ฉํ์ฌ prop ๊ฐ์ ๋ฌธ์์ดํํฉ๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด '' + propValue
๋ฉ๋๋ค.Polymer์ paper-input ์์์๋ 37๊ฐ์ ์์ฑ์ด ์์ผ๋ฏ๋ก ๋งค์ฐ ํฐ ๊ตฌ์ฑ์ ์์ฑํฉ๋๋ค.
๊ตฌ์ฑ์ outlier props์๋ง ํ์ํ๋ค๊ณ ์ ์ํ๊ณ ์ถ์ต๋๋ค. ๊ตฌ์ฑ์ ํฌํจ๋์ง ์์ XFoo ์ธ์คํด์ค์ ๋ชจ๋ ์ํ์ ๋ํด ๊ธฐ๋ณธ์ ์ผ๋ก ๋ค์๊ณผ ๊ฐ์ด ์ค์ ํฉ๋๋ค.
eventName: the prop name,
propertyName: the prop name,
attributeName: camelCaseToDashCase(the prop name),
๋๋ ์ด๋ฒคํธ๋ฅผ ๋ณ๋์ ๋ค์์คํ์ด์ค์ ๋ณด๊ดํ๋ ๊ฒ์ด ํฉ๋ฆฌ์ ์ผ ์ ์์ต๋๋ค. ์ด ๊ฒฝ์ฐ ๋ง์ง๋ง ์ฃผ์์์ eventName
์ ๊ด๋ จ๋ ๋ชจ๋ ๊ฒ์ ์ ๊ฑฐํ๊ณ ๋์ ์ด๋ฒคํธ๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ๋ฑ๋กํฉ๋๋ค.
<XFoo prop1={propValue1} prop2={propValue2} events={event1: functionFoo, event2: functionBar}>
</XFoo>
@gaearon @effulgentsia ์ต์ 1๊ณผ ์ต์ 5์ ์กฐํฉ์ ๋ํด ์ด๋ป๊ฒ ์๊ฐํ์๋์?
์ต์ 1์ ์ฌ์ฉํ๋ฉด ์ฌ์ฉ์ ์ง์ ์์์ ์ผ๋ฐ ์ฌ์ฉ์๊ฐ ํ๋ถํ ๋ฐ์ดํฐ๋ฅผ ๋ ์ฝ๊ฒ ์ ๋ฌํ ์ ์์ต๋๋ค. ์ ๋ ์ฑ์ ๋ง๋ค๊ณ ์๊ณ ๋ช ๊ฐ์ง ์ฌ์ฉ์ ์ ์ ์์๋ฅผ ์ฌ์ฉํ๋ ค๋ ์๋๋ฆฌ์ค๋ฅผ ์์ํ๊ณ ์์ต๋๋ค. ๋๋ ๊ทธ๋ค์ด ์ด๋ป๊ฒ ์๋ํ๋์ง ์ด๋ฏธ ์๊ณ ์๊ณ ๊ทธ๊ฒ์ ๋ํ ๊ตฌ์ฑ์ ์์ฑํ๊ณ ์ถ์ ์ ๋๋ก ํฌ์ํ์ง ์์์ต๋๋ค.
์ต์ 5๋ ์ฑ ์ ์ฒด์์ ์ข ์ด ์ ๋ ฅ๊ณผ ๊ฐ์ ๊ฒ์ ์ฌ์ฉํ๊ณ ์ ์ฒด API๋ฅผ ํ์ ๋ชจ๋ ์ฌ๋์๊ฒ ๊ณต๊ฐํ๋ ค๋ ์ฌ๋๋ค์ ์ํ ๊ฒ์ ๋๋ค.
์ต์ 1์ SSR์ ๊ฒฝ์ฐ ๋ฐ๊ฒฌ์ ๋ฐฉ๋ฒ์ ์๋ฒ์์ ๋ ๋๋งํ๋ ๊ฒฝ์ฐ ํญ์ ์์ฑ์ ์ฌ์ฉํ ์ ์์ต๋๋ค. camelCase ์์ฑ์ dash-case ์์ฑ์ผ๋ก ๋ณํ๋ฉ๋๋ค. ์ด๋ ์น ๊ตฌ์ฑ ์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ ๋ฐ์ ๊ฑธ์ณ ๊ฝค ์ผ๋ฐ์ ์ธ ํจํด์ธ ๊ฒ ๊ฐ์ต๋๋ค.
๋๋ option1 + option5 ์กฐํฉ์ ์์ด๋์ด๋ฅผ ์์ฃผ ์ข์ํฉ๋๋ค. ๋๋ถ๋ถ์ ์ฌ์ฉ์ ์ ์ ์์์ ๋ํด ๋ค์์ ์๋ฏธํฉ๋๋ค.
<x-foo prop1={propValue1}>
์์๋๋ก ์๋ํฉ๋๋ค. prop1์ ์์ฑ ํด๋ผ์ด์ธํธ ์ธก ๋ฐ (๋์ ๋์๋ฌธ์) ์๋ฒ ์ธก ์์ฑ์ผ๋ก ์ค์ ๋ฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ ์ฌ๋๋ค์ ์์ ๋ด์ฉ์ด ์์ ์๊ฒ ์ ํฉํ์ง ์์ ๊ฒฝ์ฐ ์ต์ 5๋ก ์ ํํ ์ ์์ต๋๋ค.
React 16์ด ์๋ํ๋ ๋ฐฉ์์์ ํ๊ธฐ์ ์ธ ๋ณํ๊ฐ ๋ ๊ฒ์ ๋๋ค. ์ด๋ฌํ ํ์์ ๊ฒฝํํ ์ฌ๋์(์: ์์ฑ์ด ์ง์๋์ง ์๋ ์์ฑ์ ๊ฐ์ง ์ฌ์ฉ์ ์ ์ ์์๋ฅผ ์ฌ์ฉํ๊ณ ์๋ ๊ฒฝ์ฐ) ์ต์ 5๋ก ์ ํํ ์ ์์ง๋ง ์ฌ์ ํ ์ค๋จ์ ๋๋ค. ๋๋ ๊ทธ๊ฒ์ด ์์ฉ ๊ฐ๋ฅํ์ง ๊ฒฐ์ ํ๊ธฐ ์ํด React ํ์ ๋งก๊น๋๋ค.
์, ๊ธฐ์ฐจ @robdodson ๐คฆโโ๏ธ ์์ ๋นจ๋ฆฌ ์ฝ์ด์
์ต์ 5๋ ํฉ๋ฆฌ์ ์ด๊ณ ๊ฐ๋จํด ๋ณด์ ๋๋ค.
@effulgentsia ๊ฐ ํฅํ๊ณ ์๋ ๋ญ๋๋ค . ํ ์ ์๋ ์ด์ ๊ฐ ์์ต๋๊น?
const XFoo = ReactDOM.createCustomElementType('x-foo', {
propName1: T.Attribute,
propName2: T.Event,
propName3: T.Prop
})
์๋๋ฉด ๋จ์ผ ์ํ์์ ์ฌ๋ฌ ์ ํ์ ์ง์ํ๋ ๊ฒ์ด ๊ฐ์น๊ฐ ์์ต๋๊น?
๋๋ @effulgentsia๋ฅผ ํตํด ์ด ํ๋ฆ์ ์ฃผ์ ํ ๊ฒ์ ๋๋ค.
๊ฐ์ด ํจ์์ธ ๊ฒฝ์ฐ:
eventName: ์ํ ์ด๋ฆ,
๋ ๋ค๋ฅธ:
propertyName: ์ํ ์ด๋ฆ,
attributeName: camelCaseToDashCase(์ํ ์ด๋ฆ),
ํจ์ ์ํ์ด ์ด๋ฒคํธ๋ก ๊ธฐ๋ณธ ์ค์ ๋๋ ๊ฒ์ ์ํ์ง ์๊ณ propertyName๊ณผ attributeName์ ๋ชจ๋ ํ ๋นํ๋ ๊ฒ์ด ํฉ๋ฆฌ์ ์ด๋ผ๊ณ ์๊ฐํฉ๋๊น? ์์ ์ง๋ฌธ์ ๋ชจ๋ฐฉํ๊ธฐ ์ํด ์ธ์ ๋ ๋ค ์ง์๋๊ธฐ๋ฅผ ์ํ์ญ๋๊น? ๐
@LeeCheneler :
๋ฌธ์ ์์ฝ์ ์ต์ 1 ์ฐฌ์ฑ์์ ์ธ์ฉ:
Polymer ๋๋ Skate์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก ์์ฑ๋ ๋ชจ๋ ์์๋ ๋ ธ์ถ๋ ์์ฑ์ ๋ท๋ฐ์นจํ๋ ์์ฑ์ ์๋์ผ๋ก ์์ฑํฉ๋๋ค. ์ด๋ฌํ ์์๋ ๋ชจ๋ ์์ ์ ๊ทผ ๋ฐฉ์์ผ๋ก "์ ์ ์๋"ํด์ผ ํฉ๋๋ค. ๋ฐ๋๋ผ ๊ตฌ์ฑ ์์๋ฅผ ์ง์ ์์ฑํ๋ ๊ฐ๋ฐ์๋ ์์ฑ์ ์ฌ์ฉํ์ฌ ์์ฑ ์ ์ง์ํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ์ด๋ HTML5 ์์(
<video>
,<audio>
๋ฑ)๊ฐ ์ผ๋ง๋ ํ๋์ ์ธ์ง(์ฆ,<input>
์ ๊ฐ์ ์ด์ํ ๊ฒ์ด ์๋)์ ๋ฐ์ํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ๊ตฌํ๋์์ต๋๋ค.
์ด๊ฒ์ด propertyName๊ณผ attributeName์ ๋ชจ๋ ํ ๋นํ๋ ๊ฒ์ด ํฉ๋ฆฌ์ ์ธ ์ด์ ์ ๋๋ค. ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๋ฐ๋ฅด๋ ์์์ ์ค์ ์ฌ๋ก๋ฅผ ๋ฐ์ํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ React๊ฐ ์ด๋ฅผ ์ธ์ํ๊ฒ ํจ์ผ๋ก์จ React๋ ์ํฉ์ ๋ฐ๋ผ ์ด๋ค ๊ฒ์ ์ฌ์ฉํ ์ง ๊ฒฐ์ ํ ์ ์์ต๋๋ค. ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๋ฐ๋ฅด์ง ์๊ณ ํด๋น ์์ฑ์ด ์๋ ์ผ๋ถ ์์ฑ ๋ฐ/๋๋ ํด๋น ์์ฑ์ด ์๋ ์ผ๋ถ ์์ฑ์ด ์๋ ์ฌ์ฉ์ ์ง์ ์์์ ๊ฒฝ์ฐ React๋ ์ด๋ฅผ ์ธ์ํด์ผ SSR ๋ฐ ์์ฑ ์ค์ ์์ฑ์ด ์๋ ์์ฑ์ด ๋ ๋๋ง๋์ง ์์ต๋๋ค. -less-attributes๋ ํด๋ผ์ด์ธํธ ์ธก ๋ ๋๋ง ์ค์ setAttribute()๋ฅผ ์ฌ์ฉํ์ฌ ์ค์ ํ ์ ์์ต๋๋ค.
๊ทํ์ ์ ์์ผ๋ก ๋ค์๊ณผ ๊ฐ์ ๋นํธ ๊ฒฐํฉ ํ๋๊ทธ๋ก ์ ์ฌ์ ์ผ๋ก ์ํํ ์ ์์ต๋๋ค.
propName1: T.Property | T.Attribute,
๊ทธ๋ฌ๋ ์ด๋ ์์ฑ ์ด๋ฆ์ด ์์ฑ ์ด๋ฆ๊ณผ ๋ค๋ฅด๋ค๋ ๊ฒ์ ํํํ๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํ์ง ์์ต๋๋ค(์: camelCase์์ dash-case๋ก). ๋ํ SSR ๋์ ๋ฆฌ์น ๊ฐ์ฒด๋ฅผ ์์ฑ์ผ๋ก ์ง๋ ฌํํ๋ ๋ฐฉ๋ฒ์ ํํํ๋ ๋ฐฉ๋ฒ๋ ์ ๊ณตํ์ง ์์ต๋๋ค("[object Object]"์ ํ์ฌ ๋์์ ์ ์ฉํ์ง ์์).
ํจ์ ์ํ์ด ์ด๋ฒคํธ๋ก ๊ธฐ๋ณธ ์ค์ ๋๋ ๊ฒ์ ์ํ์ง ์๋๋ค๊ณ ์๊ฐํฉ๋๋ค.
๋ค, ์ ๋ ๊ทธ ๋ง์ ๋์ํ๋ ๊ฒ ๊ฐ์ผ๋, ํ์ ๋๊ธ ์ ๋๋ค. ๋ด ์ฃผ์ ๋ฅผ ํ์ธ ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค!
์ด์ ์ ์ ์ ๋ ์ฅํฉํ ๋ฒ์ ์ ๋ํ ์๊ฐ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
const XFoo = ReactDOM.createCustomElementType('x-foo', {
UNREFLECTED_ATTRIBUTES: [
'my-attr-1',
'my-attr-2',
],
UNREFLECTED_PROPERTIES: [
'myProp1',
'myProp2',
],
REFLECTED_PROPERTIES: {
// This is default casing conversion, so could be omitted.
someVeryLongName1: 'some-very-long-name-1',
// In case anyone is still using all lowercase without dashes.
someVeryLongName2: 'someverylongname2',
// When needing to define a function for serializing a property to an attribute.
someRichData: ['some-rich-data', JSON.stringify],
},
});
๊ทธ๋ฆฌ๊ณ ์์ ์ฝ๋ ์ฃผ์์ ๋ฐ๋ผ ๋ชจ๋ ๋ฐ์๋ ์์ฑ์ ์ ์ํ ํ์๊ฐ ์์ผ๋ฉฐ ์์ฑ ์ด๋ฆ์ด ๋์ ๋์๋ฌธ์ ๋ฒ์ ์ธ ๋ฐ์๋ ์์ฑ์ผ๋ก ์๋์ผ๋ก ์ ์๋์ง ์์ ๋ชจ๋ ์์ฑ์ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ง์ ํฉ๋๋ค.
์ดํด๊ฐ ๋๋ค์ @effulgentsia ๐
๋๋ ๋น์ ์ ๋ ๋ฒ์งธ ์๋ฅผ ์ข์ํ์ง๋ง ๋ ๋ง์ ์ ํ์ด ์ถ๊ฐ๋๋ฉด ์กฐํฉ ํญ๋ฐ์ ์ด๋ ค ์์ง ์์ต๋๊น?
- UNREFLECTED_ATTRIBUTES
- UNREFLECTED_PROPERTIES
- UNREFLECTED_EVENTS
- REFLECTED_PROPERTIES_ATTRIBUTES
- REFLECTED_PROPERTIES_EVENTS
- REFLECTED_ATTRIBUTES_EVENTS
- REFLECTED_PROPERTIES_ATTRIBUTES_EVENTS
...
์ด์จ๋ ์ด๋ฒคํธ๋ฅผ ์ํ์ด๋ ์์ฑ๊ณผ ํผํฉํ๊ณ ์ถ์ง ์๋ค๊ณ ์๊ฐํ์ง๋ง ๐ค ์์ฑ๊ณผ ์ํ์ ์๋ง๋ ๋ชจ๋ฐฉํ๊ณ ์ถ์ ์ ์ผํ ๊ฒ์ ๋๋ค.
React์ Web Component ์ปค๋ฎค๋ํฐ ๋ชจ๋๊ฐ ๋ชจ๋ฒ ์ฌ๋ก์ ๋ถํฉํ ์ ์๋ ๊ธฐํ๊ฐ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. React๊ฐ ์ฌ๊ธฐ์์ ์๊ฒฌ์ ๊ฐ๋ ๊ฒ์ ๊ด๋ฒ์ํ ์ฑํ๊ณผ ์๊ฒฌ์ด ์๋ฐํ๋ ๋ฌด๊ฒ๋ก ์ธํด ์ฌ์ฉ์ ์ ์ ์์ ์์ฑ์๊ฐ ์ฌ๋ฐ๋ฅธ ๋ฐฉํฅ์ผ๋ก ์๋ด๋๋ ๋ฐ ํฐ ๋์์ด ๋ ๊ฒ์ ๋๋ค.
์ต์ 4์ ๊ตฌํ์ ์์ฑํ์ง๋ง ์์ฑ๊ณผ ์ด๋ฒคํธ๋ฅผ ์์ฑ์์ ๋ถ๋ฆฌํด์ผ ํ๋ ๋ฌธ์ ์ ํญ์ ์ฌ๋ก์กํ ์์ต๋๋ค. ์ด์์ ์ผ๋ก๋ ์ต์ 1์ ์ ํธํฉ๋๋ค. ์ค์ ๋ก๋ ํ์ถ๊ตฌ๊ฐ ์๋ ์ต์ 2๋ฅผ ์ ํธํฉ๋๋ค.
์ต์ 1์ด ์ด์์ ์ด์ง๋ง ํด๋น ์์ฑ(aria / data)์ด ์๋ ๋ง์ ์ ํ์ ์์ฑ์ด ์์ผ๋ฏ๋ก ์ด๋ฌํ ์์ฑ์ ๋ํ ์ถ๊ฐ ๋ฐ๊ฒฌ์ ๋ฐฉ๋ฒ์ด ํ์ํ๊ณ ์์์ ์์ฑ์ด ์์ด์ผ ํ๋
์ต์ 2๋ ์ฃผ์ ๋ณ๊ฒฝ ์ฌํญ์ด ์๋๋ฏ๋ก ์ ํธ๋ฉ๋๋ค. ์ธ์คํด์ค๊ฐ ์์ฑ๋๊ธฐ ์ ์ ์ฌ์ฉ์ ์ ์ ์์ ์ ์๊ฐ ๋ฑ๋ก๋๋(๋๋ ์์ฑ์ด ์ค์ ๋๊ธฐ ์ ์ ๋ก๋๋๋) ๋ชจ๋ ์ํฉ์์ ์๋ํฉ๋๋ค. ์ด ์ต์ ์ ๋ํ ์ ํ ๊ธฐ์ ์ Preact(cc @developit)์ด๋ฉฐ ์ง๊ธ๊น์ง ์ ์๋ํ์ต๋๋ค. ์ด ๊ฒฝ๋ก๋ฅผ ๋ฐ๋ผ๊ฐ๋ฉด ์ฑ๊ณต์ ์ธ React ๋ณํ์ผ๋ก ์ ์ฆ๋์์ผ๋ฉฐ ๋๋ถ๋ถ์ ์ํฉ์์ ์๋ํ๋ ํฉ๋ฆฌ์ ์ผ๋ก ๊ฐ๋ ฅํ๊ณ ์ค๋จ๋์ง ์๋ ๊ตฌํ์ ์ ๊ณตํฉ๋๋ค. ์ด์จ๋ , ๊ทธ๊ฒ์ React์ ๋จ๊ธฐ์ ์ธ ์๋ฃจ์ ์ ์ ๊ณตํ๋ ๋ฐ๋ฉด ๋ ๋์ ์๋ฃจ์ ์ ์ฅ๊ธฐ์ ์ผ๋ก ํ๊ฐ๋ฉ๋๋ค.
์ด๊ฒ์ด ์๋ํ์ง ์๋ ์ํฉ(์ํฉ s ?)์ ๊ฒฝ์ฐ - ์ฌ์ฉ์ ์ ์ ์์ ์ ์์ ์ง์ฐ ๋ก๋ฉ ๋ฐ ์ฐ๋ฆฌ๊ฐ ๋ค๋ฃจ์ง ์์ ๋ค๋ฅธ ๋ชจ๋ ๊ฒ - Incremental DOM์ด ์ํํ ๊ฒ๊ณผ ๊ฐ์ ํ์ถ ํด์น๊ฐ ๊ตฌํ๋ ์ ์์ต๋๋ค. ์ด๊ฒ์ @effulgentsia ๊ฐ ์ ์ํ๋ ๊ฒ๊ณผ ์ ์ฌํ์ง๋ง x
์ฌ์ฉ์ ์ ์ ์์ ์๋ก ํ์ฅํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ์๋น์๊ฐ ์ฌ์ฉ์ ์ ์ ์์๋ณ๋ก ์ด๋ฅผ ์ํํ๊ธฐ๋ฅผ ์ํ๋ฉด ์ฌ์ ํ ํ ์ ์์ต๋๋ค. ์๋ํ๋ฉด ๊ทธ๊ฒ์ ๋จ์ง ๊ธฐ๋ฅ์ด๊ธฐ ๋๋ฌธ์
๋๋ค. ์ด๋ฅผ ํตํด React๋ ๋ชจ๋ ์ฃ์ง ์ผ์ด์ค์ ๋ํ ์ฑ
์์ ์๋น์์๊ฒ ๋๊น์ผ๋ก์จ ์๊ฒฌ์ ๊ฐ๊ณ ํด์น๋ฅผ ๋ฒ์ด๋ ๋ชจ๋ ์ฌ์ฉ ์ผ์ด์ค๋ฅผ ๋ง์กฑ์ํฌ ์ ์์ต๋๋ค. ์ด๋ ์ด์ ์ @developit ๊ณผ ๋
ผ์ํ ๋ด์ฉ์ด๊ธฐ๋ ํฉ๋๋ค. ์ฌ๊ธฐ์ Preact / React ๊ฐ์ ์ ๋ ฌ์ ํฐ ์น๋ฆฌ๊ฐ ๋ ๊ฒ์
๋๋ค.
๋ฏธ๋์ HTML ์์ฑ์ ๋ํ ์ฐ๋ ค์ ๋ํด ์ด๊ฒ์ ์ฐ๋ฆฌ๊ฐ ํด๊ฒฐํ ์ ์๋ ๊ฒ์ด๋ฏ๋ก ์ฌ๊ธฐ์ ์ฐ๋ฆฌ๊ฐ ๊ทธ๊ฒ์ ๋ํด ๊ณ ๋ฏผํด์ผ ํ๋ค๊ณ ์๊ฐํ์ง ์์ต๋๋ค.
์ด๋ฌํ
ReactDOM.defineCustomElementProp()
ํธ์ถ์ ์ฌ์ฉ์ ์ ์ ์์ ์์ฑ์๊ฐ ์ ์ง ๊ด๋ฆฌํ๋ JS ํ์ผ์์ ์ ๊ณต๋ ์ ์์ต๋๋ค.
์ด๊ฒ์ ์ฌ์ฉ์ ์ ์ ์์ ๊ตฌํ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ณ ๊ตฌํ(์ด ๊ฒฝ์ฐ React)์ ์ฐ๊ฒฐํฉ๋๋ค. ์ ์๊ฐ์๋ ์ฌ์ฉ์ ์ ์ ์์ ์์ฑ์์๊ฒ ๋๋ฌด ํฐ ๋ถ๋ด์ ๋๋ค. ๊ฒ๋ค๊ฐ React๋ฅผ ์ฌ์ฉํ์ง ์๋ ์ ์์ ๊ฒฝ์ฐ ์ ์๋ฅผ ์ ๋ฌํ๋๋ก ์ค๋ํ๋ ๊ฒ์ ์๋ฌด๋ ์ํ์ง ์๋ ์ ์น ํ ๋ก ์ผ๋ก ์ด์ด์ง๋๋ค.
์ฌ์ฉ์๊ฐ ์ค์ ๋ก ์ฌ์ฉํ๋ ์์ฑ/์์ฑ๋ง์ผ๋ก ์ฌ์ฉ์ ์ ์ ์์์ ์ฌ์ฉ์๊ฐ ์ด๋ฌํ API๋ฅผ ํธ์ถํ๋ ๊ฒ์ ์ ์ํ๋ ๊ฒ์ ์ ์ง ๊ด๋ฆฌํ ์ฝ๋๊ฐ ์ ๊ณ ํํ๋ ฅ์ด ๋ฐ์ด๋ฉ๋๋ค.
๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์ฑ์๊ฐ React๋ฅผ ์ฌ์ฉํ์ง ์๋๋ผ๋ ํด๋น ์น ๊ตฌ์ฑ ์์์ ํด๋ผ์ด์ธํธ๊ฐ ์์ฑ ๊ตฌ์ฑ์ ํ ๋ฒ ์ ์ํ ๋ค์ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ ๋์ UX๋ผ๊ณ ์ฃผ์ฅํฉ๋๋ค.
์์ฑ์ด ํ์ํ ์น ๊ตฌ์ฑ ์์๋ฅผ ์ฒ์ ์ฌ์ฉํ ๋๋ sigil์ ์ถ๊ฐํ๋ ๊ฒ๋งํผ ์ด๋ ต์ง๋ง(๋ ์ฅํฉํ์ง๋ง ๋ ๋ช ์์ ) ๋์ค์ ์ฌ์ฉํ ๋๋ ์ด์ ๋ํด ์๊ฐํ ํ์๊ฐ ์๊ธฐ ๋๋ฌธ์ ๋ ์ฝ์ต๋๋ค. ํด๋น ๊ตฌ์ฑ ์์์ ๋ชจ๋ ๋จ์ผ ํธ์ถ ์ฌ์ดํธ. ๋ ๊ฒฝ์ฐ ๋ชจ๋ ์ ์น ๊ตฌ์ฑ ์์๋ฅผ ์ฑํํ ๋ ์์ฑ/์์ฑ ์ฐจ์ด๋ฅผ ์ดํดํด์ผ ํ์ง๋ง ๋จ์ผ ๊ณต์ ๊ตฌ์ฑ์ ์ฌ์ฉํ๋ฉด ๋์ผํ ์ฑ ๋ด์์ ํด๋น ๊ตฌ์ฑ ์์์ ๋ชจ๋ ์ฌ์ฉ์๊ฐ ๊ทธ๊ฒ์ ๋ํด ์๊ฐํ ํ์๊ฐ ์์ต๋๋ค.
๋ ๋ง์ React ๊ด์ฉ๊ตฌ ์ด๋ฆ์ ๋ง๋ค ์ ์๋๋ก ํด๋น ๊ตฌ์ฑ์์ ์์ฑ ์ด๋ฆ์ ๋ค์ ๋งคํํ๋ ๊ฒ์ ์ ์ฌ์ ์ผ๋ก ํ์ฉํ ์ ์์ต๋๋ค. ํ์ํ ๊ฒฝ์ฐ XFoo๋ฅผ ํ์ํ ๋ฉ์ง ๋ฒ์ญ ๋ ผ๋ฆฌ๋ฅผ ์ํํ๋ ์ฌ์ฉ์ ์ ์ React ๊ตฌ์ฑ ์์๋ก ๊ต์ฒดํ ์ ์๊ธฐ ๋๋ฌธ์ ๋ณด๋ค ์ ๊ตํ ๋ํผ๋ก์ ์ ๊ทธ๋ ์ด๋ ๊ฒฝ๋ก๋ ๋ ์ํํฉ๋๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ์ฌ๋๋ค์ด ๊ตฌ์ฑ ์์๋ฅผ ์ฌ์ฉํ ๋๋ง๋ค ์์ฑ ๊ตฌ์ฑ์ ๋ํด ์๊ฐํ์ง ์๋ ๊ฒ์ด ๊ฐ๋ฅํ๋ค๋ฉด ๊ทธ ์ ๊ทผ ๋ฐฉ์์ ์ ํธํฉ๋๋ค. ๊ทธ๋์ 5๋ฒ ์ต์ ์ ์ ์ํ์ต๋๋ค. 3๋ฒ๊ณผ 4๋ฒ๋ณด๋ค ์ธ์ฒด๊ณตํ์ ์ด๋ฉด์ ๋์์ ์ ์ฐํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
์ต์ 1๊ณผ 2๋ ์๋ฒ ๋ ๋๋ง(HTML ์์ฑ)์์ ์ ์๋ํ์ง ์์ผ๋ฉฐ ์ต์ 2๋ ๋ํ ์น ๊ตฌ์ฑ ์์ ์์ฑ์์๊ฒ ์ ๊ทธ๋ ์ด๋ ์ํ์ ์์ฑํฉ๋๋ค. ์ฌ๊ธฐ์ ๊ธฐ์กด ์์ฑ๊ณผ ๋์ผํ ์ด๋ฆ์ ๊ฐ์ง ์์ฑ์ ์ถ๊ฐํ๋ ๊ฒ์ ์ฃผ์ ๋ณ๊ฒฝ ์ฌํญ์ ๋๋ค. SSR์ด ์ ์ฉํ์ง ์๋ค๊ณ ๊ฒฐ์ ํ๋ฉด ์ต์ 1์ด React ๊ด์ ์์ ๊ฝค ๋งค๋ ฅ์ ์ ๋๋ค. ์ค์ ๋ก ์ถฉ๋ถํ ํฌ๊ด์ ์ธ์ง๋ ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ๊ตฌ์ฑ ์์ ์์ฑ์๊ฐ ์์ฑ์ ํตํด ๋ชจ๋ ๊ฒ์ ๋ ธ์ถํฉ๋๊น?
@treshugart ์์ ๊ฑฐ ์ธ๋จ ์ ๋๋ฌด ๊น์ด ๋ค์ด
@sophiebits๋์ด ๋ต๊ธ์ ์ด์ ์์ผ ๋ณด๊ฒ ๋์ด ์ฃ์กํฉ๋๋ค. ๋๋ ๊ทธ๊ฒ์ ๋ช ๋ฒ ๋ ์ฝ์ ํ์ ๋ช ๊ฐ์ง ์์ ์ ์๋ตํ๊ณ ์ถ์ง๋ง ์ด๊ฒ์ ์ ์ํ๊ฒ ์๋ตํ๊ณ ์ถ์์ต๋๋ค.
์ค์ ๋ก ์ถฉ๋ถํ ํฌ๊ด์ ์ธ์ง๋ ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ๊ตฌ์ฑ ์์ ์์ฑ์๊ฐ ์์ฑ์ ํตํด ๋ชจ๋ ๊ฒ์ ๋ ธ์ถํฉ๋๊น?
Polymer ๋๋ Skate๋ก ๊ตฌ์ถ๋ ๋ชจ๋ ๊ตฌ์ฑ ์์๋ ์์ฑ์ ํตํด ๋ชจ๋ ๊ฒ์ ๋ ธ์ถํฉ๋๋ค. ๋ช ๊ฐ์ง ๋๋ฌธ ์ด์์น๊ฐ ์์ ์ ์์ง๋ง(์คํ์ผ ์ง์ ์ ์ํ ์์ฑ ์ค์ ๋ฑ) ๊ทธ๋ ์ง ์์ผ๋ฉด ํญ์ ์์ฑ์ด ๋ท๋ฐ์นจํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ๋๋ ๋๋ถ๋ถ์ ํ๋ก๋์ ์น ๊ตฌ์ฑ ์์๊ฐ ์ด ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค ํ๋๋ฅผ ์ฌ์ฉํ์ฌ ๊ตฌ์ถ๋๋ค๊ณ ํ์ ํฉ๋๋ค.
๋๊ตฐ๊ฐ๊ฐ ๋ฐ๋๋ผ ์น ๊ตฌ์ฑ ์์๋ฅผ ์๋์ผ๋ก ์์ฑํ๋ ๊ฒฝ์ฐ ์์ฑ์ ํตํด ๋ชจ๋ ๊ฒ์ ๋ ธ์ถํ๋๋ก ๊ฐ์ํ๋ ๊ฒ์ ์์ง๋ง ๋ชจ๋ฒ ์ฌ๋ก ๋ฌธ์ ๋ฐ ์์ ์์ ๊ทธ๋ ๊ฒ ํ๋๋ก ๊ถ์ฅํฉ๋๋ค.
๊ทธ๋งํ ๊ฐ์น๊ฐ ์๊ธฐ ๋๋ฌธ์ ์์ฑ์ ์ฌ์ฉํ๋๋ก ๊ฐ์ํ๋ ๊ฒ๋ ์์ต๋๋ค. ์ฌ์ฉ์ ์ ์ ์์ ์ ์๋ ๊ฐ๋ฐ์๊ฐ ์ํ๋ ๋ชจ๋ ์์ ์ ์ํํ ์ ์๋๋ก ํ๋ ํด๋์ค์ผ ๋ฟ์ ๋๋ค. ๊ทธ๋ฌ๋ ์ค์ ๋ก ๋๋ถ๋ถ์ ์ฌ๋๋ค์ ๊ตฌ์ฑ ์์๋ฅผ ์์ฑํ๊ธฐ ์ํด Polymer ๋๋ Skate์ ๊ฐ์ ์ถ์ํ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ์ ํธํ๋ฏ๋ก ์์ฑ API๋ฅผ ๋ฌด๋ฃ๋ก ๋ฐ์ต๋๋ค.
์๋ง๋ ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ ํญ์ ํด๋ผ์ด์ธํธ ์ธก์์ ์์ฑ์ ์ํํ ๋ค์ ์ฑ์์ SSR์ ์ง์ํ๋ ค๋ ์ฌ๋๋ค์ ์ํด ๊ธฐ๋ณธ ์์ฑ ์ด๋ฆ์ ๋ํ ์ต์ 5 ์คํ์ผ ๊ตฌ์ฑ ๋งต์ ์์ฑ ์ด๋ฆ์ผ๋ก ์ง์ํ๋ ๊ฒ์ ๋๋ค.
@sophiebits : ์์ฑ ์ด๋ฆ์ ์ฌ์ฉํ์ฌ React ์ฑ์ ์์ฑํ ์ฌ๋๋ค์๊ฒ ํ๊ธฐ์ ์ธ ๋ณํ๋ผ๋ ์ ์ ์ ์ธํ๊ณ ๋ ์ข์ ์์ด๋์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ์๋ฅผ ๋ค์ด:
<x-foo long-name={val} />
๊ทธ๋ฌ๋ propname์ ๋์๊ฐ ์์ผ๋ฉด "do ์์ฑ"์ ๋ํ ๊ท์น๊ณผ ๋์๊ฐ ์์ผ๋ฉด "do ์์ฑ"์ ๋ํ ๊ท์น์ ์ด๋ป์ต๋๊น?
@robdodson : ๋์๋ฅผ ํฌํจํ์ง ์๊ณ ํด๋น ์์ฑ์ ์์ฑ ๋์๋ฌธ์๊ฐ ๋ค๋ฅธ ์ฌ์ฉ์ ์ง์ ์์ ํ๋ ์์ํฌ ๋๋ ๊ดํ์ ์๊ณ ์์ต๋๊น? ์ฆ, longname
์์ฑ์ด ์๋ longName
์์ฑ? ๊ทธ๊ฒ์ ์ค์ ๋ก ๋ด์ฅ HTML ์์์ ์ ์ญ ์์ฑ(์: contenteditable
=> contentEditable
)์ ์ฌ์ฉํ๋ ํจ์ฌ ๋ ์ผ๋ฐ์ ์ธ ํจํด์ธ ๊ฒ ๊ฐ์ง๋ง ์ด์ ์ถฉ๋ถํ ๊ถ์ฅ๋์ง ์๋์ง ํ์คํ์ง ์์ต๋๋ค. Polymer ๋ฐ Skate ๋๋ถ์ ์ฌ์ฉ์ ์ ์ ์์ ์์ฑ์ ๋ํด. ์ฌ์ ํ ๋ฌธ์ ์ธ ๊ฒฝ์ฐ ๋ค์์ด ํฌํจ๋ ๊ธฐ์กด JSX:
<x-foo longname={val} />
์์ฑ์ด longName
์ด๋ฉด ์์ฑ ์งํฉ์ผ๋ก ์คํจํฉ๋๋ค.
@effulgentsia ์ ๋ Skate์ ๋ํด์๋ง ๋งํ ์ ์์ง๋ง HTML์ ์์ฑํ๋ ๊ฒฝ์ฐ์๋ง ์์ฑ API๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ๋ชจ๋ ์๋์ ๋ชฉ์ ์ ์ํด ์๋ฒ ๋ ๋๋ง์ผ๋ก๋ ๋ถ๋ฅ๋ ์ ์์ต๋๋ค. JS๋ฅผ ํตํด ๋ฌด์์ด๋ ํ๊ณ ์๋ค๋ฉด props๋ฅผ ์ค์ ํด์ผ ํฉ๋๋ค. ์ฐ๋ฆฌ์ props
API๋ ์์ฑ์์ ์๋์ผ๋ก ๋จ๋ฐฉํฅ ๋๊ธฐํ/์ญ์ง๋ ฌํ๋ฅผ ์ํํ๊ณ ์์ฑ ์ด๋ฆ์ ๋์๋ก ๊ตฌ๋ถํ์ฌ ์์ฑ ์ด๋ฆ์ ํ์ํฉ๋๋ค(camelCase๋ camel-case ๋ฑ). ์ด ๋์์ ์ ์ฒด์ ์ผ๋ก ๊ตฌ์ฑํ ์ ์์ง๋ง ์์ ์ธ๊ธํ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๊ถ์ฅํฉ๋๋ค.
๋ง์ ์ฌ๋๋ค์ด ๋งํ๋ฏ์ด props๋ SSR์ ์ด๋ ต๊ฒ ๋ง๋ค๊ณ ์ด๊ฒ์ ์ ํจํ ์ฐ๋ ค์ ๋๋ค. ๋๋ถ๋ถ์ด ์ต์ 1์ ์ ํธํ๋ ๊ฒ์ฒ๋ผ ๋ค๋ฆฌ๋ฏ๋ก @sophiebits ์ ํด๋ผ์ด์ธํธ์ ์ํ์ ์ค์ ํ๋ ๋์์ ํด๋ฐฑ/๋งคํ์ ์ ๊ณตํ๋ ์ ์์
์๋ฅผ ์ํด, ์ฌ๊ธฐ ๋น์ ์ด ๊ตฌํ ์ค์ผ์ดํธ์ ํด๋ผ์ด์ธํธ (๋ฐ ์ฌ์ฉ์ ์ ์ ์์๊ฐ ์๋ฒ๋ก๋ถํฐ ์ํ ๋ฐ ์ํ์ ํตํด ์ํ ๊ตฌํํ ์์๋ ๋ฐฉ๋ฒ์ renderedCallback()
๋ฐ props
๋ฐ / ๋๋ state
setters. ์ฌ์ฉ์ ์ ์ ์์ ์์ค์์ ๊ทธ๋ ๊ฒ ํ๋ ๊ฒ์ ๊ฐ๋จํฉ๋๋ค. React๊ฐ ์๋ฒ์์ ์์ฑ์ ์ค์ ํ๋ ๊ธธ์ ๊ฐ๋ค๋ฉด, ์ฌ์ํ๋ ๋ณธ์ง์ ์ผ๋ก ๋์ผํ ๊ฒ์
๋๋ค. Skate ๊ตฌ์ฑ ์์ ์์ฑ์๋ ์ค์ ๋ก ์ฐ๋ฆฌ์ฒ๋ผ ์๋ฌด ๊ฒ๋ ํ ํ์๊ฐ ์์ต๋๋ค. ์ด๋ฏธ ๊ทธ๋ค์๊ฒ ์ญ์ง๋ ฌํ ๋
ผ๋ฆฌ๋ฅผ ์ ๊ณตํ์ ๊ฒ์
๋๋ค.
@robdodson ๋๋ Incremental DOM์ด ํ๋ ๊ฒ๊ณผ ๋น์ทํ ์ผ์ ํ ๊ฒ์ ๋๋ค. ์ด๊ฒ์ ๋ค์๊ณผ ๊ฐ์ด ๋ณด์ผ ๊ฒ์ ๋๋ค:
const isBrowser = true; // this would actually do the detection
const oldAttributeHook = ReactDOM.setAttribute;
// This is much like the IDOM impl but with an arguably more clear name.
ReactDOM.setAttribute = (element, name, value) => {
// This is essentially option 2, but with the added browser check
// to keep attr sets on the server.
if (isBrowser && name in element) {
element[name] = value;
} else {
oldAttributeHook(element, name, value);
}
};
@sophiebits
์ต์ 2๋ ๋ํ ๊ธฐ์กด ์์ฑ๊ณผ ์ด๋ฆ์ด ๊ฐ์ ์์ฑ์ ์ถ๊ฐํ๋ ๊ฒ์ด ์ฃผ์ ๋ณ๊ฒฝ ์ฌํญ์ธ ์น ๊ตฌ์ฑ ์์ ์์ฑ์์๊ฒ ์ ๊ทธ๋ ์ด๋ ์ํ์ ๋ง๋ญ๋๋ค.
์์ฑ์ด ํ๋ซํผ์์ ์๋ํ๋ ๋ฐฉ์์ ๊ณ ๋ คํ ๋ ์ด๊ฒ์ด ๋ถ๊ฐํผํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ฌ์ฉ์ ์ง์ ์์๋ฅผ SSRํ์ฌ ์์ฑ์ ์จ์ผ ํ๋ ๊ฒฝ์ฐ ํฅํ ํ๋ซํผ์์ ์ ์ฌํ ์ด๋ฆ์ ์์ฑ์ ์ ๊ณตํ ์ํ๋ ์์ต๋๋ค. @treshugart๊ฐ ์ด์ ์
์ด๊ฒ์ด ์ต์ 2์ ๋ํด ๋ง์์ด ๋ฐ๋์๋์ง ํ์ ํ ์ ์์ง๋ง ์ต์ 2์๋ ๋ช ๊ฐ์ง ๋ฉ์ง ๋ณด๋์ค๊ฐ ์๊ณ Preact๊ฐ ์ค์ ๋ก ๊ทธ๊ฒ์ ์ฆ๋ช ํ๋ ๊ฒ ๊ฐ๊ธฐ ๋๋ฌธ์ ์ธ๊ธํ๊ณ ์ถ์์ต๋๋ค.
์๋ง๋ ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ ํญ์ ํด๋ผ์ด์ธํธ ์ธก์์ ์์ฑ์ ์ํํ ๋ค์ ์ฑ์์ SSR์ ์ง์ํ๋ ค๋ ์ฌ๋๋ค์ ์ํด ๊ธฐ๋ณธ ์์ฑ ์ด๋ฆ์ ๋ํ ์ต์ 5 ์คํ์ผ ๊ตฌ์ฑ ๋งต์ ์์ฑ ์ด๋ฆ์ผ๋ก ์ง์ํ๋ ๊ฒ์ ๋๋ค.
+1, ์ ๋ ์ด ๋ฐฉํฅ์ผ๋ก ๊ณ์ ๋์๊ฐ๋ ๊ฒ์ ์ง์งํฉ๋๋ค.
@effulgentsia
์์ฑ ์ด๋ฆ์ ์ฌ์ฉํ์ฌ React ์ฑ์ ์์ฑํ ์ฌ๋๋ค์๊ฒ ํ๊ธฐ์ ์ธ ๋ณํ๋ผ๋ ์ ์ ์ ์ธํ๊ณ ๋ ํ๋ฅญํ ์์ด๋์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
์ต์
2๋ ๊ทธ๊ฒ์ ํด๊ฒฐํ ๊ฒ์
๋๋ค :)
๊ทธ๋ ์ง ์์ผ๋ฉด ๋์ ์ผ์ด์ค ์์ฑ์ camelCased ์์ฑ์ ๋งคํํ๋ ์ต์
1๊ณผ ๊ฒฐํฉ๋ ๊ฒฝํ์ ๋ฐฉ๋ฒ์ด ํ์ํ ์ ์์ต๋๋ค.
๊ทธ๋ฌ๋ propname์ ๋์๊ฐ ์์ผ๋ฉด "do ์์ฑ"์ ๋ํ ๊ท์น๊ณผ ๋์๊ฐ ์์ผ๋ฉด "do ์์ฑ"์ ๋ํ ๊ท์น์ ์ด๋ป์ต๋๊น?
์ด๋ฆ์ ๋์๊ฐ ์์ผ๋ฉด Preact ๊ฐ ์์ฑ์ ์ค์ ํ๋ ๊ฒ์ฒ๋ผ ๋ณด์
๋๋ค. ๋๋ ๊ทธ๋ค์ด ์ต์
2๋ฅผ ์ฌ์ฉํ๊ณ long-name
๊ฐ in
๊ฒ์ฌ๋ฅผ ํต๊ณผํ์ง ๋ชปํ์ฌ ์์ฑ( source )์ผ๋ก ๋์ฒด๋๊ธฐ ๋๋ฌธ์ด๋ผ๊ณ ๊ฐ์ ํฉ๋๋ค.
๋๋ ๊ฐ์ธ์ ์ผ๋ก ์ด ๋์์ ์ข์ํ์ง๋ง ์์ฑ์ ์ค์ ํ๋ ์์ญ๊ณผ ๋ฏธ๋์ ๋ฐ์ํ ์ ์๋ ์ถฉ๋๋ก ๋์๊ฐ๋ฏ๋ก @sophiebits ๊ฐ ๋ฌด๊ฒ๋ฅผ
๋์๋ฅผ ํฌํจํ์ง ์๊ณ ํด๋น ์์ฑ์ ์์ฑ ๋์๋ฌธ์๊ฐ ๋ค๋ฅธ ์ฌ์ฉ์ ์ง์ ์์ ํ๋ ์์ํฌ ๋๋ ๊ดํ์ ์๊ณ ์์ต๋๊น?
๋ด๊ฐ ์๊ธฐ๋ก๋ ์๋์ผ. ๋์๋ฅผ ์ฌ์ฉํ๋ฉด ๋์๊ด์์ ๋ํ ์ผ์ด์ค์ ์์น๋ฅผ โโ์ฝ๊ฒ ์ ์ ์์ต๋๋ค. ๋ฐ๋๋ผ ์น ๊ตฌ์ฑ ์์๋ฅผ ์๋์ผ๋ก ์์ฑํ๋ ๊ฒฝ์ฐ longname/longName
ํ ์ ์์ผ๋ฉฐ longname
์์ฑ์ ์ฐพ์ง ๋ชปํ๊ธฐ ๋๋ฌธ์ ์ต์
2๋ง ์ ์ฅ๋์ง๋ง ์ด์ ์ ์ฌ์ฉ๋ ๊ตฌ์ฑ ์์๋ก ๋์ฒด๋ฉ๋๋ค. longname
์์ฑ.
๊ทธ๋งํ ๊ฐ์น๊ฐ ์๊ธฐ ๋๋ฌธ์ Preact๋ ์ตํ์ ์๋จ ์ผ๋ก ์์ฑ ์ ์ค์ ํ๊ธฐ ์ ์ <x-foo longName={bar}/>
SSRํ๋ ๊ฒฝ์ฐ longname=""
์์ฑ์ผ๋ก๋ ์ ์ ํ๊ฒ ํด๋ฐฑ๋ฉ๋๋ค.
@treshugart
๋์ฒด/๋งคํ์ ์ ๊ณตํ๋ฉด์ ํด๋ผ์ด์ธํธ์ ์ํ์ ์ค์ ํ์๋ @sophiebits ์ ์ ์์
์, ์.
๋๋ Incremental DOM์ด ํ๋ ๊ฒ๊ณผ ๋น์ทํ ์ผ์ ํ ๊ฒ์ ๋๋ค.
๋ชจ๋ ์์(๋๋ ๊ธฐ๋ณธ ํด๋์ค)๊ฐ ์ด๊ฒ์ ํผํฉํด์ผ ํ๋ค๋ ์์ด๋์ด์ ๋๊น?
btw, ํ ๋ก ์ ๊ณ์ ์ฐธ์ฌํด ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค. ๊ฝค ์ค๋๋์๋ค๋ ๊ฒ์ ์๊ณ ์์ต๋๋ค โค๏ธ
https://github.com/facebook/react/issues/11347#issuecomment -339858314์ ๋ง์ง๋ง ์๋ฅผ ์ดํดํ๋์ง ํ์คํ์ง ์์ง๋ง ์ด์ ๊ฐ์ ์ ์ญ ์ฌ์ ์ ๊ฐ๋ฅํ ํํฌ๋ฅผ ์ ๊ณตํ ๊ฐ๋ฅ์ฑ์ ๊ฑฐ์ ์์ต๋๋ค.
@gaearon ๋๋ Trey๊ฐ ์์ญ์ด ํจ์น๋ก ์ ๋ณ๊ฒฝ ์ฌํญ์ ๋ณด์ฌ์ฃผ๊ณ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ์๋ง๋ ReactDOM ๊ตฌํ ์์ฒด์ ์์ฑ๋์์ ๊ฒ์ ๋๋ค.
์ต๊ทผ ์๊ฒฌ์ ๋ฐํ์ผ๋ก ์ด ์ ์์ ๋ํด ์ด๋ป๊ฒ ์๊ฐํ์ญ๋๊น?
BC์ ๊ฒฝ์ฐ React์์ ์๋ฌธ์ ์ฌ์ฉ์ ์ ์ ์์๊ฐ ์๋ํ๋ ๋ฐฉ์์ ๋ํด ์๋ฌด ๊ฒ๋ ๋ณ๊ฒฝํ์ง ๋ง์ญ์์ค. ์ฆ, <x-foo ... />
์ ๊ฐ์ JSX๋ React 16์์์ ๋ง์ฐฌ๊ฐ์ง๋ก React 17์์๋ ๊ณ์ ๋์ผํ ๋ฐฉ์์ผ๋ก ์๋ํฉ๋๋ค. ๋๋ _์ฌ์ํ_ ๋ฒ๊ทธ ์์ ์ด ํ์ํ ๊ฒฝ์ฐ ๋ณ๋์ ๋ฌธ์ ๋ฅผ ์ด์ด ์ด์ ๋ํด ๋
ผ์ํ์ธ์.
๋ ๋์ ์ฌ์ฉ์ ์ ์ ์์ ์๋ฏธ ์ฒด๊ณ๋ก React ๊ตฌ์ฑ ์์๋ฅผ ์์ฑํ๊ธฐ ์ํด config-less API๋ฅผ ์ถ๊ฐํ์ญ์์ค. ์: const XFoo = ReactDOM.customElement('x-foo');
.
์์์ ๋ง๋ ๊ตฌ์ฑ ์์์ ๋ํด ๋ค์ ์๋ฏธ ์ฒด๊ณ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
children
, ref
, ๊ธฐํ?)์ธ XFoo์ ๋ชจ๋ prop์ ๋ํด ์ผ๋ฐ์ ์ธ React ์๋ฏธ ์ฒด๊ณ๋ฅผ ์ ์ฉํฉ๋๋ค(์์ฑ์ด๋ ์์ฑ์ผ๋ก ์ค์ ํ์ง ๋ง์ญ์์ค. ์ฌ์ฉ์ ์ ์ ์์ DOM ๋
ธ๋์์).data-*
๋ฐ aria-*
)์ ๋ํด div
์ ์๋ ๊ฒฝ์ฐ React์์ ์ํํ๋ ๊ฒ๊ณผ ๋์ผํ ์์
์ ํด๋น ์ํ์ผ๋ก ์ํํฉ๋๋ค <XFoo data-x={} className={} contentEditable={} />
์ props๋ฅผ DOM ๋
ธ๋์ ์ ์ฉํ๋ ๋ฐฉ๋ฒ์ <div data-x={} className={} contentEditable={} />
(ํด๋ผ์ด์ธํธ ์ธก ๋ฐ SSR ๋ชจ๋)์ ์ ์ฉํ๋ ๋ฐฉ๋ฒ๊ณผ ๋์ผํด์ผ ํฉ๋๋ค.XFoo์ ๋ค๋ฅธ ๋ชจ๋ ์ํ์ ๊ฒฝ์ฐ ํด๋ผ์ด์ธํธ ์ธก์ ๋ ๋๋งํ ๋ DOM ๋ ธ๋์์ ์์ฑ์ผ๋ก ์ค์ ํฉ๋๋ค. SSR์ ๊ฒฝ์ฐ ๊ฐ์ด ๊ธฐ๋ณธ์ด๋ฉด ์์ฑ์ผ๋ก ๋ ๋๋งํฉ๋๋ค. ๊ธฐ๋ณธ์ด ์๋ ๊ฒฝ์ฐ ๋ ๋๋ง์ ๊ฑด๋๋ฐ๊ณ ์ํ ์ค์ ํด๋ผ์ด์ธํธ ์ธก ์์ฑ์ผ๋ก ์ค์ ํฉ๋๋ค. ์์ฑ์ผ๋ก SSR ๋ ๋๋ง์ ๊ฒฝ์ฐ camelCaseToDashCase ์ด๋ฆ์ ๋๋ค.
์ #2์ API๋ฅผ ํตํด ์์ฑ๋ ๊ตฌ์ฑ ์์์ ๊ฒฝ์ฐ ์ด๋ฒคํธ ๋ฆฌ์ค๋์ ์ฌ์ฉํ ์ํ ์ด๋ฆ์ ์์ฝํ์ญ์์ค. ์: 'events'
๋๋ 'eventListeners'
. ๋๋ ์ ์ฌ์ ์ธ ์ฌ์ฉ์ ์ ์ ์์ ์์ฑ ์ด๋ฆ๊ณผ ์ถฉ๋ํ์ง ์์ผ๋ ค๋ฉด '_eventListeners'
๋๋ 'EventListeners'
. XFoo
์ ReactDom ์์ฑ ๊ตฌํ์ ์ด๋ฌํ ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ฅผ DOM ๋
ธ๋์ ์๋์ผ๋ก ๋ฑ๋กํฉ๋๋ค.
๊ทน๋จ์ ์ธ ๊ฒฝ์ฐ(์: ์์ ๊ตฌํ์ด ๋ฐ๋์งํ์ง ์๊ฑฐ๋ ์ถฉ๋ถํ์ง ์์ ์ฌ์ฉ์ ์ง์ ์์ ์ฌ์ฉ)์ ๊ฒฝ์ฐ ์ฑ ๊ฐ๋ฐ์๋ ํ์ํ ๋ชจ๋ ํน๋ณํ ์์
์ ์ํํ๊ธฐ ์ํด ์์ฒด React ๊ตฌ์ฑ ์์๋ฅผ ๊ตฌํํ ์ ์์ต๋๋ค. ์ฆ, ReactDOM.customElement()
๋ฅผ ์ฌ์ฉํ ํ์๊ฐ ์๊ฑฐ๋ ํ์ฅํ ์ ์์ต๋๋ค.
์์ ๋ชจ๋ ๋์์ ์ํ์ง๋ง HTML ์์ฑ์ ์ต์ํ ์ฌ๋๋ค์ด <div>
์ ํธํ๋ ๋น์ทํ ์ด์ ๋ก JSX๊ฐ ์๋ฌธ์ ์ฌ์ฉ์ ์ ์ ์์ ์ด๋ฆ( <x-foo />
๋์ <XFoo />
, <div>
over <Div>
), ๊ทธ๋ค์ React.createElement()๋ฅผ ์์ญ์ด ํจ์นํ ์ ์์ต๋๋ค. ์์ฃผ ๊ฐ๋จํ ์์ญ์ด ํจ์น๊ฐ ๋ ๊ฒ์
๋๋ค. ์ฒซ ๋ฒ์งธ ์ธ์๋ฅผ ์ทจํ๊ณ ์ด๊ฒ์ด ์ํ๋ ์ฌ์ฉ์ ์ ์ ์์ ์ด๋ฆ๊ณผ ์ผ์นํ๋ ๊ฒฝ์ฐ(ํน์ ๋ชฉ๋ก์ด๋ ๋ชจ๋ ์๋ฌธ์์ ํ๋ ์ด์์ ๋์๊ฐ ํฌํจ๋ ๋ฌธ์์ด์ด๋ ์๊ด์์ด) ReactDOM.customElement()
๋ฅผ ํธ์ถํฉ๋๋ค ReactDOM.customElement()
๋ฅผ ์
๋ ฅํ๊ณ ๊ฒฐ๊ณผ์ ๋๋จธ์ง ์ธ์๋ฅผ ์๋ React.createElement()
ํฉ๋๋ค.
@developit @gaearon ๋ ์ค ํ๋์ผ ์ ์์ต๋๋ค. "๋งคํ"์ด ํ์ํ๋ค๋ฉด ํํฌ๊ฐ ๋ ์ง์ ๊ฐ๋ฅํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ๊ทธ๋ฌ๋ ์ด๊ฒ์ ๋ํ Jason์ด ์ง์ ํ ๊ฒ์ฒ๋ผ ReactDOM์ ์ฝ์ด์์ ๊ตฌํ๋๋ ๊ฒฝ์ฐ ์ ๋ณ๊ฒฝ ์ฌํญ์ ๋ณด์ฌ์ฃผ๊ธฐ ์ํ ๊ฒ์ ๋๋ค.
BC์ ๊ฒฝ์ฐ React์์ ์๋ฌธ์ ์ฌ์ฉ์ ์ ์ ์์๊ฐ ์๋ํ๋ ๋ฐฉ์์ ๋ํด ์๋ฌด ๊ฒ๋ ๋ณ๊ฒฝํ์ง ๋ง์ญ์์ค. ์ฆ, JSX๋
React 16์์์ ๋ง์ฐฌ๊ฐ์ง๋ก React 17์์๋ ๊ณ์ ๋์ผํ ๋ฐฉ์์ผ๋ก ์๋ํฉ๋๋ค. ๋๋ ์ฌ์ํ ๋ฒ๊ทธ ์์ ์ด ํ์ํ ๊ฒฝ์ฐ ๋ณ๋์ ๋ฌธ์ ๋ฅผ ์ด์ด ์ด์ ๋ํด ๋ ผ์ํ์ธ์.
๊ฐ์ธ์ ์ผ๋ก ์ ๋ <x-foo>
์์๋ฅผ ์๋ ๊ทธ๋๋ก ์ฌ์ฉํ๊ณ ๋จผ์ ๋ํํ ํ์ ์์ด ์์ฑ์ ์ฝ๊ฒ ์ ๋ฌํ ์ ์๊ธฐ๋ฅผ ์ํฉ๋๋ค.
๊ฐ๋ฅํ๋ค๋ฉด @sohpiebits ์ ์ต์ 1(ํด๋ผ์ด์ธํธ ์ธก ์์ฑ) ๋ฐ 5(SSR์ฉ ๊ตฌ์ฑ)๋ฅผ ์ ์ ํ๊ณ ์ถ์ต๋๋ค. ๋๋ ์ฌ์ ํ ์ฌ๋๋ค์ด ์ด์ ๋ฒ์ ๊ณผ์ ํธํ์ฑ ๋ณด๋์ค์ ๋ํด option2(์๋ง๋ ์ต์ 2 + 5?)๋ฅผ ์ฌ๊ณ ํ ๊ฒ์ด๋ผ๋ ํฌ๋ง์ ํ๊ณ ์์ต๋๋ค.
@gaearon Trey์ ์ ์์ด ReactDOM ์ฝ์ด์ ์ผ๋ถ๋ผ๋ฉด ์๊ฒฌ์ด ๋ฐ๋๋์? ๋์์ด ๋๋ค๋ฉด ์์ ๋ฅผ ๋ ๊ตฌ์ฒดํํ ์ ์์ง ์์๊น์?
์ต์ 5์ ๋ํ ๋์ ์ฃผ์ ๊ด์ฌ์ฌ๋ ์ํธ ์ด์ฉ์ฑ์ ํ์ฉํ๊ธฐ ์ํด ๋ง์ ์์ฉ๊ตฌ๋ฅผ ๋ง๋ค๊ณ DX๋ฅผ ๊นจ๋ ๊ฒ์ ๋๋ค. ๋ชจ๋ React ํต์ฌ ํ๊ณผ ๊ธฐ์ฌ์๊ฐ ์ํ๋ ์ํฅ์ ๋ฏธ์น์ง ์์ ๋ณ๊ฒฝ์ ๋ง์ ์๊ฐ์ ๋ณด๋ด๋ ๊ฒ์ ๋ถ๋๋ฌ์ด ์ผ์ ๋๋ค.
๋๋ React ํ์ด _PropTypes_์ ๊ฐ์ ๋ฆฌํฌ์งํ ๋ฆฌ์ ๋ง์ง๋ง ๋ณ๊ฒฝ ์ฌํญ์ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ์ ๋ง ์ข์ํ์ต๋๋ค. ํ๋ ์ด์์ ์ค์์น๋ฅผ ํฌํจํ๋ ๊ณํ์ ์๊ฐํ๋ ๊ฒ์ด ์ข์ ๊ฒ์ ๋๋ค. ๊ฐ๋ฐ์์๊ฒ ํฅํ ์ฌ์ฉ์ ์ง์ ์ด ์๋ ์ฌ์ฉ์ ์ง์ ์ ๋ํด ์ํํ ์ ์๋ ๋ณ๊ฒฝ ์ฌํญ์ ๊ต์กํ๋ ๊ฒ์ ๋๋ค. ์ง๋จ.
์ฐ๋ฆฌ ๋ชจ๋๋ฅผ ๋ง์กฑ์ํฌ ์๋ฃจ์ ์ ์ด ์ต์ ์ค ์ผ๋ถ๋ฅผ _steps_, API ์ถ๊ฐ, ๊ฒฝ๊ณ ๋ฐ ์ฌ์ฉ ์ค๋จ ๋๋ ๋์ ๋ณ๊ฒฝ์ผ๋ก ๊ฒฐํฉํ๋ ์๋ฃจ์ ์ด ๋ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
์ต์ 5(๊ฒฝ๊ณ ํฌํจ), ์ดํ ์ต์ 2(ํ์ํ ๋ํผ ์ฌ์ฉ ์ค๋จ ํฌํจ).
์ต์ 5(๊ฒฝ๊ณ ํฌํจ), ์ดํ ์ต์ 2(ํ์ํ ๋ํผ ์ฌ์ฉ ์ค๋จ ํฌํจ).
๋๋ ์ค์ ๋ก ๊ทธ ๋ฐ๋๋ก ํ๋ ๊ฒ์ด ๋ ๋์ ์ผ๋ จ์ ๋จ๊ณ๊ฐ ๋ ๊ฒ์ด๋ผ๊ณ ์๊ฐํ๊ณ ์์์ต๋๋ค. ์ต์ 1 ๋๋ 2๋ ๊ทน์ ์ธ ๋ณํ๊ฐ ์ ๊ธฐ ๋๋ฌธ์ ์ ํํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ๊ฒ์ด ์ด๋ป๊ฒ ์งํ๋๊ณ SSR ์คํ ๋ฆฌ๊ฐ ์น ๊ตฌ์ฑ ์์์ ๋ํด ์ด๋ป๊ฒ ๋ณด์ด๊ธฐ ์์ํ๋์ง ์ธก์ ํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ ์ API์ ํ๋ก์/๋ํผ ๊ตฌ์ฑ ์์ ๊ฐ๋ ์ ์ถ๊ฐํ๊ธฐ ๋๋ฌธ์ ์ต์ 5๋ก ํ์ ์กฐ์น๋ฅผ ์ทจํฉ๋๋ค.
์ต์ 1์ ์ฃผ์ ๋ฌธ์ ๋ BC ๋ธ๋ ์ดํฌ๊ฐ ๊ฝค ํฌ๋ค๋ ๊ฒ์ ๋๋ค. ์ต์ 2์ ์ฃผ์ ๋ฌธ์ ๋ ์์ ์ ๊ทธ๋ ์ด๋๊ฐ ์๋ฃ๋ ์์ ์ ๋ฐ๋ผ ๊ฒฝ์ ์กฐ๊ฑด์ด ์๋ค๋ ๊ฒ์ ๋๋ค. React๋งํผ ๋๋ฆฌ ์ฌ์ฉ๋๋ ํ๋ก์ ํธ์ ๋ ์ค ํ๋๊ฐ ์ง์ ์ผ๋ก ์์ฉ ๊ฐ๋ฅํ์ง ํ์ ํ ์ ์์ต๋๋ค.
์ต์
5์ ๊ฐ์ฉ์ฑ์ ๊ฐ์ํ ๋ ์ต์
5๊ฐ ์๋ ์ฌ์ฉ์ ํจ์ฌ ๋ ์์ ํ์ง๋ง ์ฌ์ ํ ์ ์ฉํ๊ฒ ๊ฐ์ ํ ์ ์๋์ง ๊ถ๊ธํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์ต์
4์ ์ญ์ ์ด๋ป์ต๋๊น: domProperties
๋ฐ eventListeners
์ํ์ ๋์
ํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ์์
์ ์ํํ ์ ์์ต๋๋ค.
<x-foo
my-attr1={...}
domProperties={{myRichDataProperty: ...}}
eventListeners={{'a-custom-element-event': e => console.log('yo')}}
/>
๋๋ฌธ์๋ก ์ธํด domProperties
๋ฐ eventListeners
๋ ์ ํจํ ์์ฑ ์ด๋ฆ ์ด ์๋๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ ์์ ํ ์ญํธํ
BC๋ฅผ ๋ณด์กดํ๋ ๊ฒ ์ธ์๋ ์ด ์ ๊ทผ ๋ฐฉ์์ ์ดํดํ๊ธฐ ์ฝ์ต๋๋ค. ์์ฑ ์ค์ฌ(React props๊ฐ ์์ ์์ฑ์ผ๋ก ์ฒ๋ฆฌ๋จ์ ์๋ฏธ)์ผ๋ก, ์์ ์ด๋ฆ ์์ฒด๊ฐ ๋ชจ๋ ์๋ฌธ์์ด๊ณ ๋์๊ฐ ์์ผ๋ฏ๋ก HTML ์ค์ฌ์ด๋ผ๋ ์ ์ ๊ฐ์ํ ๋ ์ ํฉํฉ๋๋ค. ๊ทธ๋ฌ๋ domProperties
๋ ๋ฆฌ์น ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ๊ฒ๊ณผ ๊ฐ์ด ์์ฑ์ ์ ๋ฌํด์ผ ํ๋ ๋น๊ต์ ๋๋ฌธ ๊ฒฝ์ฐ๋ฅผ ์ํด ์ ๊ณต๋ฉ๋๋ค.
๋ฉํ ๋ชจ๋ธ์ ์์ฑ ์ค์ฌ์ผ๋ก ์ ํํ๋ ค๋ ์ฌ๋๋ค(์ต์ 1)์ ์ํด ์ต์ 5 ์คํ์ผ API๊ฐ ํ์ํ ์ ์์ต๋๋ค.
const XFoo = ReactDOM.customElement('x-foo');
<XFoo prop1={} prop2={} data-foo={} aria-label={} />
์ด ๊ตฌ๋ฌธ์ ์ฌ์ฉํ๋ฉด ๋ชจ๋ ์ํ์ด ์์ฑ์ผ๋ก ์ฒ๋ฆฌ๋ฉ๋๋ค(์ต์
1). "name"(XFoo) ์์๋ JS ์ค์ฌ ๊ท์น์ ๋ฐ๋ฅด๊ธฐ ๋๋ฌธ์ ์ ํฉํฉ๋๋ค. ๋๋ ์ฐ๋ฆฌ๊ฐ ์ต์ํ data-*
๋ฐ aria-*
props๋ฅผ ์์ฑ์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ๋ฅผ ์ํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ด ์์ฑ๋ง ์ ํํ๊ฑฐ๋ ๋์๊ฐ ์๋ ๋ชจ๋ prop์ ์์ฑ์ผ๋ก ์ฒ๋ฆฌํ๋๋ก ์ผ๋ฐํํ ์ ์์ต๋๋ค. ๊ธฐ์ธํ๋ค.
ํํธ, SSR์ ์ต์
5 ๊ตฌ์ฑ์ ์ง์ํ๊ธฐ ์ํด ๋ค์๊ณผ ๊ฐ์ด ๊ตฌ์ฑ API๋ฅผ ReactDOM.customElement
์ถ๊ฐํ ์ ์์ต๋๋ค.
const XFoo = ReactDOM.customElement('x-foo', ssrConfiguration);
์๋ง๋ ssrConfiguration
๋ @treshugart ์ ์ฝ๋ฉํธ ์ ์๋ ReactDOM.setAttribute
์ ์ ์ฌํ ์ฝ๋ฐฑ ํจ์๊ฐ ๋ ์ ์์ต๋๊น?
์ด๋ป๊ฒ ์๊ฐํ๋์?
@effulgentsia ๋๋ ๋น์ ์ ์๊ฐ์ด ์ด๋๋ก ๊ฐ๋์ง ์ข์ํฉ๋๋ค. ์ฝ๊ฐ์ ์ด๋ฆ ๋ณ๊ฒฝ: domProps
/ domEvents
. ์ด๊ฒ์ ์ต์
4์ ๋งค์ฐ ๊ฐ๊น์ต๋๋ค.
WRT SSR, ๋๋ React๊ฐ ๊ตฌ์ฑ ์์๊ฐ ์ถ์ ํ์ง ์๋ ๊ฒฝ์ฐ ์์ฒด์ ์ผ๋ก ๋ณ๊ฒฝ๋๋ ์์ฑ์ ์กด์คํ ์ ์๋ ํ ์ฌ์ฉ์ ์ ์ ์์ ์์ฒด์์ SSR์ ์ฒ๋ฆฌํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ด์ ์ ์์ง๋ฅผ ๊ฒ์ํ์ง๋ง ํธ์์ ๋ค์ ์ฌ๊ธฐ์ ์์ต๋๋ค. https://gist.github.com/treshugart/6eff0da3c0bea886bb56589f743b78a6. ๊ธฐ๋ณธ์ ์ผ๋ก ๊ตฌ์ฑ ์์๋ ์๋ฒ์์ ๋ ๋๋งํ ํ ์์ฑ์ ์ ์ฉํ๊ณ ํด๋ผ์ด์ธํธ์์ ๋ค์ ์ํํฉ๋๋ค. ์น ๊ตฌ์ฑ ์์์ ๋ํ SSR์ ๊ฐ๋ฅํ์ง๋ง ์๋ฃจ์ ์ ์ฌ์ ํ โโํ์ค ์์ค์์ ๋ ผ์๋๊ณ ์์ผ๋ฏ๋ก ์ ์์ ์ด ๋ถ๋ถ์ ๊ธฐ๋ค๋ฆฌ๋ ๊ฒ์ด ๊ฐ์ฅ ์ข์ต๋๋ค.
@effulgentsia ๋๋ ๋น์ ์ด ํฅํ๊ณ ์๋ ๊ณณ์ด ์ข์์. @sophiebits , @gaearon do
์ด ๋ฐฉํฅ์ ๋ํ ์๊ฐ์ด ์์ผ์ ๊ฐ์?
2017๋ 10์ 31์ผ ํ์์ผ ์คํ 7์ 33๋ถ Trey Shugart [email protected] ์ ๋ค์๊ณผ ๊ฐ์ด ์ผ์ต๋๋ค.
@effulgentsia https://github.com/effulgentsia ๋๋ ๋น์ ์ ์์น๋ฅผ โโ์ข์ํฉ๋๋ค
์๊ฐ์ด ๊ฐ๊ณ ์์ต๋๋ค. ์ด๋ฆ์ ์ฝ๊ฐ ๋ณ๊ฒฝํ๋ฉด ์ ์ฉํ ์ ์์ต๋๋ค.
domProps / domEvents ๋ฑ์ ์ด๋ฆ์ ์ ๋ ฌํฉ๋๋ค.WRT ์ต์ 2, ์ต์ํ ์ด์ ๋ฒ์ ๊ณผ ํธํ๋๋ฉฐ ๋๋ถ๋ถ์ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ํด๊ฒฐํฉ๋๋ค.
๊ทธ๋ฌ๋ ๋๋ ๋์์ ์ ์ํ๊ณ ์์ต๋๋ค.๋๋ SSR์ด
React๋ ๊ตฌ์ฑ ์์๊ฐ ๋ณ๊ฒฝ๋๋ ์์ฑ์ ์กด์คํ ์ ์์ต๋๋ค.
๊ทธ๋ค์ ์ถ์ ํ์ง ์์ต๋๋ค. ์ ์ ์์ ์ ๊ฒ์ํ์ง๋ง ์ฌ๊ธฐ์ ๋ค์ ์์ต๋๋ค.
ํธ์:
https://gist.github.com/treshugart/6eff0da3c0bea886bb56589f743b78a6.
๊ธฐ๋ณธ์ ์ผ๋ก ๊ตฌ์ฑ ์์๋ ์๋ฒ์์ ๋ ๋๋งํ ํ ์์ฑ์ ์ ์ฉํฉ๋๋ค.
ํด๋ผ์ด์ธํธ์ ๋ค์ ์๋ถ์ ๊ณต๊ธํฉ๋๋ค. ์น ์ปดํฌ๋ํธ์ฉ SSR์ ๊ฐ๋ฅํ์ง๋ง
์๋ฃจ์ ์ ์ฌ์ ํ โโํ์ค ์์ค์์ ๋ ผ์๋๊ณ ์์ผ๋ฏ๋ก
์ฌ๊ธฐ์์ ์ ์์ ์ด ๋ถ๋ถ์ ๊ธฐ๋ค๋ฆฌ๋ ๊ฒ์ด ๊ฐ์ฅ ์ข์ต๋๋ค.โ
๋น์ ์ด ์ธ๊ธ๋์๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ ๋ฐ๋ ๊ฒ์ ๋๋ค.
์ด ์ด๋ฉ์ผ์ ์ง์ ๋ต์ฅํ๊ณ GitHub์์ ํ์ธํ์ธ์.
https://github.com/facebook/react/issues/11347#issuecomment-340960798 ,
๋๋ ์ค๋ ๋ ์์๊ฑฐ
https://github.com/notifications/unsubscribe-auth/ABBFDeiQhBWNGXNplbVV1zluYxT-ntFvks5sx9hngaJpZM4QD3Zn
.
์ด๋ฆ์ ์ฝ๊ฐ ๋ณ๊ฒฝ: domProps / domEvents.
๋๋ ๊ทธ๊ฒ๋ค์ ์ข์ํ๋ค. ๋ํ "dom"์ ๊ฐ๋
์ "ref"์ ๊ฐ๋
์ผ๋ก ๋์ฒดํ์ฌ React์ ๋ ๊ด์ฉ์ ์ผ๋ก ๋ง๋ค ์ ์๋ ๋ฐฉ๋ฒ์ด ์๋์ง ๋ธ๋ ์ธ์คํ ๋ฐ ์ค์
๋๋ค. ์ฆ, refProps
/ refEvents
"ref"์ ์ํ ๋ฐ ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ฅผ ์ฐ๊ฒฐํ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์
๋๋ค.
๊ทธ๋ฆฌ๊ณ this.props
๋ด๋ถ์ ์๋ก์ด ํน์ ์ด๋ฆ์ ๋์
ํ๋ ๋์ ๊ธฐ์กด ref
JSX ์์ฑ์ ์ค๋ฒ๋ก๋ํ๋ฉด ์ด๋จ๊น ํ๋ ์๊ฐ์ด ๋ค์์ต๋๋ค. ํ์ฌ "ref"๋ React ์ปดํฌ๋ํธ๊ฐ ๋ง์ดํธ ๋ฐ ๋ง์ดํธ ํด์ ๋ ๋ ํธ์ถ๋๋ ํจ์์
๋๋ค. ๋ค์๊ณผ ๊ฐ์ด ๊ฐ์ฒด๋ ํ์ฉํ๋ฉด ์ด๋ป๊ฒ ๋ ๊น์?
<x-foo my-attr-1={}
ref={{
props: ...
events: ...
mounted: ...
unmounted: ...
}}
/>
๊ทธ๋ฅ ์์ด๋์ด์ ๋๋ค.
์ด ์ ๊ทผ ๋ฐฉ์์ด ์ ๋ง ๋ง์์ ๋ญ๋๋ค. :)
์ด๊ฒ์ ๋ํ ์น์ ํ ํ. @gaearon @sophiebits @effulgentsia ์ ์ต๊ทผ ์ ์์ ๋ํด ์๊ฒฌ์ด ์์ผ์ ๊ฐ์? ๊ทธ๊ฒ์ด ์ผ๊ตฌ์ฅ์ ์๋์ง ์๋๋ฉด ๋น์คํํฐ์ ์๋์ง ๊ถ๊ธํฉ๋๋ค.
RFC ํ๋ก์ธ์ค๋ฅผ ๋ฐฉ๊ธ ์ด์์ต๋๋ค. RFC๋ก ์ ์ถํ๋๋ก ์์ฒญํ ์ ์์ต๋๊น?
https://github.com/reactjs/rfcs
domProperties
๋ฐ eventListeners
"props"(๋๋ ref={{}} ๊ฐ์ฒด ๋ด์์ ์ด์ ์์ํ๋ ๊ฒ)๋ฅผ ์ถ๊ฐํ์ง ์๋ ๊ฒ์ด ์ข์ต๋๋ค. ์๋ํ๋ฉด ์ฌ์ฉ์ ์ ์ ์์๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ค๋ฅธ ๋ชจ๋ React ๊ตฌ์ฑ ์์์ ๋ฌ๋ฆฌ ๋งค์ฐ ๋ถ์์ฐ์ค๋ฝ๊ธฐ ๋๋ฌธ์
๋๋ค. ๊ตฌ์ฑ ์์ ์ฌ์ฉ์๊ฐ ์์ฑ๊ณผ ์์ฑ ๋ฑ์ ์ฐจ์ด์ ์ ์ ํํ ์์์ผ ํ๋ ๊ฒฝ์ฐ์๋ ReactDOM.createCustomElementType ์คํ์ผ ์๋ฃจ์
์ผ๋ก ํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ๊ทธ๋ฐ ๋ค์ ๊ตฌ์ฑ ์์๋ฅผ ์ ํํ ํ ๋ฒ ์ฌ์ฉํ๋ฉด ๋น์ทํ ์์
๋(๊ตฌ์ฑ์ ์ง์ ํ ๋ค์ ํ ๋ฒ ์ฌ์ฉ)์ด์ง๋ง ๊ตฌ์ฑ ์์๋ฅผ ์ฌ๋ฌ ๋ฒ ์ฌ์ฉํ๋ฉด ๊ตฌ์ฑ ๊ฐ์ฒด์ ๋ํด ๋งค๋ฒ ์๊ฐํ ํ์๊ฐ ์์ต๋๋ค. ๋งค๋ฒ ๊ตฌ์ฑ์ ์ง์ ํ๋๋ก ์๊ตฌํ๋ ๊ฒ์ ๋ด๊ฐ ๋ญ๊ฐ๋ฅผ ๋์น๊ณ ์์ง ์๋ ํ ๊นจ๋ํ ์ฌ์ฉ์ ์ ์ ์์ ํตํฉ์ ๊ฐ๋ ๋ชฉํ๋ฅผ ๋ฌดํจํํ๋ ๊ฒ ๊ฐ์ต๋๋ค.
@sophiebits ์ข์, ๊ทธ๋ฐ ์์ผ๋ก RFC๋ฅผ ์์ฑํ ์ ์์ต๋๋ค. 10์ 26์ผ ์ ์ฒ์์ผ๋ก ์์ฑ์ ํด๋ผ์ด์ธํธ ์ธก์ผ๋ก ์ด๋ํ๊ณ ์ฌ๋๋ค์ด SSR์ ๋ํด ReactDOM.createCustomElementType์ ์์ฑํ ์ ์๋๋ก ํ๊ฑฐ๋ ํด๋ผ์ด์ธํธ๊ฐ ์์ฑ/์์ฑ์ ๋งคํํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์ ๋ง ์ธ๋ถํ๋ ์ ์ด๋ฅผ ์ํ๋ ๊ฒฝ์ฐ์ ๋ํด ์ด๋ป๊ฒ ์๊ฐํ์ญ๋๊น? ?
์ต์ํ createCustomElementType
์คํ์ผ์ ์ฌ์ฉํ๋ฉด ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ API๋ฅผ ์ฝ๊ฒ ๋งคํํ ์ ์์ต๋๋ค. ์ฆ, ์ฐ๋ฆฌ์ skatejs/renderer-react๋ props
์ฝ๊ฒ ๋ฐ์ React์ ๋ํ ์ฌ์ฉ์ ์ ์ ์์๋ฅผ ๊ตฌ์ฑํ ์ ์์ต๋๋ค. ์ด๋ฐ ์ข
๋ฅ์ ๋ฐ๋๋ผ ์ฌ๋๋ค์ ์ถ์ํ ๋๋ ์ฝ๊ฐ์ ์์
์์ด๋ ๋๊ณ ๊ฑด์กฐํฉ๋๋ค. ๋๋ ์ธ๋ถํ๋ ์ ์ด๋ฅผ ํ์ฉํ๋ฉด์ ์์ ํ ๊ธฐ๋ณธ๊ฐ์ ๋ํ Rob์ ์ ์์ ์ข์ํฉ๋๋ค. ๊ทธ๊ฒ ํจ๊ณผ๊ฐ ์์๊น์?
@robdodson ๋๋ ๊ทธ๊ฒ์
์ต์ 3์ ์ง๊ธ๊น์ง ์ต๊ณ ์ ์ต์ ์ด๋ฉฐ SSR๊ณผ ํจ๊ป ์๋ํ ์ ์์ต๋๋ค. ๋ฐฉ๋ฒ์ ๋ํ ์์ด๋์ด๋ฅผ ์ค๋ช ํ๊ฒ ์ต๋๋ค.
์ง๊ธ๊น์ง 3๊ฐ๋ฅผ ์ ์ธํ ๋ชจ๋ ์ต์ ์ ๋จ๋ ์ผ๋ก,
๋ค์์ ์ฐ๋ฆฌ ๋ชจ๋๊ฐ ๋์ํ๋ ๋ณดํธ์ ์ธ ๊ท์น์ ๋๋ค.
setAttribute
๋ฅผ ์ฌ์ฉํ์ฌ ํน์ฑ์ ์ค์ ํ๋ ๊ฒ์ ์ ์ธ์ HTML ํน์ฑ๊ณผ 1:1๋ก ์ผ์นํ๋ ๋ฐฉ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์์์ ์ ๋ฌํ๋ ๊ฐ์ฅ ํ์ค์ ์ธ ๋ฐฉ๋ฒ์
๋๋ค. ์ด๊ฒ์ ์ฐ์ฃผ์ ๋ฒ์น์ผ๋ก ํญ์ 100% ์๋ํด์ผ ํ๋ฏ๋ก ๋ฐ์ดํฐ๋ฅผ ์์์ ์ ๋ฌํ๋ ์ ์ผํ 100% ๋ณด์ฅ๋ ๋ฐฉ๋ฒ์
๋๋ค.๋ฐ๋ผ์ ์ต์ํ React๊ฐ _์ฐ์ฃผ์ ๋ชจ๋ ๋จ์ผ ์ฌ์ฉ์ ์ ์ ์์๋ก 100% ์๋ํ๊ณ
setAttribute
์ฆ 100 % ํ์ค ๋๋ฌธ์
๋๋ค.setAttribute
๋ง๋ค๊ณ , ์์ ์ ํด๋์ค ์ ์ ๋ฉ์๋๋ฅผ setAttribute
๋ฌธ์์ด์ด ์๋ ๋ค๋ฅธ ์ผ์ ๋์ํฉ๋๋ค. ๋ํ์ ์ธ ์๋ก A-frame๊ณผ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ค ์ ์์ต๋๋ค.setAttribute
์ ์์กดํ์ฌ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ชจ๋ ๊ฒ๊ณผ ํธํ๋๋ ์์๋ฅผ ๋ง๋๋ ๊ฒ์ ์๋ฝ ํด์ผ ํฉ๋๋ค. ๋ชจ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์์ฑ์ ์์กดํ๋ฉด ์ ์ฒด ์ ๋๋ฒ์ค๊ฐ ์๋ก ์๋ํฉ๋๋ค. _์ด๊ฒ์ ๋ํด ์ด๋ค ๊ฒฝ์ฐ๋ ์๊ณ , ๋ฐ๋๋ ์์ต๋๋ค!_ (w3c/whatwg๊ฐ ์ฝ๊ฐ์ ํฐ ๋ณ๊ฒฝ์ ๊ฐํ์ง ์๋ ํ)Soooooooo , ์ฆ, ์ฐ๋ฆฌ๋ ์ต์ํ
๊ทธ๋ฐ ๋ค์ ๋๋๋ก ๊ฐ์ฒด ์์ฑ API๊ฐ ์๋ ์์์ ์๋ฏธ์ ๋ํด ์๊ฐํ ์ ์์ต๋๋ค.
setAttribute
๊ฐ ํญ์ ์๋ํ๋ค๋ ๊ฒ์ ์๊ณ ์ฌ์ฉํ ์ ์์ต๋๋ค.๋ฐ๋ผ์ ์์ฑ๊ณผ ์์ฑ์ ๋ํ ์ด๋ฌํ ์ง์์ ๋ฐํ์ผ๋ก _ํ์ค์ 100% ํ์ฅํ๊ณ ์ฐ์ฃผ์ ๋ฒ์น์ ์กด์คํ๊ธฐ ๋ฅผ ๊ณผ ๊ฐ์์ผ ํฉ๋๋ค.
<x-foo blah="blah" />
์ default_์ง๋ _byํ๋ค setAttribute
ํ๊ณ _unchanged_ ๋ฐ๋ผ ๊ฐ์ ์ ๋ฌํฉ๋๋ค. ์ด๋ ์ค๋จ๋์ง ์๋ ๋ณ๊ฒฝ ์ฌํญ์
๋๋ค. ์ฌ์ค, ์ด๋ ์๋ฏธ ์๋ "[object Object]"
๋ฌธ์์ด์ด ์ ๋ฌ๋๋ ๊ฒฐ๊ณผ๋ฅผ ์ด๋ํ๋ ์์ ๋ณ๊ฒฝ ์ฌํญ์
๋๋ค.sigil์ ์ฌ์ฉํ๋ ์ต์
3(์ถ๊ฐ ๊ตฌ๋ฌธ์ ์์งํ ๋ฐฐ์ฐ๊ธฐ ์ด๋ ต์ง ์์)์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ด์์ ๊ฐ์ฅ ๊ฐ๊น์ด ์๋ฃจ์
์ธ ๊ฒ ๊ฐ์ต๋๋ค. ์ด SO ์ง๋ฌธ์ ๋ฐ๋ฅด๋ฉด ์ฌ์ฉ ๊ฐ๋ฅํ ์ ์ผํ ๊ธฐํธ๋ =
์ด์ง๋ง &
( \&
์ ๊ฐ์ ์ด์ค์ผ์ดํ ๊ฐ๋ฅํ ํ์ ์ฌ์ฉ)์ ๊ฐ์ ํญ๋ชฉ์ ์ ์ฐฉํ๋ ๊ฒ์ด ๋ ์ฝ๊ธฐ ์ฝ์ต๋๋ค. ์๋ฅผ ๋ค์ด ๊ตฌ์ฒด์ ์ผ๋ก ์ํ์ ์ํ๋ ๊ฒฝ์ฐ:
<x-foo &blah="blah" />
WHATWG HTML ๊ตฌ๋ฌธ ์ฌ์์์ ๋ค๋ฃจ๋ ๋๋ถ๋ถ์ ๋ค๋ฅธ ๋ฌธ์๋ ์๋ํด์ผ ํ๋ฉฐ ์๋ํ๊ธฐ๋ฅผ ๋ฐ๋๋๋ค. ๊ทธ๋ฌ๋ ์ด๋ ๋ค๋ฅธ ์ฃผ์ ์ ๋๋ค.
์ต์ 3์ ์ง๊ธ๊น์ง ์ต๊ณ ์ ์ต์ ์ ๋๋ค.
ํด๋ผ์ด์ธํธ์์ ์ํ๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ๋ฐ๋ผ์ ์ํ์ด SSR์์ ์๋ฏธ๊ฐ ์๋ค๋ฉด ์ค ๊ธ์์. ์ด์ ์๋ ์๋ํ์ง ์์์ผ๋ฉฐ ์ง๊ธ์ ์๋ํ์ง ์์๋ ๋ฉ๋๋ค. PHP ์คํ์ผ ๋๋ Java ์คํ์ผ SSR์ ์ํ ์์ด ์ ์ HTML์ ์ ์กํ๋ฉฐ ์์ฑ์ 100% ์์กดํฉ๋๋ค. ์ฆ, React SSR์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ํด๋ผ์ด์ธํธ ์ธก ์ํ๋ฅผ ์ฌ์ฉํ๊ณ ์ํ๋ฅผ ์ํ์ง ์๋ ๊ฒฝ์ฐ ์ด ๊ฒฝ์ฐ props๋ฅผ ์ฌ์ฉํ์ง ์์์ผ ํ๋ค๋ ์ฌ์ค์ ์๊ณ ์์ด์ผ ํฉ๋๋ค. _ ๊ฐ๋จํฉ๋๋ค. ๋ฐ์ํด์ผ ํ ๋ชจ๋ ๊ฒ์ ๋ฌธ์์์ ์ด ๊ฒฝ๊ณ ๋ฅผ ๋ช ํํ๊ฒ ํ๋ ๊ฒ์ ๋๋ค._
ํ์ง๋ง!!! ๊ทธ๊ฒ ๋ค๊ฐ ์๋์ผ! ์ฌ๋๋ค์๊ฒ ๋ ๋ง์ ์ ์ด ๊ถํ์ ์ ๊ณตํ๊ธฐ ์ํด ์ฌ์ ํ ์ต์ 5์ ๊ธฐ๋ฅ์ ํฌํจํ ์ ์์ต๋๋ค. ์ต์ 5์ ๊ฐ์ API๋ฅผ ์ฌ์ฉํ๋ฉด
๊ฒฐ๊ตญ ๋ค์์ ์๋ํ๋ ์๋ฃจ์ ์ฒ๋ผ ๋ณด์ ๋๋ค.
setAttribute
์ต์
3์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ค์์ ์ฌ์ฉ๋ฉ๋๋ค.์ํด ๋ณต ๋ง์ด ๋ฐ์ผ์ธ์!
์์ ๋ช ๊ฐ์ง ์ฌํญ์ ๋ตํ๊ณ ์ถ์ง๋ง ์ด ์ค๋ ๋๊ฐ ์ด๋ฏธ _๋ฏฟ์ ์ ์์ ์ ๋๋ก_ ๊ธธ๋ค๋ ์ฌ์ค์ด ๋๋ ต์ต๋๋ค. ๊ทธ๋์ ๋ ๊ธธ์ด์ ธ์ ์ฃ์กํฉ๋๋ค :P
๋ค์์ ์ฐ๋ฆฌ ๋ชจ๋๊ฐ ๋์ํ๋ ๋ณดํธ์ ์ธ ๊ท์น์ ๋๋ค.
setAttribute๋ฅผ ์ฌ์ฉํ์ฌ ํน์ฑ์ ์ค์ ํ๋ ๊ฒ์ ์ ์ธ์ HTML ํน์ฑ๊ณผ 1:1๋ก ์ผ์นํ๋ ๋ฐฉ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์์์ ์ ๋ฌํ๋ ๊ฐ์ฅ ํ์ค์ ์ธ ๋ฐฉ๋ฒ์ ๋๋ค. ์ด๊ฒ์ ์ฐ์ฃผ์ ๋ฒ์น์ผ๋ก ํญ์ 100% ์๋ํด์ผ ํ๋ฏ๋ก ๋ฐ์ดํฐ๋ฅผ ์์์ ์ ๋ฌํ๋ ์ ์ผํ 100% ๋ณด์ฅ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
์ด๊ฒ์ ์์ ํ ์ฌ์ค์ด ์๋๋๋ค. ํ๋ซํผ์๋ ์ฌ์ฉ์ ์ ์ ์์๊ฐ ์์ฑ ์ธํฐํ์ด์ค๋ฅผ ๋ ธ์ถํ๋๋ก ๊ฐ์ ํ๋ ๊ฒ์ด ์์ต๋๋ค. JS ์์ฑ๋ง ํ์ฉํ๋ ์์ฑ์ ์ฝ๊ฒ ๋ง๋ค ์ ์์ต๋๋ค. ๋ฐ๋ผ์ "๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ๋ณด์ฅ๋ ๋ฐฉ๋ฒ"์ด ์๋๋๋ค. ์ํ ๋ฉ์ปค๋์ฆ์ด ์๋ค๋ ๊ฒ์ 100% ํ์คํ๊ฒ ์คํ์ผ(HTML ์์ฑ ๋๋ JS ์์ฑ)์ ์์กดํ ์ ์๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
์ด๋ค ์ฌ๋๋ค์ ๊ทธ๊ฒ์ด ๋ฌธ์์ด๋ง์ ์ํด ์ค๊ณ๋ ๊ฒ์ ๋ง์กฑํ์ง ์์ต๋๋ค.
์ผ๋ถ ์์(์ผ๋ถ ์์๋ง ๋ฐ๋ณต)๋ ํน์ ์์ฑ์ ๋งคํ๋๋ ๊ฐ์ฒด ์์ฑ์ ํตํด ๊ฐ์ ํ์ฉํฉ๋๋ค. ์ด๊ฒ์ 100% ์ ๋ขฐํ ์ ์๋ ๊ฒ์ด ์๋๋๋ค.
์ฐ๋ฆฌ๋ ์ฌ๋๋ค์ด ๊ฐ์ฒด/๋ฐฐ์ด๊ณผ ๊ฐ์ ํ๋ถํ ๋ฐ์ดํฐ๋ฅผ ํ์ฉํ๋ ์์ฑ์ ๋ํ ์์ฑ์ ์์ฑํ๋ ๊ฒ์ ๊ท์ฐฎ๊ฒ ํ์ง ์๋๋ก ๊ถ์ฅํฉ๋๋ค. ์ด๋ ์ผ๋ถ ๋ฐ์ดํฐ๋ฅผ ์์ฑ ๋ฌธ์์ด๋ก ๋ค์ ์ง๋ ฌํํ ์ ์๊ธฐ ๋๋ฌธ์ ๋๋ค. ์๋ฅผ ๋ค์ด ๊ฐ์ฒด ์์ฑ ์ค ํ๋๊ฐ DOM ๋ ธ๋์ ๋ํ ์ฐธ์กฐ์ธ ๊ฒฝ์ฐ ์ค์ ๋ก ๋ฌธ์์ดํํ ์ ์์ต๋๋ค. ๋ํ ๊ฐ์ฒด๋ฅผ ๋ฌธ์์ดํํ๊ณ ์ฌ๋ถ์ํ๋ฉด ๊ฐ์ฒด์ ID๊ฐ ์์ค๋ฉ๋๋ค. ์ฆ, ๋ค๋ฅธ POJO์ ๋ํ ์ฐธ์กฐ๊ฐ ์๋ ๊ฒฝ์ฐ ์์ ํ ์๋ก์ด ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ธฐ ๋๋ฌธ์ ํด๋น ์ฐธ์กฐ๋ฅผ ์ค์ ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ด๋ค ์ฌ๋๋ค์ ๋น๋ฌธ์์ด์ ๋ฐ์๋ค์ผ ์ ์๊ธฐ ๋๋ฌธ์ ๊ฐ์ฒด ์์ฑ์ ์ข์ํฉ๋๋ค.
๋ฐ๋ผ์ React๋ 100% ํ์ค์ด๊ธฐ ๋๋ฌธ์ ๊ธฐ๋ณธ์ ์ผ๋ก setAttribute๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํด์ผ ํฉ๋๋ค.
JavaScript ์์ฑ์ ํ์ค๊ณผ ๋์ผํฉ๋๋ค. ๋๋ถ๋ถ์ HTML ์์๋ ์์ฑ๊ณผ ํด๋น ์์ฑ ์ธํฐํ์ด์ค๋ฅผ ๋ชจ๋ ๋
ธ์ถํฉ๋๋ค. ์: <img src="">
๋๋ HTMLImageElement.src .
React๋ Custom Element ์์ฑ์๊ฐ ํด๋์ค ์ ์์์ setAttribute ๋ฉ์๋๋ฅผ ํ์ฅ/์ฌ์ ์ํ ์ ์๋ค๋ ์ฌ์ค์ ๋ฐ์๋ค์ฌ์ผ ํฉ๋๋ค. setAttribute๋ ๋ฌธ์์ด ์ด์ธ์ ๊ฒ์ ํ์ฉํฉ๋๋ค.
์์ฑ์๋ ๊ทธ๋ ๊ฒ ํ ์ ์์ง๋ง ์ค์ ๋ก๋ JS ์์ฑ์ ์ฌ์ฉํ๋ ๊ฒ๋ณด๋ค ํจ์ฌ "๋นํ์ค"์ธ ๊ฒ ๊ฐ์ต๋๋ค. ๋ํ ์์ ๊ตฌ๋ฌธ ๋ถ์ ๋ฐ ๋ณต์ ์ ๊ด๋ จ๋ ์ด์ํ ๋ฌธ์ ์ ๋ ธ์ถ๋ ์ ์์ต๋๋ค.
React๋ ์ฌ์ฉ์ ์ ์ ์์ ์์ฑ์๊ฐ ์ฌ์ฉ์ ์ ์ ์์๊ฐ React๋ฟ๋ง ์๋๋ผ ๋ชจ๋ ๊ฐ๋ฅํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํจ๊ป ์๋ํ๊ธฐ๋ฅผ ์ํ๋ ๊ฒฝ์ฐ ํด๋น ์์ฑ์๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ชจ๋ ๊ฒ๊ณผ ํธํ๋๋ ์์๋ฅผ ๋ง๋ค๊ธฐ ์ํด setAttribute์ ์์กดํ๊ณ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ชจ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์์ฑ์ ์์กดํ๋ ๊ฒฝ์ฐ ์๋ฝํด์ผ ํฉ๋๋ค. , ๊ทธ๋ฌ๋ฉด ์จ ์ฐ์ฃผ๊ฐ ์๋ก ํ๋ ฅํ ๊ฒ์ ๋๋ค. ์ด๊ฒ์ ๋ํด์๋ if, and, buts๊ฐ ์์ต๋๋ค! (w3c/whatww๊ฐ ํฐ ๋ณํ๋ฅผ ์ฃผ์ง ์๋ ํ)
์ฌ์ฉ์ ์ ์ ์์(์: Angular)์ JS ์์ฑ์ ์ค์ ํ๋ ๊ฒ์ ์ ํธํ๋ ๋ค๋ฅธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์๊ธฐ ๋๋ฌธ์ ์ด ๊ฒฐ๋ก ์ ์ด๋ป๊ฒ ๋๋ฌํ๋์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ์ต๋์ ํธํ์ฑ์ ์ํด ์์ฑ์๋ JS ์์ฑ์ผ๋ก ์์ฑ์ ์ง์ํด์ผ ํฉ๋๋ค. ๊ทธ๊ฒ์ ๊ฐ๋ฅํ ์ฌ์ฉ์ ๊ฐ์ฅ ํฐ ํ๋ฉด์ ์ ๋ฎ์ ๊ฒ์ ๋๋ค. Polymer๋ก ์์ฑ๋ ๋ชจ๋ ์์๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ด ์์ ์ ์ํํฉ๋๋ค.
์์ฑ์ด ๊ธฐ๋ณธ์ ์ผ๋ก 100% ์๋ํ๋๋ก ํ์ฉํฉ๋๋ค. ์ด๊ฒ์ ์๋ฏธํฉ๋๋ค
๊ธฐ๋ณธ์ ์ผ๋ก setAttribute์ ๋งคํ๋๊ณ ๋ณ๊ฒฝ๋์ง ์์ ๊ฐ์ ์ ๋ฌํด์ผ ํฉ๋๋ค. ์ด๋ ์ค๋จ๋์ง ์๋ ๋ณ๊ฒฝ ์ฌํญ์ ๋๋ค. ์ฌ์ค, ๊ทธ๋ ์ง ์์ผ๋ฉด ์๋ฏธ ์๋ "[object Object]" ๋ฌธ์์ด์ด ์ ๋ฌ๋๋ ์์ ๋ณ๊ฒฝ ์ฌํญ์ ๋๋ค.
๋๋ React๊ฐ ์ค์ ๋ก ๊ฐ์ ๋ณ๊ฒฝํ์ง ์๊ณ ์ ๋ฌํ๋ _is_๋ผ๊ณ ์๊ฐํฉ๋๋ค. setAttribute('foo', {some: object})
ํธ์ถํ๋ฉด [object Object]
๋ฉ๋๋ค. ๊ทธ๋ค์ด ๊ฐ์ฒด์ ๋ํด JSON.stringify()
๋ฅผ ํธ์ถํ๋๋ก ์ ์ํ์ง ์๋ ํ? ๊ทธ๋ฌ๋ ๊ทธ ๊ฐ์ฒด๋ "๋ณ๊ฒฝ๋์ง ์์" ๊ฒ์ด ์๋๋๋ค. setAttribute()
์(๋ฅผ) ์ฌ์ ์ํ ์์ฑ์์๊ฒ ์์กดํ๊ณ ์๋ ๊ฒ ๊ฐ์ต๋๋ค. DOM์ ์์ญ์ด ํจ์นํ๋ ๋์ ํด๋น JS ์์ฑ์ ์์ฑํ๋๋ก ๊ถ์ฅํ๋ ๊ฒ์ด ๋ ๊ทธ๋ด๋ฏํฉ๋๋ค.
๋๋ React๊ฐ ์ค์ ๋ก ๊ฐ์ ๋ณ๊ฒฝํ์ง ์๊ณ ์ ๋ฌํ๋ _is_๋ผ๊ณ ์๊ฐํฉ๋๋ค.
setAttribute('foo', {some: object})
ํธ์ถํ๋ฉด[object Object]
React๋ setAttribute
์ ๋ฌํ๊ธฐ ์ ์ ๊ฐ์ ๋ฌธ์์ด๋ก ๊ฐ์ ๋ณํํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ
๋๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋น์ ์ด ๋งํ ๋ชจ๋ ๊ฒ์ ๋์ํฉ๋๋ค.
์ฐ๋ฆฌ๋ ์ฌ๋๋ค์ด ์๋ฐฉํฅ์ผ๋ก ์ผ์ ํ๋ค๋ ๋ฐ ๋์ํ๊ณ ๋ชจ๋ ์ฌ๋์ด ์ด๋ ํ ๋ฐฉํฅ์ผ๋ก๋ง ํ๋๋ก ๊ฐ์ํ๋ ํ์ค์ด ์๊ธฐ ๋๋ฌธ์ ์ฌ์ ํ ์๊ฐํฉ๋๋ค.
setAttribute
๊ฐ ๊ธฐ๋ณธ์ ์ผ๋ก ์ฌ์ฉ๋๋ ์ต์
3๊ณผ ์ธ์คํด์ค ์์ฑ์ ์ฌ์ฉํ๋๋ก ์ง์ ํ๊ธฐ ์ํ ์ธ์ฅ,์ต์ 5๊ฐ ์ ์ํ๋๋ฉด SSR ์๋ฃจ์ ์ ๋ํ ์ํ๋ ์ต์ 5 API๋ฅผ ์ฌ์ฉํ์ฌ ์ง์ ํ ์ ์๋ ์์ฑ ๋๋ ์ํ์ ๋ฐ์ดํฐ๋ฅผ ๋งคํํ ์ ์์ต๋๋ค.
React๋ setAttribute์ ์ ๋ฌํ๊ธฐ ์ ์ ๊ฐ์ ๋ฌธ์์ด๋ก ๊ฐ์ ๋ณํํฉ๋๋ค.
์ ๊ฒ ์ด์. ๋๋ถ๋ถ์ ์ฌ๋๋ค์ ์ฌ์ฉ์ ์ ์ toString()
์ ์ํ์ง ์๊ธฐ ๋๋ฌธ์ ๊ธฐ๋ณธ๊ฐ์ [object Object]
์
๋๋ค.
๋๋ถ๋ถ์ ์ฌ๋๋ค์ ์ฌ์ฉ์ ์ ์
toString()
์ ์ํ์ง ์๊ธฐ ๋๋ฌธ์ ๊ธฐ๋ณธ๊ฐ์[object Object]
์ ๋๋ค.
๋ง์น ๋ด๊ฐ ํ๋ ๊ฒ์ฒ๋ผ
const div = document.createElement('div')
div.setAttribute('foo', {a:1, b:2, c:3})
๊ฒฐ๊ณผ๋
<div foo="[object Object]"></div>
๋ถ๋ช ํ ์น ๊ฐ๋ฐ์๋ก์ ์ฐ๋ฆฌ๋ ๋น๋ฌธ์์ด์ ์์ ์์ฑ์ ์ ๋ฌํ ๋ ์ด๋ค ์ผ์ด ๋ฐ์ํ๋์ง ์๊ณ ์์ด์ผ ํฉ๋๋ค. ์๋ฅผ ๋ค์ด ๋น๋ฌธ์์ด์ A-Frame ์์์ ์ ๋ฌํ ์ ์๋ค๋ ๊ฒ์ ์๊ณ ์์ผ๋ฉฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ๋ฐฉํด๋ฐ์ง ์๊ณ ์์ ๋กญ๊ฒ ํด์ผ ํฉ๋๋ค.
React๋ ๊ทธ๊ฒ์ด ์ ์ด ์๋๋ผ๋ ๊ฒ์ ๊นจ๋ฌ์์ผ ํฉ๋๋ค. ์ฌ๋๋ค์ด react ์ธ์ ์ฌ์ฉํ๋ ๋ค๋ฅธ ๋ง์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์์ต๋๋ค.
์ด๊ฒ์ ๋ถํ์ํ๊ฒ ๋น๊ผฌ๋ ๊ฒ์ ๋๋ค. ์ด ์ค๋ ๋์์ ์ฐ๋ฆฌ๋ ์ด๊ฒ์ ๊ด์ฌ์ด ์์ง๋ง ์ฌ์ฉ์ ์ ์ ์์ ๋์์ธ์ ์ทจํ ์์น์ ๋ํ ๋ค์ํ ์ต์ ๊ณผ ๋น์ ์ด ์์์ ์ ์ ์์ต๋๋ค. ๋ฌด์์ ํด์ผ ํ๋์ง ๋ถ๋ช ํ์ง ์์ต๋๋ค.
@sebmarkbage ์ฃ์กํฉ๋๋ค. ์ ๋
๋ด๊ฐ ์๋ฏธํ๋ ๋ฐ๋ React๊ฐ ๋งค์ฐ ์ธ๊ธฐ๊ฐ ์๋ค๋ ๊ฒ์ ๋๋ค. ๊ทธ๋์ React๋ ๋ค๋ฅธ ๊ณณ์์๋ ์๋ํ์ง ์์ ์ ์๋ ํน์ ํ ๋ฐฉ์์ผ๋ก ์ผ์ ํ๋๋ก ์ฌ๋๋ค์ ํ๋ค ์ ์๋ ๊ฐ๋ฅ์ฑ์ด ์์ต๋๋ค. t ๋ชจ๋ ์ฌ์ฉ์ ์ ์ ์์์ ํจ๊ป ์๋).
React๋ ํ์ฌ ์์ ์์ฑ์ ์ ๋ฌ๋ ๋ชจ๋ ๊ฐ์ ๋ฌธ์์ด๋ก ๋ณํํฉ๋๋ค. ์๋ฅผ ๋ค์ด React๊ฐ ์ด ์์ ์ ์ํํ์ง ์์๋ค๋ฉด (๋ฌธ์์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋) frame-react ๊ฐ
React๊ฐ ์ผ๋ฐ JavaScript์์์ ๊ฐ์ด ๋ฐ์ดํฐ๋ฅผ ์์์ ์ ๋ฌํ๋ ๋ฐฉ๋ฒ์ ์ ํํ ์ ์๊ฒ ํด์ค๋ค๋ฉด ๊ฐ์ฅ ๋ง์กฑ์ค๋ฌ์ด ์ฌ์ฉ์๊ฐ ๋ ๊ฒ์ ๋๋ค. ๐
๋ค์ ํ ๋ฒ ๋ง์๋๋ฆฌ์ง๋ง ์ฃ์กํฉ๋๋ค. ๋ค์์ ํ๋ฒ ๋ ์๊ฐํด๋ด์ผ๊ฒ ์ต๋๋ค.
์ด์ ๋ํ RFC PR์ ๋ํ ์ค๋ช ์ ์ถ๊ฐํ์ต๋๋ค. ์ฌ์ฉ์ ์ ์ ์์์ ๊ทธ ์์ฑ์ ์์ ์ ์ผ๋ก ์ถ๋ก ํ๊ธฐ ์ํ ๋ ๊ฐ๋จํ ๋ชจ๋ธ๋ฟ๋ง ์๋๋ผ ์ ์๋ ๋ด์ฉ์ ๋ค๋ฃจ๊ธฐ ๋๋ฌธ์ ๋ ผ์ํ ๊ฐ์น๊ฐ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ๋ค์ ํ์ด๋ธ๋ฆฌ๋ ์ ๊ทผ ๋ฐฉ์์ผ๋ก ์ ํํ์ง๋ง ๋๋ถ๋ถ์ ์ฌ์ฉ ์ฌ๋ก์ ๋ํด ๊ตฌ์ฑ์ด ํ์ ์๋ ํตํฉ ๋ฐฉ์์ ์ ๊ณตํฉ๋๋ค.
์ด ๊ธฐ๋ฅ์ด React์์ ๊ตฌํ๋๋ ๊ฒ์ ๋ณด๊ณ ์ถ์ต๋๋ค. React๋ฅผ ํ๋ฅญํ๊ฒ ๋ง๋๋ ๋ ธ๋ ฅ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค.
์ด RFC์ ๋ํ ์ ๋ฐ์ดํธ๊ฐ ์์ต๋๊น?
์ฌ์ฉ์ ์ ์ ์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ ๋ง ์ข์์ง๊ณ ์์ผ๋ฉฐ ๋ด React ์ฑ์์ ์ฌ์ฉํ๊ณ ์ถ์ต๋๋ค. ์์ง ์์์ด ์๋์? ์ฌ์ฉ์ ์ ์ ์์๋ฅผ ๋ํํ๊ณ ๋์ค์ ๋ค์ ๊ตฌ๋ฌธ ๋ถ์ํ๊ธฐ ์ํด ํด๋น ๋ด์ฉ์ ๋ฌธ์์ดํํ๋ ๊ฒ์ Vue ๋ฐ Angular๊ฐ ๊ธฐ๋ณธ์ ์ผ๋ก ๊ตฌ์ฑ ์์๋ฅผ ์ฝ๊ฒ ์ฒ๋ฆฌํ๋ค๋ ์ ์ ๊ณ ๋ คํ ๋ ์๋นํ ์คํ ๋ถ๊ฐ๋ฅํ ์๋ฃจ์ ์ ๋๋ค.
์ด ๋ฌธ์ ์ ๋ํ ์ ๋ฐ์ดํธ๊ฐ ์์ต๋๊น?
๋๋ ํดํน์ ์์กดํ์ง ์๊ณ ์ฌ์ฉ์ ์ ์ ์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๊ณ ์ถ์ต๋๋ค. ์ด ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋์์ผ๋ฉด ํฉ๋๋ค.
@mgolub2 React ํ์ ์น ์ปค๋ฎค๋ํฐ๊ฐ ์ํ๋ ๊ฒ์ด ๋ฌด์์ธ์ง ์ ๊ฒฝ ์ฐ์ง ์์ต๋๋ค. ์น ๊ตฌ์ฑ ์์๋ ์ด์ ๋๋ฆฌ ์ง์๋๋ ํ์ค์ด๋ฉฐ 2๋ ์ด ์ง๋ ํ์๋ ์ด ํ์ค์ ์ง์ํ๋ผ๋ ํ์ ์ ํธ๊ฐ ์์ต๋๋ค.
์๋ ํ์ธ์ ์ฌ๋ฌ๋ถ, ์ ๋ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ค์ ๋ ์ค์ ๋ณ๊ฒฝํ์ฌ ํ ๋ฆฌํ์คํธ๋ฅผ ์์ํ์ต๋๋ค: https://github.com/facebook/react/pull/16899
์ด๋ฅผ ํตํด ์ฌ์ฉ์ ์ ์ ์์ ์์ฑ์๋ ๋ค์๊ณผ ๊ฐ์ ์์ ์ ์ํํ ์ ์์ต๋๋ค.
class MyElement extends HTMLElement {
setAttribute(name, value) {
// default to existing behavior with strings
if (typeof value === 'string')
return super.setAttribute(name, value)
// but now a custom element author can decide what to do with non-string values.
if (value instanceof SomeCoolObject) { /*...*/ }
}
}
ํ์ฅ๋ setAttribute
๋ฉ์๋์ ๋ชจ์์๋ ๋ง์ ๋ณํ์ด ์์ผ๋ฉฐ ์ด๋ ํ๋์ ์์ ์์ผ ๋ฟ์
๋๋ค.
React ํ, ์ฌ์ฉ์ ์ ์ ์์ ์์ฑ์๋ ๊ฒฝ์ฐ์ ๋ฐ๋ผ DOM์ ๊ธฐ๋ณธ ์์ฑ ์ฒ๋ฆฌ๋ฅผ ์ฐํํ๊ธฐ ๋๋ฌธ์(๊ฐ์ด ๋ฌธ์์ด์ด ์๋ ๊ฒฝ์ฐ fe) ๊ทธ๋ ๊ฒ ํด์๋ ์ ๋๋ค๊ณ ์ฃผ์ฅํ ์ ์์ต๋๋ค. ๋น์ ์ด ๊ทธ ์๊ฒฌ์ ๊ฐ์ง๊ณ ์๋ค๊ณ ํด๋ ๊ทธ๊ฒ์ด ์ฌ์ฉ์ ์ ์ ์์ ์์ฑ์๊ฐ __ ์ฌ์ฉ์ ์ ์ __ ์์๋ก ํ ์ ์๋ ์ผ์ ๋ฐฉํดํด์ผ ํ๋ค๋ ์๋ฏธ๋ ์๋๋๋ค.
React๋ ๊ธฐ์กด DOM API๊ฐ ์ด๋ป๊ฒ ์ฌ์ฉ๋๋์ง์ ๋ํด ์๊ฒฌ์ ์ ์ํด์๋ ์ ๋ฉ๋๋ค. React๋ DOM์ ์กฐ์ํ๊ธฐ ์ํ ๋๊ตฌ์ด๋ฉฐ DOM์ ๋ํด ์ํํ ์ ์๋ ์์ ์ ๋ํด ์๊ฒฌ์ ์ ์ํด์๋ ์ ๋ฉ๋๋ค. "๋ฐ์ดํฐ๊ฐ DOM์ผ๋ก ํ๋ฅด๋ ๋ฐฉ์"์ด๋ ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ์ง ์๊ณ ๋ฐ์ดํฐ๊ฐ ๊ฑฐ๊ธฐ์ ๋๋ฌํ๋ ๋ฐ ๊ฑธ๋ฆฌ๋ ๊ฒฝ๋ก๋ฅผ ์๋ฏธํฉ๋๋ค(์์ฑ์์ ๊ฐ์ฒด๋ฅผ ๋ฌธ์์ด๋ก ๋ณํํ๋ ๊ฒ์ ์์ฑ์์ ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ๋ ๊ฒ์ ๋๋ค).
์์ฑ์์ ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ๋ ค๋ ์ด์ ๋ ๋ฌด์์ ๋๊น? DOM์ ์กฐ์ํ๋ ค๋ ์ฌ๋์ด DOM์ ์ ๋ฌํ ๋ฐ์ดํฐ๋ฅผ ์๊ณ ์๋ค๊ณ ๊ฐ์ ํ ์ ์๋ ์ด์ ๋ ๋ฌด์์ ๋๊น?
@trusktr ๋๋ ์ด๊ฒ์ด https://github.com/facebook/react/issues/10070 ์์ ๋ ผ์๋์๋ค๊ณ ์๊ฐํฉ๋๋ค.
์ฌ์ฉ์ ์ ์ ์์ ์์ฑ์์๊ฒ setAttribute
์ ๊ฐ์ ๋ด์ฅ ๋ฉ์๋๋ฅผ ์ฌ์ ์ํ๋ผ๊ณ ๋งํ๋ ๊ฒ์ ๋ํด ์ฌ๋๋ค์๊ฒ ์ ๋ง ์ฃผ์๋ฅผ ์ฃผ๊ณ ์ถ์ต๋๋ค. ์ฐ๋ฆฌ๊ฐ ์์ญ์ด ํจ์น๋ฅผ ํ ์๋๊ฐ ์๋๋ผ๊ณ ์๊ฐํฉ๋๋ค. cc @gaearon
์ด์ ๊ฐ์ ํ์ ํด๋์ค์์ setAttribute
๋ฅผ ์ฌ์ ์ํ๋ ๊ฒ์ ๋ฌดํดํฉ๋๋ค(์์ญ์ด ํจ์น๊ฐ ์๋). ๊ทธ๋ฌ๋ ๋ด๊ฐ ์ธ๊ธํ๋ฏ์ด, ๊ทธ๊ฒ์ด ๋ฐ๋์ React ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์์
์ด ์๋ ๊ฒฝ์ฐ React๊ฐ ๊ทธ๊ฒ์ ๋ํด ์ง์ํด์ผ ํ๋ ์ด์ ๋ ๋ฌด์์
๋๊น? ์ฐ๋ฆฌ๋ (์ฅ์ ์์ด) DOM์ ์กฐ์ํ๊ธฐ ์ํด React๋ฅผ ์ฌ์ฉํ๊ธฐ๋ฅผ ์ํฉ๋๋ค.
์ฑ๋ฅ ํฅ์์ ์ํด ์๋์ผ๋ก el.setAttribute()
๋ฅผ ์ฌ์ฉํด์ผ ํ๋ ๊ฒฝ์ฐ์๋ ๊ฐ๋ฐ ํ๊ฒฝ์ด ์
ํ๋ฉ๋๋ค.
React ํ์ด setAttribute
๋ก ์ ๋ฌ๋ ๋ชจ๋ ๊ฒ์ ๋ฌธ์์ด๋ก ๋ณํํ์ฌ ์์ฒญ๋ ์ํ์์ ๋ง์ ์ฌ๋๋ค์ ๊ตฌํ๊ณ ์๋ค๊ณ ์๊ฐํ์ง ์์ต๋๋ค.
๋ค๋ฅธ ์๋ฃจ์ ์ด ๋ ๋์ ์ ์๋ค๋ ๋ฐ ๋์ํฉ๋๋ค. ์๋ฅผ ๋ค์ด JSX ์ฌ์์ ์๋ก์ด ๊ตฌ๋ฌธ์ผ๋ก ์ ๋ฐ์ดํธํ์ง๋ง ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆฌ๋ ๊ฒ ๊ฐ์ต๋๋ค.
์๋ ๋ฌธ์์ด ๋ณํ์ ์์ ๋ฉด ์ปค๋ฎค๋ํฐ๊ฐ ์๋ ๊ฒ์ ๋ฌด์์ ๋๊น? React ํ์ ๋ฌด์์ ์์ต๋๊น?
React ํ์ ๋์ค์ ๋ ๋์ ์๋ฃจ์ ์ผ๋ก ์ํฉ์ ๊ฐ์ ํ ์ ์์ต๋๋ค.
์ต์ํ ๋จ์ํ ๋ฌธ์์ดํ๋ฅผ ์ฐํํ ์ ์๋ ์ต์ ์ ์ ๊ณตํ์ง ์๋ ์ด์ ๋ ๋ฌด์์ ๋๊น? ๊ทธ๊ฒ์ ๋น์ ์ด ๊ธฐ๊บผ์ด ๊ณ ๋ คํ ์ ์๋ ๊ฒ์ ๋๊น?
์ฌ์ฉ์ ์ ์ ์์ ์์ฑ์์๊ฒ
setAttribute
์ ๊ฐ์ ๋ด์ฅ ๋ฉ์๋๋ฅผ ์ฌ์ ์ํ๋ผ๊ณ ๋งํ๋ ๊ฒ์ ๋ํด ์ฌ๋๋ค์๊ฒ ์ ๋ง ์ฃผ์๋ฅผ ์ฃผ๊ณ ์ถ์ต๋๋ค.
๊ทธ ์ด์ ์ ๋ํด ์ข์ ์ด์ ๋ฅผ ์ ์ํ ์ ์์ต๋๊น?
์ด๊ฒ์ ์ฒญ์ด์ฒ๋ผ ๋ณด์ ๋๋ค. "์ฌ์ฉ์ ์ ์ ์์๋ฅผ ์์ฑํ๋ ๋ชจ๋ ์ฌ๋์ด ์์ ์ ์์์ ํน์ ๋์์ด ์๋ ๋ฉ์๋๋ฅผ ์ฒจ๋ถํ๋๋ก ์ค๋"์ DOM ์์์ ์์ฑ์ ์ค์ ํ๋ ๋ฐฉ๋ฒ์ ๋ํ ์ด ๋ฌธ์ ์ ๋ํ ํด๊ฒฐ์ฑ ์ด ์๋๋๋ค.
@trusktr
๊ทธ ์ด์ ์ ๋ํด ์ข์ ์ด์ ๋ฅผ ์ ์ํ ์ ์์ต๋๊น?
์น ๊ตฌ์ฑ ์์๋ ํ์ค์ ๋๋ค. ๋ฐ๋ผ์ ํ์ค์ ํ์๋ฌผ๋ ํ์ค์ ์ค์ํด์ผ ํฉ๋๋ค.
๊ทธ๋ฌ๋ setAttribute
์ฌ์ ์ํ๋ ๊ฒ์ ์ด ์กฐ๊ฑด์ ๋ง์ง ์์ต๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ์น ๊ตฌ์ฑ ์์์ ํจ๊ป ์๋ํ๋ ๋ค๋ฅธ ๋ง์ ํ๋ ์์ํฌ๊ฐ ์์ง๋ง React์ ๋ํด์๋ง ํดํน์ ์์ฑํฉ๋๋ค. ๋ฐ๋ผ์ React์ ์ ํ ์๋ํ์ง ์๋ ๊ฒฝ์ฐ์๋ React ํต์ ์๋นํด์ผ ํฉ๋๋ค. ๋๋ ๊ทธ๊ฒ์ด ์ฌ๋ฐ๋ฅธ ํด๊ฒฐ์ฑ
์ด๋ผ๊ณ ์๊ฐํ์ง ์์ต๋๋ค.
๋ค์์ผ๋ก, ํ์ค ๋ฐฉ๋ฒ์ ํจ์นํ๋ ๊ฒ์ ์๋ชป๋ ์ ๊ทผ ๋ฐฉ์์ด๋ผ๋ ๊ฒ์ ์ ์๋ ค์ ธ ์์ต๋๋ค. setAttribute
์ฌ์ ์ํ๋ฉด ์ต์ข
์ฌ์ฉ์๊ฐ ์ฌ์ฉํ๋ ค๊ณ ํ ๋ ํผ๋์ค๋ฌ์ํ ์ ์๋ ์๋ ๋์์ด ๋ณ๊ฒฝ๋ฉ๋๋ค. ๋ชจ๋ ์ฌ๋์ ํ์ค์ด ํ์ค์ผ๋ก ์๋ํ๊ธฐ๋ฅผ ๊ธฐ๋ํ๋ฉฐ ์ฌ์ฉ์ ์ง์ ์์๋ ์์ธ๋ ์๋๋๋ค. HTMLElement
๋์์ ์์ํ๊ธฐ ๋๋ฌธ์
๋๋ค. React์ ํจ๊ป ์๋ํ ์๋ ์์ง๋ง ๋ค๋ฅธ ๋ชจ๋ ์ฌ์ฉ์๋ฅผ ์ํ ํจ์ ์ ๋ง๋ญ๋๋ค. ์๋ฅผ ๋ค์ด ํ๋ ์์ํฌ ์์ด ์น ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ setAttribute
๊ฐ ๋ง์ด ํธ์ถ๋ ์ ์์ต๋๋ค. ์ฌ์ฉ์ ์ ์ ์์ ๊ฐ๋ฐ์๊ฐ ์ด ์ ๊ทผ ๋ฐฉ์์ผ๋ก ๋ฐ์ ๋ผ๋ ๋ฐ ๋์ํ ์ง ์์ฌ์ค๋ฝ์ต๋๋ค.
๊ฐ์ธ์ ์ผ๋ก, ์ด๋ค ์ข ๋ฅ์ React ๋ํผ๊ฐ ํจ์ฌ ๋ ์ ๋งํด ๋ณด์ธ๋ค๊ณ ์๊ฐํฉ๋๋ค.
์ฌ๋ฌ๋ถ, ๊ธฐ๋ค๋ฆฌ๋ ๋์ React https://www.npmjs.com/package/reactify-wc ์์ ์น ๊ตฌ์ฑ ์์๋ฅผ ๋ํํ๊ธฐ ์ํ shim์ ๋ง๋ค์์ต๋๋ค.
import React from "react";
import reactifyWc from "reactify-wc";
// Import your web component. This one defines a tag called 'vaadin-button'
import "@vaadin/vaadin-button";
const onClick = () => console.log('hello world');
const VaadinButton = reactifyWc("vaadin-button");
export const MyReactComponent = () => (
<>
<h1>Hello world</h1>
<VaadinButton onClick={onClick}>
Click me!
</VaadinButton>
</>
)
์ด๊ฒ์ด ๋์์ด ๋๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
(์ด๊ฒ์ ๋ด๊ฐ OSS์ ์ฒ์์ผ๋ก ์ง์ถํ ๊ฒ์ด๊ณ , ์ฌ๋ฌด์ค ๋ฐ์์ ๋ฌด์ธ๊ฐ๋ฅผ ๊ณต๊ฐํ ์ต์ด์ ๊ฒ ์ค ํ๋์ ๋๋ค. ๊ฑด์ค์ ์ธ ๋นํ์ ๋ํ ๋์ ์์ด ํ์์ ๋๋ค ๐ )
์ฌ๋ฌ๋ถ, ๊ธฐ๋ค๋ฆฌ๋ ๋์ React https://www.npmjs.com/package/reactify-wc ์์ ์น ๊ตฌ์ฑ ์์๋ฅผ ๋ํํ๊ธฐ ์ํ shim์ ๋ง๋ค์์ต๋๋ค.
import React from "react"; import reactifyWc from "reactify-wc"; // Import your web component. This one defines a tag called 'vaadin-button' import "@vaadin/vaadin-button"; const onClick = () => console.log('hello world'); const VaadinButton = reactifyWc("vaadin-button"); export const MyReactComponent = () => ( <> <h1>Hello world</h1> <VaadinButton onClick={onClick}> Click me! </VaadinButton> </> )
์ด๊ฒ์ด ๋์์ด ๋๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
(์ด๊ฒ์ ๋ด๊ฐ OSS์ ์ฒ์์ผ๋ก ์ง์ถํ ๊ฒ์ด๊ณ , ์ฌ๋ฌด์ค ๋ฐ์์ ๋ฌด์ธ๊ฐ๋ฅผ ๊ณต๊ฐํ ์ต์ด์ ๊ฒ ์ค ํ๋์ ๋๋ค. ๊ฑด์ค์ ์ธ ๋นํ์ ๋ํ ๋์ ์์ด ํ์์ ๋๋ค ๐ )
ํ๋ฅญํ ๋ํผ :)
Stencil๋ก ์น ๊ตฌ์ฑ ์์๋ฅผ ๋น๋ํ๋ฉด React์์ ์ด ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋๋ค๋ ์ ๋ ์ธ๊ธํ ๊ฐ์น๊ฐ ์์ต๋๋ค. https://stenciljs.com/docs/faq#can -data-be-passed-to-web-components-
@matsgm Stencil์ ์ฌ์ฉํ ๋น๋๊ฐ ๋์์ด ๋์ด ๊ธฐ์ฉ๋๋ค. ๊ทธ๋ฌ๋ ์ฐ๋ฆฌ ๊ฒฝํ์ ๋ฐ๋ฅด๋ฉด Stencil์ ๋ค๋ฅธ ์น ๊ตฌ์ฑ ์์ ํ๋ ์์ํฌ, ํนํ Polymer์์ ์ ๋๋ก ์๋ํ์ง ์๋ ๊ฒ์ผ๋ก ์ ์ฆ๋์์ผ๋ฉฐ ๋น๋ ๋๊ตฌ, ์ง์ ๋ฐ ์ผ๋ฐ ๊ธฐ๋ฅ ์ฌ์ด์ 6๊ฐ์ง ๋ค๋ฅธ ๋ฌธ์ ๋ก ์ธํด ์ง์ฆ์ด ๋ฌ์ต๋๋ค. ๊ทํ์ ๋ง์ผ๋ฆฌ์ง๊ฐ ๋ค๋ฅผ ์ ์์ต๋๋ค :)
์ด ์ค๋ ๋๋ก ์ต์ ์ ๋ณด๋ฅผ ์ป์ผ๋ ค๊ณ ํฉ๋๋ค. ์ต์ข ํด๊ฒฐ์ฑ ์ ๋ฌด์์ ๋๊น?
์ด๋ค ๋ฉด์์ ์ ๋ ๋งค์ฐ ํผ๋์ค๋ฌ์ธ ์ ์๋ ๋ง์ ์ ๋ฐ๊ฒฌ๋ณด๋ค ์์ฑ, ์ํ, ์ด๋ฒคํธ๋ฅผ ๋ช ์์ ์ผ๋ก ์ ์ํ๋ ๊ฒ์ ์ข์ํฉ๋๋ค.
์๋ฅผ ๋ค์ด snabbdom ์ ๋ช
์์ ์ธ ์ต์์ ๋ค์์คํ์ด์ค๋ฅผ ์ฌ์ฉํ๋ฏ๋ก ๋ฌด์์ด ์ด๋๋ก ๊ฐ๋์ง ์ฝ๊ฒ ์ ์ ์์ต๋๋ค. ๋ ๋น ๋ฅธ ์คํ์ ์ํ ๋ฌธ์์ด ์กฐ์์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด onClick
=> click
์์ ์ ๋ฏธ์ฌ๋ฅผ ์๋ฅด๋ ๊ฒ์ ์ฌ์ ํ โโ์ฑ๋ฅ์ด ์ข์ต๋๋ค.
<input attrs={{placeholder: `heyo`}} style={{color: `inherit`}} class={{hello: true, world: false}} on={{click: this.handleClick}} props={{value: `blah`}} />
attr = (attr, val) => elem.setAttribute(attr, val);
prop = (prop, val) => elem[prop] = val;
on = (event, handler) => elem.addEventListener(event, handler)
style = (prop, val) => elem.style[prop] = val;
class = (name, isSet) => isSet ? elem.classList.add(name) : elem.classList.remove(val)
dataset = (key, val) => elem.dataset[key] = val;
JSX๊ฐ ์ ๊ตฌ๋ฌธ์ผ๋ก ๋ค์์คํ์ด์ค๋ฅผ ์ง์ํ์ผ๋ฉด ํฉ๋๋ค. ์ด๊ฒ์ props๊ฐ ๊ธฐ๋ณธ ๋ค์์คํ์ด์ค๊ฐ ๋๋ฉฐ ๊ฐ๋จํ ์์ฑํ ์ ์์์ ์๋ฏธํฉ๋๋ค.
<div tabIndex={-1} attr.title={"abcd"} on.click={handler} style.opacity={1} class.world={true} />`
์ฐธ๊ณ ๋ก @sebmarkbage ^
const whatever = 'Whatever';
const obj = { a: 1, b: 2 };
const reactComponent = (props) => (
<div>
...
<custom-element attr="{whatever}" someProp={obj} />
{ /* double quotes for attributes */ }
{ /* no quotes for properties */ }
</div>
);
์ด๊ฒ์ React JSX Pragma ํ์๋ฅผ ์์ ํ์ฌ ๋ฌ์ฑํ ์ ์์ต๋๋ค.
์ถ๊ฐ ์ต์
์ propeties
(๋๋ ๋ฐ์ ํฌ์ ๊ฒฝ์ฐ props
)์ ์์ฐ ์ ๋ฌ์ ๋ํ ์ง์ ๋ ๋จ์ด๋ก ์ ์งํ๋ ๊ฒ์
๋๋ค.
์ค๋ 17.0์ด ์ถ์๋์์ผ๋ฏ๋ก ์ด ๋ฌธ์ ๊ฐ ์ธ์ ํด๊ฒฐ๋๋์ง ์ํ๋ฅผ ๋ฐ์ํ๋๋ก ์ด ๋ฌธ์ ๋ฅผ ์ ๋ฐ์ดํธํ ์ ์์ต๋๊น?
์. ์ฐ๋ฆฌ๋ ์๋ React 17์ ๋ ๋ง์ ์ง์ ์ค๋จ์ด ์ ๊ฑฐ๋๊ณ ์๋ก์ด ๊ธฐ๋ฅ์ด ํฌํจ๋ ๋ฆด๋ฆฌ์ค๋ก ๊ณํํ์ต๋๋ค. ๊ทธ๋ฌ๋ ์ค๋๋ ์ฝ๋๋ฒ ์ด์ค๊ฐ ๋ชจ๋ ์ฝ๋๋ฅผ ์ ๋ฐ์ดํธํ๋ ๊ฒ์ ๊ทธ๋ค์ง ํ์ค์ ์ด์ง ์์ผ๋ฉฐ, ์ด๊ฒ์ด ์ฐ๋ฆฌ๊ฐ ํ๋์ ์ค์ํ ์ฃผ์ ๋ณ๊ฒฝ ์ฌํญ(์ด๋ฒคํธ๋ ๋ฌธ์๊ฐ ์๋ ๋ฃจํธ ์์์ ์ฒจ๋ถ๋จ)์๋ง ์ด์ ์ ๋ง์ถ React 17์ ์ถ์ํ๊ธฐ๋ก ๊ฒฐ์ ํ ์ด์ ์ ๋๋ค. ). ์ด๋ ์ค๋๋ ์ฑ์ด React 17์ ์์ํ ๋จ์ ์๊ณ ๊ทธ ์ค ์ผ๋ถ๋ง 18+๋ก ์ ๋ฐ์ดํธํ ์ ์๋๋ก ํ๊ธฐ ์ํ ๊ฒ์ ๋๋ค.
์ด ํน์ ๊ธฐ๋ฅ์ด 17์ ๋ค์ด๊ฐ ๊ฒ์ด๋ผ๊ณ ๋งํ๋ ๊ฒ์ด ์ค๋ง์ค๋ฝ๋ค๋ ๊ฒ์ ์๋๋ค. ํ์ง๋ง ์๋ 17์ ๋ํด ๊ณํํ๋ ๋ชจ๋ ๊ธฐ๋ฅ๋ 18๋ก ์ฎ๊ฒจ์ก๋ค๋ ๊ฒ์ ์๊ฒ ๋์ค ๊ฒ์ ๋๋ค. 17์ ํน๋ณํ ๋๋ค๋ ๋ฐ๋งค์ ๋๋ค. ์ด๋ฅผ ํตํด 18์์ ๋ ๊ณต๊ฒฉ์ ์ธ ์ฃผ์ ๋ณ๊ฒฝ ์ฌํญ์ ๋ง๋ค ์ ์์ต๋๋ค. ์์ผ๋ก ๋ช ํํ ๊ฒฝ๋ก๊ฐ ์๋ค๋ฉด ์ด ๋ณ๊ฒฝ ์ฌํญ์ ํฌํจํ ์ ์์ต๋๋ค.
์ด๋ฌํ ์ต์ ์ค ์ด๋ ๊ฒ์ด ๋ ๋ฐ๋์งํ์ง์ ๋ํ WC ์ปค๋ฎค๋ํฐ์ ์ต์ ํฉ์๊ฐ ๋ฌด์์ธ์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ๊ทธ๊ฒ์ ๊ทธ๋ค ๋ชจ๋๊ฐ (๊ทธ ์ผ์ ์ํด @robdodson์ ํฐ ์ํ) ์๊ฐ์ ์ ์ด์ด ๋งค์ฐ ๋์์ด๋ฉ๋๋ค. ์ด ์ค๋ ๋๊ฐ ์์ฑ๋ ์ดํ ์ด๋ฌํ ์ต์ ์ ๋ํ ์ฌ๋๋ค์ ์๊ฒฌ์ด ๋ฐ์ ํ๋์ง, ๋ฐฉํฅ์ ์ ํํ๋ ๋ฐ ๋์์ด ๋ ์ ์๋ ์๋ก์ด ์ ๋ณด๊ฐ ์๋์ง ๊ถ๊ธํฉ๋๋ค.
์ ๋ WC ์ปค๋ฎค๋ํฐ๊ฐ ์ ํธํ๋ ์ต์ ์ ๋ณ๊ฒฝํ๋ค๊ณ ์๊ฐํ์ง ์์ต๋๋ค. ์ฌ์ ํ ์ต์ 3์ ๋๋ค. @developit ์ Preact๊ฐ ์ฌ์ฉ์ ์ง์ ์์์ ์ด๋ป๊ฒ ํธํ๋๋์ง์ ๋ํด ๋ ๋ง์ด ๋งํ ์ ์์ต๋๋ค. ์ด๋ React์์๋ ํฅ๋ฏธ๋ก์ธ ์ ์์ต๋๋ค. ํ๋ ์์ํฌ๊ฐ ์ฌ์ฉ์ ์ ์ ์์์ (๋ณต์กํ) ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ๊ฒ๊ณผ ์ด๋ป๊ฒ ํธํ๋๋์ง์ ๋ํ ์ผ๋ฐ์ ์ธ ๊ฐ์๋ฅผ ๋ณด๋ ค๋ฉด https://custom-elements-everywhere.com/ ์ ๋ชจ๋ ์ธ๋ถ ์ ๋ณด๊ฐ ์์ต๋๋ค.
https://github.com/vuejs/vue/issues/7582 ์์ Vue๋ sigil์ ์ฌ์ฉํ๊ธฐ๋ก ์ ํํ๊ณ "."๋ฅผ ์ ํํ์ต๋๋ค. ์ ๋์ฌ๋ก (Glimmer์ "@"๊ฐ ์๋).
https://github.com/vuejs/vue/issues/7582#issuecomment -362943450์์ @trusktr ์ ๊ฐ์ฅ ์ ํํ SSR ๊ตฌํ์ด sigil'd ์์ฑ์ SSR'd HTML์ ์์ฑ์ผ๋ก ๋ ๋๋งํ์ง ์๋ ๊ฒ์ด๋ผ๊ณ ์ ์ํ์ต๋๋ค. ๋์ ์ํ ์ค์ JS๋ฅผ ํตํด ์์ฑ์ผ๋ก ์ค์ ํ์ญ์์ค.
์ด ํน์ ๊ธฐ๋ฅ๋ง์ ์ํด ์๋ก์ด JSX ๊ตฌ๋ฌธ์ ๋์ ํ ๊ฐ๋ฅ์ฑ์ ๊ฑฐ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
์ต์ (5)์ ๋ณด๋ค ์ผ๋ฐ์ ์ธ ๋ฒ์ ์ด ํ ์ด๋ธ์ ์์ ์ ์๋ ๊ฒฝ์ฐ ์ต์ (3)์ ์ํํ ๊ฐ์น๊ฐ ์๋์ง์ ๋ํ ์ง๋ฌธ๋ ์์ต๋๋ค. ์ฆ, ์ต์ (5)๋ ์ฌ์ฉ์ ์ง์ ๋ง์ดํธ/์ ๋ฐ์ดํธ/๋ง์ดํธ ํด์ /์ํ ๋์์ผ๋ก ์ฌ์ฉ์ ์ง์ ์ ์์ค React ๋ ธ๋๋ฅผ ์ ์ธํ๋ ์ ์์ค ๋ฉ์ปค๋์ฆ์ด ๋ ์ ์์ต๋๋ค. ์ฌ์ฉ์ ์ ์ ์์ ์์ฒด์๋ง ๊ตญํ๋์ง๋ ์์ต๋๋ค(์ฌ์ฉ ์ฌ๋ก ์ค ํ๋์ผ์ง๋ผ๋).
์ด ํน์ ๊ธฐ๋ฅ์ ๋ํด ์์ ํ ์๋ก์ด JSX ๊ตฌ๋ฌธ์ ๋์ ํ๋ ๋์ ๋ณด๋ค ์ผ๋ฐ์ ์ธ JSX๋ฅผ ๋์ ํ๊ณ ์ด๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์ ์ ์ ์์ฑ์ ์ ์ํ๋ ๊ฒ์ ์ด๋ป์ต๋๊น?
๋๋ ์ค๋์ ์ JSX์ ECMAScript์ ๊ณ์ฐ๋ ์์ฑ ๊ตฌ๋ฌธ์ ์ถ๊ฐํ๋ ๊ฒ์ ์ ์ํ๊ณ (facebook/jsx#108) ์ผ๋ฐ์ ์ผ๋ก ๊ตฌ๋ฌธ์ ์ ์ฉํ ์ถ๊ฐ๊ฐ ๋ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
๊ณ์ฐ๋ ์์ฑ ๊ตฌ๋ฌธ์ ์ฌ์ฉํ ์ ์๋ ๊ฒฝ์ฐ ๊ณ์ฐ๋ ์์ฑ ๊ตฌ๋ฌธ๊ณผ ๊ธฐํธ ๋๋ ์ ๋์ด๊ฐ ๋ถ์ ๋ฌธ์์ด์ ์ฌ์ฉํ์ฌ ์์ฑ์ ์ ์ํ ์ ์๋ ๊ฐ๋ฅ์ฑ์ด ์ด๋ ค ์์ต๋๋ค.
์๋ฅผ ๋ค์ด:
import {property} from 'react';
// ...
<custom-img [property('src')]="corgi.jpg" [property('hiResSrc')]="[email protected]" width="100%">
@dantman ์ด ์ ์์ ์๋ฒ ๋ ๋๋ง ๋ฐ ์ํ๋ฅผ ์ด๋ป๊ฒ ์ฒ๋ฆฌํฉ๋๊น?
WC ์ปค๋ฎค๋ํฐ์ ๋๊ตฌ๋ ์ต์ 5๋ฅผ ์ํ์ง ์๋๋ค๊ณ ์๊ฐํฉ๋๋ค.
์ฌ์ฉ์ ์ ์ ์์์ ๋ํ ์ฌ์ฉ์ ์ ์ React ๋ํผ ์์ฑ์ ํจ์นํ๋ ํ์ฌ ๊ดํ๊ณผ ์ค์ ๋ก ๋ค๋ฅด์ง ์์ต๋๋ค. ์ด ์ ๊ทผ ๋ฐฉ์์ ํฐ ๋จ์ ์ ๊ตฌ์ฑ ์์ ์์ฑ์์๊ฒ ํน๋ณํ ๊ฒฝ์ฐ์ React ๋๋ ๊ตฌ์ฑ ์์ ์๋น์์๊ฒ ํน๋ณํ ๊ฒฝ์ฐ์ ์ฌ์ฉ์ ์ง์ ์์์ ๋ํ ๋ถ๋ด์ ์ฃผ๋ฉฐ ๋ ๋ค ํ์ํ์ง ์์์ผ ํ๋ค๋ ๊ฒ์ ๋๋ค.
์๋ฒ ๋ ๋๋ง ๋ฐ ์ํ์ ๋ํด ์ด๋ป๊ฒ ์๊ฐํ์ญ๋๊น? ๋ช ์์ ๊ตฌ์ฑ์ด ์๋ ๊ฒฝ์ฐ ์ด๋ค ๊ฒฝํ์ ๋ฐฉ๋ฒ์ด ๋ฐ๋์งํฉ๋๊น? WC ์ปค๋ฎค๋ํฐ์์ ์ผ๋ฐ์ ์ผ๋ก ์ํ๋๋ ๋ฐฉ์์ด ํตํฉ๋์์ต๋๊น? ์ด RFC๋ฅผ ๋ค์ ์ฝ์๋๋ฐ ์ด ์ฃผ์ ์ ๋ํ ์ธ๋ถ ์ ๋ณด๊ฐ ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ๊ทธ๋ฌ๋ ํนํ React๊ฐ ์๋ฒ ๋ ๋๋ง์ ๋ ์ค์ ์ ๋๋ ๋ฐฉํฅ์ผ๋ก ์ด๋ํจ์ ๋ฐ๋ผ ๋งค์ฐ ์ค์ํฉ๋๋ค.
@gaearon ํ์ํ ๊ฒ์ด ๋ฌด์์ธ์ง ์๊ธฐ์ ์ถฉ๋ถํ ์ํ ๋ฐ ์ฌ์ฉ์ ์ ์ ์์ฑ์ ์์ง ๋ชปํฉ๋๋ค. ์ด๊ฒ์ ์ฃผ๋ก ๊ตฌ๋ฌธ ์ ์์ ๋๋ค.
์ผ๋ฐ์ ์ผ๋ก property(propertyName)
๋ ๊ตฌํ ๋ฐฉ๋ฒ์ ๋ฐ๋ผ ์ ๋์ด๊ฐ ๋ถ์ ๋ฌธ์์ด(์: '__REACT_INTERNAL_PROP__$' + propertyName
)์ ์ถ๋ ฅํ๊ฑฐ๋ Symbol์ ์์ฑํ๊ณ "symbol => propertyName" ์ฐ๊ด์ ์ ์ฅํ ์ ์๋ค๋ ๊ฒ์
๋๋ค. ์ง๋.
๋์ค์ ํด๋น ๋งต์ ํด๋ผ์ด์ธํธ์ ํต์ ํด์ผ ํ๋ ๊ฒฝ์ฐ ๋ฌธ์ ๊ฐ ๋ ์ ์์ต๋๋ค.
๊ทธ๋ฌ๋ ๋ด ๋๋ต์ ์ธ ์ดํด์ ๋ฐ๋ฅด๋ฉด ์์ฑ์ ์๋ฒ์์ ์ฒ๋ฆฌํ ์ ์๋ ๊ฒ์ด ์๋๋ฉฐ ์ํ์๋ ํด๋ผ์ด์ธํธ ์ฝ๋๊ฐ ํฌํจ๋๋ฏ๋ก ์ด์ ๋ํ ๊ณํ์ด ๋ฌด์์ธ์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ๋ด ์ ์์ ๊ดํด์๋ ๊ทธ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์ด๋ค ๊ณํ์ ๊ฐ์ง๊ณ ์๋ ์ ์ฉํ ์ ์์ ๊ฒ์
๋๋ค. ์๋ฒ์ ์์ฑ์ ๋ฐ์ํ๋๋ก ํ๋ ค๋ ๊ฒ์ด ์๋ค๋ฉด property
์ํด ์์ฑ๋ ์์ฑ ์ค ํ๋๋ฅผ ๋ณผ ๋๋ง ๊ทธ๋ ๊ฒ ํ ์ ์์ต๋๋ค.
์น ๊ตฌ์ฑ ์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์ฑ์๋ก์ ์ต์ 5๋ ํธ๋ฆฌํ ์ ํ์ด ์๋๋๋ค. ๊ฐ ํ๋ ์์ํฌ ๋ฐ ๊ตฌ์ฑ ์์์ ๋ํ ์คํค๋ง๋ฅผ ๋ช ์์ ์ผ๋ก ์ ์ํ์ง ์๊ณ ๋ ์ฌ์ฉ์ ์ง์ ์์๋ฅผ ๋ง๋ค๊ณ ์ถ์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ง์ ์ฌ์ฉ์ ์ ์ ์์ ์์ฑ์๋ ์ด๊ฒ์ ํ์ง ์์ React ๊ฐ๋ฐ์์๊ฒ ๋ถ๋ด์ ์ค๋๋ค.
์ต์ 5๋ก ์น์๋ ์์ต๋๋ค. ๐
@claviska ์๋ฒ ๋ ๋๋ง ๋ฐ ์ํ ์์ ์ด ๋ณด๋ค ์์์ ์ธ ์ ๊ทผ ๋ฐฉ์์ผ๋ก ์๋ํ๋ ๋ฐฉ์์ ๋ํ ์๊ฒฌ์ด ์์ต๋๊น?
@gaearon SSR์ ์ฌ์ฉ์ ์ ์ ์์๊ฐ SSR์ ์ง์ํ๋ ๊ฒฝ์ฐ์ ์ง์ํ์ง ์๋ ๊ฒฝ์ฐ์ ๋ ๊ฐ์ง ์ํฉ์ผ๋ก ์ธ๋ถํ๋ฉ๋๋ค.
SSR์ ์ง์ํ์ง ์๋ ์์์ ๊ฒฝ์ฐ ์๋ฒ์ ์์ฑ ์ค์ ์ ์ค์ํ์ง ์์ต๋๋ค. id
๋ฐ className
์ ๊ฐ์ ๋ด์ฅ ๋ฐ์ ์์ฑ์ ์ ์ธํ๊ณ ๋ ์ญ์ ํ ์ ์์ผ๋ฉฐ ํด๋ผ์ด์ธํธ์์๋ง ์ธ ์ ์์ต๋๋ค.
SSR ์์ฑ์ ์ง์ํ๋ ์์์ ๊ฒฝ์ฐ ์ค์ํ์ง๋ง DOM์์ ๋ฐ์ํ๋ ๊ฒฐ๊ณผ๋ฅผ ํธ๋ฆฌ๊ฑฐํ ์ ์์ด์ผ ํฉ๋๋ค. ์ด๋ฅผ ์ํด์๋ ์์ ์ธ์คํด์ค ๋๋ ์ผ์ข ์ SSR ํ๋ก์/์คํ ๋์ธ ๋ฐ SSR์ DOM ์ํ๋ฅผ ์ ๋ฌํ๊ธฐ ์ํ ์ผ๋ถ ํ๋กํ ์ฝ์ด ํ์ํฉ๋๋ค. ์์ง ์ด ํ๋ก์ธ์ค์ ๋ํ ๊ณตํต ์๋ฒ ์ธก ์ธํฐํ์ด์ค๊ฐ ์์ผ๋ฏ๋ก ์ง๊ธ์ ์ฌ๊ธฐ์ ์ํํ ์์ ์ด ์์ต๋๋ค. ์น ๊ตฌ์ฑ ์์ ์์ฑ์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ ์ง ๊ด๋ฆฌ์๋ React๊ฐ ๊ฑฐ๊ธฐ์ ๋ค๋ฆฌ๋ฅผ ๊ตฌ์ถํ๊ธฐ ์ ์ ๋ช ๊ฐ์ง ์ฌํญ์ ํ์ ํด์ผ ํฉ๋๋ค.
SSR ๋ด ํ์ ์ํ์์ ์ฐ๋ฆฌ๋ ํจ์น์ ์ํด ๋ฐ์์ฉ๊ณผ ํตํฉ ํ createElement
ํ๊ณ ์ฌ์ฉํ์ฌ dangerouslySetInnerHTML
. ๋๋ ๊ทธ๊ฒ์ด ์ฐ๋ฆฌ๊ฐ ์ ์ ๋์ ์์ ํตํฉ/์คํ์ ์์ค์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ์กฐ๋ง๊ฐ SSR ์์คํ
๋ด์์ ์ํธ ์ด์ฉ์ฑ์ ์ํ ์ผ๋ถ ์ฌ์ฉ์ ์์ญ ํ๋กํ ์ฝ์ ์๋ ดํ ์ ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค. ๊ทธ๋๊น์ง๋ _deep_ SSR ์์ด ์ฌ์ฉ์ ์ ์ ์์ ์์ฑ ๋ฐ ์ด๋ฒคํธ ์ง์์ ๊ฐ๋ ๊ฒ์ด ์๋ฒฝํ๊ฒ ์์ ํ๊ณ ์ ์คํฉ๋๋ค. ์์์ ํ๊ทธ๋ ์ค๋๋ ๊ณผ ๊ฐ์ด ์ฌ์ ํ React ๊ตฌ์ฑ ์์์ ์์์ผ๋ก SSR'๋ฉ๋๋ค.
id ๋ฐ className๊ณผ ๊ฐ์ ๋ด์ฅ ๋ฐ์ ์์ฑ์ ์ ์ธํ๊ณ ๋ ์ญ์ ํ ์ ์์ผ๋ฉฐ ํด๋ผ์ด์ธํธ์์๋ง ์ธ ์ ์์ต๋๋ค.
์ด๊ฒ์ด ์ด๋ป๊ฒ ์๋ํ๋์ง ์ดํดํ๋๋ก ๋์ ์ฃผ์๊ฒ ์ต๋๊น? ์๋ฅผ ๋ค์ด <github-icon iconname="smiley" />
๊ฐ ์๋ค๊ณ ๊ฐ์ ํฉ๋๋ค. SSR์ด HTML ์๋ต์ <github-icon />
๋ง ํฌํจํ๋ฉด React๊ฐ ์ํ ์ค์ domNode.iconname = ...
์ค์ ํ๋ค๋ ๋ป์ธ๊ฐ์? ์ด ๊ฒฝ์ฐ React ํ์ด๋๋ ์ด์
์ด ๋ฐ์ํ๊ธฐ ์ ์ ์ฌ์ฉ์ ์ ์ ์์ ๊ตฌํ์ด ๋ก๋๋๋ฉด ์ด๋ป๊ฒ ๋๋์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. iconname
๊ฐ HTML์ ์๋ ๊ฒฝ์ฐ github-icon
๊ตฌํ์์ ๋ ๋๋งํ ์์ด์ฝ์ ์ด๋ป๊ฒ ์ ์ ์์ต๋๊น?
์์ง ์ด ํ๋ก์ธ์ค์ ๋ํ ๊ณตํต ์๋ฒ ์ธก ์ธํฐํ์ด์ค๊ฐ ์์ผ๋ฏ๋ก ์ง๊ธ์ ์ฌ๊ธฐ์ ์ํํ ์์ ์ด ์์ต๋๋ค. ์น ๊ตฌ์ฑ ์์ ์์ฑ์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ ์ง ๊ด๋ฆฌ์๋ React๊ฐ ๊ฑฐ๊ธฐ์ ๋ค๋ฆฌ๋ฅผ ๊ตฌ์ถํ๊ธฐ ์ ์ ๋ช ๊ฐ์ง ์ฌํญ์ ํ์ ํด์ผ ํฉ๋๋ค.
์ฌ๊ธฐ์ ์ปค๋ฎค๋ํฐ๊ฐ ํฉ์๋ฅผ ์ด๋ฃจ๊ธฐ ์ํด ํน๋ณํ ํด์ผ ํ ์ผ์ด ์๋์ง ๊ถ๊ธํฉ๋๋ค. ๋ฆฌ์กํธ๊ฐ ๊ทธ๊ฒ์ ๋ง๊ณ ์์ต๋๊น? ์ด ๋ฌธ์ ๊ฐ 2017๋ ๋ถํฐ ๊ณต๊ฐ๋์ด ๋ต๋ตํจ์ ๋ง์ด ์ดํดํฉ๋๋ค. ํํธ, 3๋ ์ด ์ง๋ฌ๊ณ ์์ง ์ด๋ฌํ ํฉ์๊ฐ ์ด๋ฃจ์ด์ง์ง ์์๋ค๊ณ ๋ง์ํ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ๋ฐ์ํ๊ธฐ ์ํ ์ ์ ์กฐ๊ฑด์ ๋ฌด์์ ๋๊น? ๋จ์ง ๋ ๋ง์ ์คํ์ ๋ฌธ์ ์ ๋๊น?
@gaearon ์ฌ์ฉ์ ์ ์ ์์ ๊ตฌํ์ด React ์ํ ์ ์ ๋ก๋๋๋ฉด iconname
์์ฑ์ ๊ธฐ๋ณธ ๊ฐ์ด ๋ฌด์์ด๋ ํ ๋นํฉ๋๋ค. if _iconname_ does not exist in the HTML
์(๋) ๋ฌด์จ ๋ป์ธ๊ฐ์? HTMLElement ์ ํ์ ์ ์๋ ์์ฑ์ด ์์ผ๋ฉด ๋ฌด์ํฉ๋๋ค. ์ฌ์ฉ์ ์ ์ ์์ ์ ์๊ฐ ๋ก๋๋๋ฉด HTMLElement ์ ํ์ ํ์ฅํ๊ณ iconname
์ ์ํ๊ณ ์ ๋ฌ๋๋ ์ ๊ฐ์ ๋ฐ์ํ ์ ์์ต๋๋ค.
๋๋ ์ด๊ฒ์ ์ฌ์ฉ์์ ๊ด์ ์์ ์ดํดํ๋ ค๊ณ ๋ ธ๋ ฅํ๊ณ ์์ต๋๋ค. ์๋ฒ์์ ํ์ด์ง๋ฅผ ๋ ๋๋งํ๊ณ ์์ต๋๋ค. ํ ์คํธ ์ค๊ฐ์ ์์ด์ฝ์ด ์์ต๋๋ค. ํด๋น ์์ด์ฝ์ ์ฌ์ฉ์ ์ ์ ์์๋ก ๊ตฌํ๋ฉ๋๋ค. ์ต์ข ์ฌ์ฉ์๊ฐ ๊ฒฝํํด์ผ ํ๋ ์์๋ ๋ฌด์์ ๋๊น?
์ง๊ธ๊น์ง ๋ด ์ดํด๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
๊ทธ๋ค์ ์ด๊ธฐ ๋ ๋๋ง ๊ฒฐ๊ณผ๋ฅผ ๋ด
๋๋ค. ์ฌ๊ธฐ์๋ ๋ชจ๋ ์ผ๋ฐ ๋งํฌ์
์ด ํฌํจ๋์ง๋ง <github-icon>
์ฌ์ฉ์ ์ ์ ์์๋ ์ ํ ํ์๋์ง ์์ต๋๋ค. ์๋ง๋ ๋น div์ ๊ฐ์ ๊ตฌ๋ฉ์ด ๋ ๊ฒ์
๋๋ค. ์ ๊ฐ ํ๋ ธ๋ค๋ฉด ์ง์ ํด์ฃผ์ธ์(?). ๊ตฌํ์ด ์์ง ๋ก๋๋์ง ์์์ต๋๋ค.
<github-icon>
์ฌ์ฉ์ ์ ์ ์์ ๊ตฌํ์ด ๋ก๋๋๊ณ ๋ฑ๋ก๋ฉ๋๋ค. ๋ด๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์ดํดํ๋ฉด ์ด๊ฒ์ด "์
๊ทธ๋ ์ด๋"๋ผ๋ ํ๋ก์ธ์ค์
๋๋ค. ๊ทธ๋ฌ๋ JS๊ฐ ์ค๋น๋์ด ์์ด๋ HTML์ iconname
๋ฅผ ํฌํจํ์ง ์์๊ธฐ ๋๋ฌธ์ ์ฌ์ ํ ์๋ฌด๊ฒ๋ ํ์๋์ง ์์ต๋๋ค. ๋ฐ๋ผ์ ๋ ๋๋งํ ์์ด์ฝ์ ๋ํ ์ ๋ณด๊ฐ ์์ต๋๋ค. ์ด์ ์ "๋น ๋ด์ฅ ์์ฑ์ HTML์์ ์ญ์ ํ ์ ์๋ค"๊ณ ๋งํ๊ธฐ ๋๋ฌธ์
๋๋ค. ๋ฐ๋ผ์ ์ฌ์ฉ์๋ ์ฌ์ ํ "๊ตฌ๋ฉ"์ ๋ด
๋๋ค.
React์ ์ ํ๋ฆฌ์ผ์ด์
์ฝ๋๊ฐ ๋ก๋๋ฉ๋๋ค. ์๋ถ์ด ๋ฐ์ํฉ๋๋ค. ์ํํ๋ ๋์ React๋ ํด๋ฆฌ์คํฑ์ ๋ฐ๋ผ .iconname =
์์ฑ์ ์ค์ ํฉ๋๋ค. ์ฌ์ฉ์๋ ์ด์ ์์ด์ฝ์ ๋ณผ ์ ์์ต๋๋ค.
์ฌ์ฉ์ ์ ์ ์์ JS ๊ตฌํ์ด ๋จผ์ ๋ก๋๋๋ ๊ฒฝ์ฐ์ ๋ํ ์ฌ๋ฐ๋ฅธ ๋ถ์์ ๋๊น? ์ด๊ฒ์ด WC ์ปค๋ฎค๋ํฐ์ ๋ฐ๋์งํ ํ๋์ ๋๊น?
@gaearon ๋ต ์ด ์ํฉ์์ ์์๋๋ ์ผ์ ๋๋ค.
ํํธ 3๋ ์ด ์ง๋ฌ๋๋ฐ ์์ง ์ด๋ฐ ๊ณต๊ฐ๋๊ฐ ํ์ฑ๋์ง ์์๋ค๋ ๋ง์์ด์ ๊ฒ ๊ฐ์๋ฐ์.
ํฉ์๊ฐ ์ด๋ฃจ์ด์ง์ง ์์๋ค๋ ๋ง์ ์๋๋๋ค. ์ง๊ธ ๋น์ฅ์ _deep_ SSR์ ๋ํด ๊ฑฑ์ ํ ํ์๊ฐ ์์ผ๋ฉฐ ํ์ฌ ๋ฌ์ฑํ ์ ์๊ณ ๋งค์ฐ ์ ์ฉํ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ํด๋ผ์ด์ธํธ ์ธก ์ํธ ์ด์ฉ์ฑ์ ๋ง๋ ๋ง์ฐํ ์ฐ๋ ค๋ก ์ธํด ๊ฑฑ์ ํ ํ์๊ฐ ์์ต๋๋ค.
๋๋ ์ด ๊ตฌ๋ณ(๊น์ ๊ฒ๊ณผ ์์ ๊ฒ)์ ๋ณธ ์ ์ด ์์ผ๋ฏ๋ก ๋ด๊ฐ ๋น์ ์ ์ดํดํ๋์ง ํ์ธํ๊ธฐ ์ํด ๋ค์ ๋งํ๊ฒ ์ต๋๋ค.
"๊น์" SSR์ React ๊ตฌ์ฑ ์์์์ ์๋ํ๋ ๋ฐฉ์๊ณผ ์ ์ฌํ SSR์ ์๋ฏธํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ฆ, CE๋ฅผ ๋ ๋๋งํ๋ฉด ํด๋น CE์ ๋ ผ๋ฆฌ๊ฐ ๋ก๋๋๊ธฐ ์ ์ ํ์๋ ์ ์๋ ์ถ๋ ฅ์ด ์์ฑ๋ฉ๋๋ค. ์ด๊ฒ์ ์ฐ๋ฆฌ๊ฐ ์ง๊ธ ์ง์์ ๋ํด ๊ฑฑ์ ํ ํ์๊ฐ ์๋ค๊ณ ๋งํ๋ ๊ฒ์ ๋๋ค. ๊ทธ๊ฒ์ ๋์๊ฒ ์๋ฏธ๊ฐ ์์ต๋๋ค.
"๊น์ง ์์" SSR์ CE ํ๊ทธ ์์ฒด๋ฅผ HTML์ ๋ฃ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ๊ทธ๊ฒ์ด ๋ฌด์์ ํด๊ฒฐํ๋์ง ๊ฑฑ์ ํ์ง ์๊ณ . ์ ์๊ฒ๋ ์๋ฏธ๊ฐ ์์ต๋๋ค. ๋ด ์ง๋ฌธ์ _์ด_ ํ๋ฆ์ ๊ดํ ๊ฒ์ด์ง๋ง "๊น์" SSR์ ๋ํ ๊ฒ์ด ์๋๋๋ค.
ํนํ https://github.com/facebook/react/issues/11347#issuecomment -713230572 ๋ CE ๋ก์ง์ ๋ค์ด๋ก๋ํ _์ด๋ฏธ ๊ฐ์ง๊ณ ์๋ ๊ฒฝ์ฐ์๋ ์ํ๋ ๋๊น์ง ์ฌ์ฉ์์๊ฒ ์๋ฌด ๊ฒ๋ ํ์ํ ์ ์๋ ์ํฉ์ ์ค๋ช ํฉ๋๋ค. ์ ์ฒด ์ ํ๋ฆฌ์ผ์ด์ ์ JS ํด๋ผ์ด์ธํธ ์ฝ๋๊ฐ ๋ก๋๋๊ณ ์ํ๋ ๋๊น์ง ์์ฑ์ ์ ์ ์์ต๋๋ค. ์ด๊ฒ์ด ์ค์ ๋ก ์ํ๋ ๋์์ธ์ง ๋ฌป๊ณ ์์ต๋๋ค.
์ ์ ์ฅ์์ ๋ง์ฐํ ๊ณ ๋ฏผ์ ์๋ ๊ฒ ๊ฐ์์. ๊ธฐ๋ฅ ์์ฒญ์ ์คํดํ๊ณ ์ถ์ง ์์ต๋๋ค. ๋ฐ๋ผ์ ์ ํํ ์๋ฏธ๋ฅผ ์ง์ ํ๋ฉด ์ด ์ ์์ ํ๊ฐํ๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด ํ ๊ฐ์ง ์ค์ง์ ์ธ ์ฐ๋ ค๋ ๋ด์ฅ ๊ตฌ์ฑ ์์ ์ค ์ด๋ ๊ฒ๋ ํ์ํ์ง ์๊ธฐ ๋๋ฌธ์ ์ค๋๋ ์ํ ์ค์ ์์ฐ์์ React๊ฐ ์ค์ ๋ก ์์ฑ/์์ฑ์ ๊ตฌ๋ณํ์ง ์๋๋ค๋ ๊ฒ์ ๋๋ค. ๊ทธ๋ฌ๋ ์ ๋ง๋ก ํ์ํ ๊ฒฝ์ฐ ์ด ํน๋ณํ ๊ฒฝ์ฐ์ ์ถ๊ฐํ ์ ์๋ ๊ฒ์ ๋๋ค.
@gaearon
https://github.com/facebook/react/issues/11347#issuecomment -713230572๊ฐ ์ด ๊ธฐ๋ฅ์ด ํ์ํ ๊ฐ์ฅ ์ข์ ์๊ฐ ์๋ ์๋ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
์ ์ด๋ ๋ด ๊ฒฝํ์ ๋ฐ๋ฅด๋ฉด ์์ฑ๋ณด๋ค๋ ์์ฑ์ ์ค์ ํ๋ ๊ฒ์ด ๋ฌธ์์ด, ์ซ์ ๋๋ ๋ถ์ธ๊ณผ ๊ฐ์ ๋จ์ํ ์ ํ์ ํ์ํ ์ ๋ถ๋ ์๋๋๋ค.
์ค๋ช
ํ๋ ๊ฒฝ์ฐ๋ iconname
๋ฅผ ์์ฑ์ผ๋ก ์ง์ ์ฌ์ฉํ์ฌ ์ฝ๊ฒ ๋ฌ์ฑํ ์ ์์ผ๋ฉฐ ์ํ๋ฅผ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ์ฌ์ ํ ๊ฑฐ์ ๋์ผํ ์ต์ข
๋ ๋๋ง ๊ฒฐ๊ณผ์
๋๋ค.
NS
์ฌ์ฉ์ ์ ์ ์์ ๊ตฌํ์ด ๋ก๋๋๊ณ ๋ฑ๋ก๋ฉ๋๋ค. ๋ด๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์ดํดํ๋ฉด ์ด๊ฒ์ด "์ ๊ทธ๋ ์ด๋"๋ผ๋ ํ๋ก์ธ์ค์ ๋๋ค. ๊ทธ๋ฌ๋ JS๊ฐ ์ค๋น๋์ด ์์์๋ ๋ถ๊ตฌํ๊ณ HTML์ iconname์ ํฌํจํ์ง ์์๊ธฐ ๋๋ฌธ์ ์ฌ์ ํ ์๋ฌด๊ฒ๋ ํ์๋์ง ์์ต๋๋ค. ๋ฐ๋ผ์ ๋ ๋๋งํ ์์ด์ฝ์ ๋ํ ์ ๋ณด๊ฐ ์์ต๋๋ค. ์ด์ ์ "๋น ๋ด์ฅ ์์ฑ์ HTML์์ ์ญ์ ํ ์ ์๋ค"๊ณ ๋งํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ๋ฐ๋ผ์ ์ฌ์ฉ์๋ ์ฌ์ ํ "๊ตฌ๋ฉ"์ ๋ด ๋๋ค.
์ฌ๊ธฐ์ ์ธ๊ธํ ๋ด์ฉ์ ๊ตฌ์ฑ ์์๊ฐ ๊ตฌํ๋๋ ๋ฐฉ์์ ๋ฐ๋ผ "๊ตฌ๋ฉ"์ด ํ์๋๋ ์ด ๋ฌธ์ ๋ฅผ ํผํ ์ ์์ต๋๋ค.
์ด ๊ฒฝ์ฐ ๊ธฐ๋ณธ ์ค์ ์ ๋จ์ํ๊ฒ ์ค์ ํ๊ฑฐ๋ ์ฌ๋กฏ์ ํตํด ์ฝํ ์ธ ์ ์ผ๋ถ ๋๋ ๋๋ถ๋ถ์ ์๋ฝํ์ฌ ๊ตฌ์ฑ ์์๊ฐ ์ ๊ทธ๋ ์ด๋๋๊ธฐ ์ ์๋ ์ฝํ ์ธ ๊ฐ ํ์๋๋๋ก ํ ์ ์์ต๋๋ค.
์ด ๊ธฐ๋ฅ์ ๊ฐ์ฒด, ๋ฐฐ์ด, ํจ์ ๋ฑ์ ์์ฑ์ด ์๋ ๋ ๋ณต์กํ ๊ตฌ์ฑ ์์๋ฅผ ์ฌ์ฉํ๋ ๋ฐ ๊ฐ์ฅ ์ ์ฉํ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
lit-virtualizer
๊ฐ์ ์คํฌ๋กค๋ฌ ๊ตฌ์ฑ ์์๋ฅผ ์๋ก ๋ค์ด ๋ณด๊ฒ ์ต๋๋ค.
์ด๊ฒ์ด ์ ๋๋ก ์๋ํ๋ ค๋ฉด items
๋ฐฐ์ด๊ณผ renderItem
ํจ์๊ฐ ํ์ํ๋ฉฐ ์ ํ์ ์ผ๋ก scrollTarget
์์๋ฅผ ์ค์ ํ ์๋ ์์ต๋๋ค. ์ด ๋ชจ๋ ๊ฒ์ refs๋ฅผ ์ฌ์ฉํ์ฌ React์์๋ง ์ค์ ํ ์ ์์ต๋๋ค. ์ง๊ธ ๋ฐ๋ก.
์ด์ ๊ฐ์ ๊ฒฝ์ฐ์๋ ์ผ์ข ์ ํ์ด์ง ๋งค๊น ๋๋ ์ง์ฐ ๋ก๋ฉ์ผ๋ก ์ฝํ ์ธ ๋ฅผ ๋ก๋ํ ์ ์์ผ๋ฏ๋ก SSR ์ผ์ด์ค์ ์ํ ๋จ๊ณ๊น์ง ์ฝํ ์ธ ๊ฐ ์๋ ๊ฒ์ด ๋ฌธ์ ๊ฐ ๋์ง ์์ ์ ์์ต๋๋ค.
@gaearon ์ฌ์ฉ์ ์ ์ ์์๋ DOM ํ์ค์ด๋ฏ๋ก ์ฌ์ฉ์ ์ ์ ์์๋ฅผ ์ฌ์ฉํ๋ ๋ชจ๋ ์ฌ๋์ด ๋์ผํ ๋ฐฉ์์ผ๋ก ์ฌ์ฉํ๋ค๋ ์๋ฏธ์์ "WC ์ปค๋ฎค๋ํฐ" ์์ฒด๊ฐ ์์ต๋๋ค. ์ฌ์ฉ์ ์ ์ ์์๋ ๋ณธ์ง์ ์ผ๋ก ์ฌ๋๋ค์ด ๊ตฌ์ถํ๋ ๋ฎ์ ์์ค์ ๊ธฐ๋ณธ ์์์ด๊ธฐ ๋๋ฌธ์ ๊ฐ ๊ฐ๋ฐ์๋ฅผ ์ํด ๊ณ ์ ํ ๋ฐฉ์์ผ๋ก ํตํฉ๋ฉ๋๋ค.
์ฆ, ์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ ์๋ง์ ํจํด์ด ๋ฑ์ฅํ์ผ๋ฉฐ ๋ชจ๋ ์ธ๊ธฐ ์๋ ํ๋ ์์ํฌ(React ์ ์ธ)๋ ์ด DOM ํ์ค์ ๋ํ ํธํ์ฑ์ ์ ๊ณตํ๊ธฐ ์ํด ๋ช ๊ฐ์ง ์๋ฃจ์ ์ ๊ตฌํํฉ๋๋ค. https://custom-elements-everywhere.com/ ์์ ๋ณผ ์ ์๋ฏ์ด ๋ชจ๋ ํ๋ ์์ํฌ/๋ผ์ด๋ธ๋ฌ๋ฆฌ(React ์ ์ธ)๋ ๋ค๋ฅธ ์ต์ ์ ์ ํํ์ต๋๋ค. ์ด๋ฒ ํธ์์ ์ ํํ ์ต์ ์ ์ต์ 1, 2, 3์ผ๋ก ๋์ด๋ฉ๋๋ค. ํ์ฌ ์ต์ 4 ๋๋ 5๋ฅผ ๊ตฌํํ๋ ํ๋ ์์ํฌ/๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์์ผ๋ฉฐ ์ด๋ฌํ ์ต์ ์ ๊ตฌํํ๋ ๊ฒ์ด ๋ฐ๋์งํ์ง ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
๋ฐ๋ผ์ ๋๋ React๊ฐ ๋ค๋ฅธ ํ๋ ์์ํฌ/๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ฐ๋ฅด๊ณ ์๋์ด ์ ์ฆ๋ ์ต์ (์: ์ต์ 1-3 ์ค์์ ์ ํ)์ ์ ํํ ๊ฒ์ ์ ์ํฉ๋๋ค. ๋๋ React๊ฐ ์ฌ๊ธฐ์์ ์ต์ 4 ๋๋ 5๋ฅผ ์ ํํ์ฌ ๋ฐํด๋ฅผ ์ฌ๋ฐ๋ช ํ ํ์๊ฐ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ๋ฐ์ดํฐ๊ฐ ์๋ React ๋๋ DOM ํ์ค์ ๊ธฐ๋ฐ์ผ๋ก ๊ตฌ์ถ๋ ์๋ฃจ์ ์ ๋ํด ์ฅ๊ธฐ์ ์ผ๋ก ์ ์ง ๊ด๋ฆฌ ๊ฐ๋ฅํ ์๋ฃจ์ ์ ๋๋ค.
๋ฐ๋ผ์ ์ ๊ฑฐ ํ๋ก์ธ์ค(์๋์ ๋งํฌ๋ ์ฃผ์ ํฌํจ)์ ์ํด ์ต์ 3์ JSX์์ ์ํ๋์ง ์์ ๊ฒ์ด๊ณ ์ต์ 4์ 5๋ ์ด ์ค๋ ๋์์ WC ์ฌ๋๋ค์ ์ํด ๋ฐ๋์งํ์ง ์์ ๊ฒ์ผ๋ก ํ์๋์์ผ๋ฏ๋ก ์ฐ๋ฆฌ๋ 1 ๋๋ 2์ ๊ฐํ ์์ต๋๋ค. .
๊ทธ๋ฆฌ๊ณ 1๋ฒ์ ๋ฒํธ ์ ์๋ ๋จ์ ์ด ์๋ ๊ฒ ๊ฐ์์ ์ต์ 2๋ฒ ์ด ํ๋์ธ ๊ฒ ๊ฐ์ฃ ? Preact๊ฐ ์ํํ๋ ๋ฐฉ์์ผ๋ก ๊ฐ์ญ์์ค.
ํ์ฌ ์ต์ 4 ๋๋ 5๋ฅผ ๊ตฌํํ๋ ํ๋ ์์ํฌ/๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์์ผ๋ฉฐ ์ด๋ฅผ ๊ตฌํํ๋ ๊ฒ์ด ๋ฐ๋์งํ์ง ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
( https://github.com/facebook/react/issues/11347#issuecomment-713474037์ @TimvdLippe )
์ด ํน์ ๊ธฐ๋ฅ๋ง์ ์ํด ์๋ก์ด JSX ๊ตฌ๋ฌธ์ ๋์ ํ ๊ฐ๋ฅ์ฑ์ ๊ฑฐ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
( https://github.com/facebook/react/issues/11347#issuecomment-713210204์ @gaearon )
๊ทธ๊ฒ์ ๋์๊ฒ ์ดํด๊ฐ ๋ ๊ฒ์ ๋๋ค. ์์ฝ ๊ฐ์ฌํฉ๋๋ค! ๐
์ ์ด๋ ๋ด ๊ฒฝํ์ ๋ฐ๋ฅด๋ฉด ์์ฑ๋ณด๋ค๋ ์์ฑ์ ์ค์ ํ๋ ๊ฒ์ด ๋ฌธ์์ด, ์ซ์ ๋๋ ๋ถ์ธ๊ณผ ๊ฐ์ ๋จ์ํ ์ ํ์ ํ์ํ ์ ๋ถ๋ ์๋๋๋ค. ์ค๋ช ํ๋ ๊ฒฝ์ฐ๋ iconname์ ์์ฑ์ผ๋ก ์ง์ ์ฌ์ฉํ์ฌ ์ฝ๊ฒ ๋ฌ์ฑํ ์ ์์ผ๋ฉฐ ์ํ๋ฅผ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ์ฌ์ ํ ๊ฑฐ์ ๋์ผํ ์ต์ข ๋ ๋๋ง ๊ฒฐ๊ณผ์ ๋๋ค.
๋๋ ์ ๋ฐ๋ฅด์ง ์๋๋ค. ๋ด ๊ฐ์ ์๋๋ฆฌ์ค๋ https://github.com/facebook/react/issues/11347#issuecomment -713223628์ ๋ํ ์๋ต์ผ๋ก id
์ ์ธํ๊ณ ์๋ฒ ์์ฑ HTML์์ ์์ฑ์ ์ ํ ๋ด๋ณด๋ด์ง ์์์ผ ํ๋ค๋ ์ ์์ฒ๋ผ ๋ค๋ ธ์ต๋๋ค.
<github-icon iconname="smiley" />
<github-icon icon={{ name: "smiley" }} />
๊ฐ์ฌ ํด์!
React.createElement()
๋ฅผ ๋ด๋ถ์์ ์์ฑ ๋งคํ์ ์ํํ๋ ์ฌ์ฉ์ ์ ์ ๊ตฌํ์ผ๋ก ๋์ฒดํ์ฌ ์ฌ์ ์์ฑํ๋ ์ต์
์ผ๋ก ๊ฐ์ฃผ๋์์ต๋๊น?
์ฌ์ฉ ์:
/** <strong i="8">@jsx</strong> h */
import { h } from 'react-wc-jsx-shim';
function Demo({ items }) {
return <my-custom-list items={items} />
}
์ด์ ๊ตฌํ:
export function h(element, props, children) {
if(typeof element === 'string' && element.includes('-')) {
return React.createElement(Wrapper, { props, customElementName: element }, children)
}
return React.createElement(element, props, children);
}
function Wrapper({customElementName, props}) {
const ref = React.useRef();
React.useEffect(() => {
for(const prop in props) {
ref.current[prop] = props[prop];
}
});
return React.createElement(customElementName, { ref, ...props });
}
์ด๊ฒ์ด ๊ธฐ๋ณธ ์ ๊ณต ๊ธฐ๋ฅ์ด ์๋๋ผ๋ ๊ฒ์ ์๊ณ ์์ง๋ง ๋งค์ฐ ๋ฎ์ ์ค๋ฒํค๋๋ก ์ฌ์ฉ์ ์ฐจ๋จ์ ํด์ ํด์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
@just-boris๋ ๊ธฐ๋ณธ์ ์ผ๋ก createElement
ํจ์น ๋๋ ๋ํผ๋ฅผ ์ฌ์ฉํ์ฌ ์ฑ์ด๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ํ์ฌ ์ํํ๋ ์์
์
๋๋ค. ๋ํ React์์ ํน๋ณํ ๊ฒฝ์ฐ์ ์์ฑ ์ด๋ฆ์ ์ ์ธํด์ผ ํฉ๋๋ค. ๋ด ๋ณด๋ธ ๋ชฉ๋ก์ด ์๋ค๊ณ ์๊ฐํ๋ฏ๋ก ['children', 'localName', 'ref', 'elementRef', 'style', 'className']
์ ๊ฐ์ ๊ฑฐ๋ถ ๋ชฉ๋ก์ ํ๋ ์ฝ๋ฉํฉ๋๋ค.
ref ๊ธฐ๋ฐ์ด๊ธฐ ๋๋ฌธ์ ์์ฑ์ ์๋ฒ์์ ์ค์ ๋์ง ์์ต๋๋ค. ์ด๊ฒ์ด ๋ด๊ฐ ์ฐ๋ ค๋ฅผ ๋ชจํธํ๋ค๊ณ ๋ถ๋ฅด๋ ์ด์ ์ ๋๋ค. React์์๋ ์์ฑ์ ์ค์ ํ ์ ์๋ ๋ฐฉ๋ฒ์ด ์ ํ ์์ผ๋ฏ๋ก ์ง๊ธ์ ๋ชจ๋ ๋ง๊ฐ์ก์ต๋๋ค. ์ฌ์ฉ ๊ฐ๋ฅํ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ด๋ฏธ ํด๋ผ์ด์ธํธ์์๋ง ์๋ํฉ๋๋ค. ์๋ฒ๊ฐ ์๋ ํด๋ผ์ด์ธํธ์์ ์์ฑ์ ์ค์ ํ๋ ๋ฐฉ๋ฒ์ด ๋ด์ฅ๋์ด ์์ผ๋ฉด SSR์ด ๊ฐ์๊ธฐ ์์ ๋๊ฑฐ๋ ์ค๋จ๋์ง ์์ต๋๋ค.
์ฌ์ค ์ ๋ SSR๋ณด๋ค ์ด๋ฒคํธ์ ๋ ๊ด์ฌ์ด ์์ต๋๋ค. React๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์ถ๊ฐํ ๋ฐฉ๋ฒ์ด ์์ผ๋ฉฐ, ์ด๋ ๊ธฐ๋ณธ DOM API์์ ์ํธ ์ด์ฉ์ฑ์์ ํฐ ๊ตฌ๋ฉ์ ๋๋ค.
React.createElement()๋ฅผ ๋ด๋ถ์์ ์์ฑ ๋งคํ์ ์ํํ๋ ์ฌ์ฉ์ ์ง์ ๊ตฌํ์ผ๋ก ๋์ฒดํ์ฌ shim์ ๋ง๋๋ ์ต์ ์ผ๋ก ๊ฐ์ฃผ๋์์ต๋๊น?
์๋ ๋ฌธ์ ์์ Rob์ด ์ธ๊ธํ๋ฏ์ด https://github.com/skatejs/val ์ ํตํด ๊ณผ๊ฑฐ์ ์ด๊ฒ์ ์คํํ ์ ์ด ์์ผ๋ฏ๋ก React.createElement
๋ฅผ ๋ํํ๋ ์ฌ์ฉ์ ์ ์ JSX pragma๋ฅผ ๊ฐ๋ ๊ฒ์ด ์คํ ๊ฐ๋ฅํฉ๋๋ค ๋จ๊ธฐ - ์๋ฃจ์
.
๋ํ ํนํ React์ ๋ํด ๊น๊ณ ์์ SSR์ด๋ผ๊ณ ํ๋ ๊ฒ์ ๋ชจ๋ ๊ตฌํํ๋ Skate์ WIP ๋ถ๊ธฐ ๊ฐ ์์ต๋๋ค. ์ง๊ธ๊น์ง ์ด ์์ ์์ ์ป์ ๊ตํ์ ๊ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์์ฒด API ๋ฐ ์๊ณ ๋ฆฌ์ฆ์ ์์กดํ๊ธฐ ๋๋ฌธ์ ์ฌ์ธต SSR์ ์ํํ๋ ค๋ ๊ฒฝ์ฐ ๋ชจ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ํด ๋จ์ผ JSX ๋ํผ๋ฅผ ๊ฐ์ง ์ ์๋ค๋ ๊ฒ์ ๋๋ค. (์ปจํ ์คํธ๋ฅผ ์ํด Skate๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํต์ฌ ์ฌ์ฉ์ ์ ์ ์์ ๋ถ๋ถ๊ณผ ์์ฅ์์ ์ธ๊ธฐ ์๋ ๊ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํตํฉํ์ฌ ์ ๋ฐ์ ์ผ๋ก ์๋น ๋ฐ ์ฌ์ฉ์ ์ผ๊ด๋๊ฒ ๋ง๋ค๊ธฐ ์ํด ๊ตฌ์ถ๋ ์์ ๋ ์ด์ด๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค.)
๋๋ ๋ ์ด์ ์คํ ์์ค์์ ๋ง์ ์ผ์ ํ์ง ์์ผ๋ฉฐ ๋ ์ด์ ํธ์ํฐ๋ ํ์ง ์์ต๋๋ค.
์ต์ 1์ ์ต์ 2์ ๋ํ ์ ๋ง์ ์นํธ์๋ก ์กด์ฌํ๋ ๊ฒ์ฒ๋ผ ๋๊ปด์ง๋๋ค.
์ต์ 2๋ ๊ฐ ๊ธธ์ฒ๋ผ ๋๊ปด์ง๋๋ค. ์ด๊ฒ์ Preact๊ฐ ํ ๊ฒ๊ณผ ๋น์ทํ๋ฏ๋ก ์ ๋ก์ ์ปค๋ฎค๋ํฐ ํ์ค์ ๊ฐ๋ฅ์ฑ์ด ์์ต๋๋ค(์ด์จ๋ ํ๋ ๊ฒ์ด ํ์์ ์ผ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. JSX๋ ์ด๊ฒ์ด ์๋ํ ์ ์์์ ๋ณด์ฌ์ฃผ์์ต๋๋ค). ๋ํ ์ ๊ทธ๋ ์ด๋ํ๊ธฐ ์ฝ๊ธฐ ๋๋ฌธ์ React์ ์ค์ฉ์ ์ธ ์์ง์์ด๊ธฐ๋ ํฉ๋๋ค. (์ต์ 1๊ณผ ๋ฐ๋).
์ต์ 3์ ๋ฌธ์์์ผ๋ก๋ ์ข์ ๋ณด์ด์ง๋ง ์ธ์ง ์ค๋ฒํค๋, ์ธ๊ธ๋ ์ค๋ฒํค๋์ ๋ํ ๋ฌธ์ํ ๋ฐ SSR์ ๋ํ ์๋ ค์ง์ง ์์ ์ฌํญ์ผ๋ก ์ธํด ๋ ผ๋ฆฌ์ ์ผ๋ก ์ต์ 2๋ณด๋ค ํจ์ฌ ๋ ์ด๋ ค์ธ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
์ธ๊ธํ๋ฏ์ด ์๋ ์ต์
4๋ฅผ ์ ์ํ์ง๋ง ๋ฐ์ฑ ํ ๋ ์ด์ ๋ง์์ ๋ค์ง ์์ต๋๋ค. ๋ช
์์ ์ธ props
๋ฐ events
( attrs
๋์ )๋ฅผ ์ง์ ํ๋ ๋ ๋ง์ ์ ํ์ผ๋ก ๋ณ๊ฒฝํ ์ ์์ง๋ง, ์ต์
2๋ ๊ตฌํ ์ธ๋ถ ์ ๋ณด์ ๋ํ ์ง์์ด ๋ ํ์ํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ๊ฒ์ ์ฑํํ๊ธฐ ์ํด ๋ณ๊ฒฝํด์ผ ํ ์ฌ๋์ ์์ต๋๋ค.
์ต์ 5๋ ํต์ฌ ๋ฌธ์ ๋ฅผ ์์ ํ ๋ฌด์ํ๋ ๊ฒ์ฒ๋ผ ๋๊ปด์ง๋๋ค.
์ ์ณ๋๊ณ , ๋๋ ์ด๊ฒ์ ๋ํ ๊ด์ฌ์ ๋ณด๊ฒ๋์ด ๋งค์ฐ ๊ธฐ์ฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ฌ๋ฌ๋ถ ๋ชจ๋๊ฐ ์ํ๊ณ ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค!
์ฌ์ฉ์ ์์ญ์ ๊ฐ๋ฅํ ์๋ฃจ์ ์ด ์๋ค๋ฉด ๋น๋ถ๊ฐ ์ปค๋ฎค๋ํฐ์์ ํตํฉ ๋ฐ ๊ถ์ฅํ ์ ์์ต๋๊น?
๊ธฐ๋ฅ์ด ์ด๋ฏธ ์ธ๊ธฐ ์๊ณ ์คํ ๊ฐ๋ฅํ ํ์ฌ ๋ชจ๋๋ก ์กด์ฌํ๋ค๋ฉด React ํต์ฌ ํ์ด ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋๋ก ์ค๋ํ๋ ๊ฒ์ด ํจ์ฌ ์ฌ์ธ ๊ฒ์ ๋๋ค.
์ฌ์ฉ์ ์์ญ์ ๊ฐ๋ฅํ ์๋ฃจ์ ์ด ์๋ค๋ฉด ๋น๋ถ๊ฐ ์ปค๋ฎค๋ํฐ์์ ํตํฉ ๋ฐ ๊ถ์ฅํ ์ ์์ต๋๊น?
๋๋ ์ด๊ฒ์ด ์ธ๋ถ์์ [๊น๋ํ๊ฒ] ํจ์น๋ ์ ์๋ ๊ฒ์ด๋ผ๊ณ ๋ฏฟ์ง ์์ต๋๋ค. ๋๋ถ๋ถ์ userland ์๋ฃจ์ ์ this ๋ฐ this ์ ๊ฐ์ ๋ํผ์ ๋๋ค. React๋ฅผ ์์ ํ์ง ์๊ณ ๋ ์ด ์ ๊ทผ ๋ฐฉ์์ ๋ํ ํฉ๋ฆฌ์ ์ธ ๋์์ ์๊ฐํ ์ ์์ผ๋ฉฐ ๋ํ์ ํ์คํ ์ด์์ ์ธ ์๋ฃจ์ ์ด ์๋๋๋ค. ๐
vuejs/vue#7582์์ Vue๋ sigil์ ์ฌ์ฉํ๊ธฐ๋ก ์ ํํ๊ณ "."๋ฅผ ์ ํํ์ต๋๋ค. ์ ๋์ฌ๋ก (Glimmer์ "@"๊ฐ ์๋).
์ด์ ๋ํ ์ ๋ขฐํ ์ ์๋ ์ค๋ช ์ ๋ํ ๋งํฌ๊ฐ ์์ง๋ง(Vue์ ๋ ๊ฐ๊น์ด ์ฌ๋์ด ๋ช ์์ ์ผ๋ก ํ์ธํ ์ ์์) Vue๊ฐ Vue 3.0๋ถํฐ Option 2๋ก ์ด๋ํ ๊ฒ์ผ๋ก ๋ณด์ ๋๋ค. ์ฆ, Preact์ ์ ์ฌํ๊ฒ ๋์ํฉ๋๋ค. (๋งฅ๋ฝ์ ์ด ๋ฌธ์ ๋ฅผ ์ฐธ์กฐํ์ญ์์ค.)
ref ๊ธฐ๋ฐ์ด๊ธฐ ๋๋ฌธ์ ์์ฑ์ ์๋ฒ์์ ์ค์ ๋์ง ์์ต๋๋ค. ์ด๊ฒ์ด ๋ด๊ฐ ์ฐ๋ ค๋ฅผ ๋ชจํธํ๋ค๊ณ ๋ถ๋ฅด๋ ์ด์ ์ ๋๋ค. React์์๋ ์์ฑ์ ์ค์ ํ ์ ์๋ ๋ฐฉ๋ฒ์ด ์ ํ ์์ผ๋ฏ๋ก ์ง๊ธ์ ๋ชจ๋ ๋ง๊ฐ์ก์ต๋๋ค. ์ฌ์ฉ ๊ฐ๋ฅํ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ด๋ฏธ ํด๋ผ์ด์ธํธ์์๋ง ์๋ํฉ๋๋ค. ์๋ฒ๊ฐ ์๋ ํด๋ผ์ด์ธํธ์์ ์์ฑ์ ์ค์ ํ๋ ๋ฐฉ๋ฒ์ด ๋ด์ฅ๋์ด ์์ผ๋ฉด SSR์ด ๊ฐ์๊ธฐ ์์ ๋๊ฑฐ๋ ์ค๋จ๋์ง ์์ต๋๋ค.
https://github.com/facebook/react/issues/11347#issuecomment -713514984์์ ํน์ ์ง๋ฌธ์ ๋ต๋ณํด ์ฃผ์๊ฒ ์ต๋๊น? ์ฐ๋ฆฌ๊ฐ ์๋ก ๊ณผ๊ฑฐ๋ฅผ ์ด์ผ๊ธฐํ๋ ๊ฒ ๊ฐ์ ๋๋์ด ๋ญ๋๋ค. ๋๋ ๋จ์ง ์๋๋ ์ ์ฒด ๋์์ ํน์ ํ ๋ฐฉ์์ผ๋ก ์ดํดํ๊ณ ์ถ์ ๋ฟ์ ๋๋ค. ์ธ์ ์ค์ ๋๊ณ ์ด๋ค ๊ฒฝ์ฐ ์ง๋ ฌํ๋๋์ง.
์ฌ๊ธฐ์ ์ฐ์ฐํ ๋ฐ๊ฒฌํ ์์์ Preact+WC ๊ฐ๋ฐ์๋ก์ ์ ๋ "์ต์ 2"๊ฐ _๋ธ๋ ์ดํน ์ฒด์ธ์ง_์ผ ๋ฟ๋ง ์๋๋ผ _๋ถ์์ ํ ์๋ฃจ์ _์์ ์ง์ ํ๊ณ ์ถ์์ต๋๋ค(Preact๋ ์ฌ์ ํ ์ ํจํ ์น ๊ตฌ์ฑ ์์์ ํ์ ์งํฉ๊ณผ ์ ์ธ์ ์ผ๋ก๋ง ์ํธ ์์ฉํ ์ ์์).
ํด๋ฆฌ์คํฑ์ ํ์ฌ ์ฌ์ฉํ๊ณ ์๋ ์ฌ๋์ด๋ผ๊ณ ํด๋ ์ฅ๊ธฐ์ ์ผ๋ก ๋ณด๊ธฐ์๋ ๊ทธ๋ค์ง ๋ฐ๋์งํ์ง ์์ต๋๋ค.
Preact์ ํด๋ฆฌ์คํฑ("์ต์
2")์ React(ํค, ์์ ๋ฑ) ๋๋ Preact( on
์์ํ๋ ๋ชจ๋ ๊ฒ)์์ ํน๋ณํ ์๋ฏธ๋ฅผ ๊ฐ๋ ์์ฑ์ ์ค์ ํ ์ ์์ต๋๋ค.
์ฆ, JSX ์๋์์ ๋ ๋๋งํ ํ:
<web-component key={'key'} ongoing={true} children={[1, 2]} />
key
, ongoing
๋ฐ children
์์ฑ์ web-component
์ ์์ฑ๋ ์ธ์คํด์ค์์ ๋ชจ๋ undefined
(๋๋ ๊ธฐ๋ณธ๊ฐ์ด ๋ฌด์์ด๋ )๊ฐ ๋ฉ๋๋ค.
๋ํ OP์ ๋ฌ๋ฆฌ ์ด ์ต์
๋ ๋ธ๋ ์ดํน ์ฒด์ธ์ง์
๋๋ค. ๋๋ถ๋ถ์ ์น ๊ตฌ์ฑ ์์(์: lit-element
)๋ ์์ HTML๊ณผ ํจ๊ป ์ฌ์ฉํ๊ธฐ ์ํด ์์ฑ์ ํตํด ์ง๋ ฌํ๋ ํ๋ถํ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ ์ ์๋ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค. ์ด๋ฌํ ๊ตฌ์ฑ ์์๋ ๋ค์๊ณผ ๊ฐ์ด React์์ ๋ ๋๋ง๋ ์ ์์ต๋๋ค.
<web-component richdata={JSON.stringify(something)} />
"์ต์ 2"๋ฅผ ์ ํํ๋ฉด ์ค๋จ๋ฉ๋๋ค. ์น ๊ตฌ์ฑ ์์์ ์ด๋ฌํ ์ฌ์ฉ์ด React์์ ์ผ๋ง๋ ์ผ๋ฐ์ ์ธ์ง ํ์คํ์ง ์์ง๋ง ๊ทธ๋ ๊ฒ ํ๋ ์ผ๋ถ ์ฝ๋ ๊ธฐ๋ฐ์ด ๋ถ๋ช ํ ์์ต๋๋ค. refs๋ณด๋ค ๋ ํจ์จ์ ์ด์ง๋ง ๊ฐ๊ฒฐํฉ๋๋ค.
๋ง์ง๋ง์ผ๋ก Web Component์ ์์ฑ์๋ ๋์ผํ ์ด๋ฆ์ ์์ฑ๊ณผ ์์ฑ์ ๋ฏธ๋ฌํ๊ฒ ๋ค๋ฅธ ์๋ฏธ๋ฅผ ์์ ๋กญ๊ฒ ์ถ๊ฐํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ๊ธฐ๋ณธ input
์์์ ๋์์ ๋ชจ๋ฐฉํ๋ ์น ๊ตฌ์ฑ ์์๊ฐ ์์ต๋๋ค. value
์์ฑ์ ์ด๊ธฐ ๊ฐ์ผ๋ก ์ฒ๋ฆฌํ๊ณ value
์์ฑ์ ๋ณ๊ฒฝ ์ฌํญ๋ง ๊ด์ฐฐํฉ๋๋ค. ์ด๋ฌํ ๊ตฌ์ฑ ์์๋ ๊ฒฝํ์ ์ ๊ทผ ๋ฐฉ์์ผ๋ก jsx๋ฅผ ํตํด ์์ ํ ์ํธ ์์ฉํ ์ ์์ผ๋ฉฐ ๋์
๋ ๊ฒฝ์ฐ ๋ฏธ๋ฌํ ์์์ ๊ฒฝํํ ์๋ ์์ต๋๋ค.
์ด ํน์ ๊ธฐ๋ฅ๋ง์ ์ํด ์๋ก์ด JSX ๊ตฌ๋ฌธ์ ๋์ ํ ๊ฐ๋ฅ์ฑ์ ๊ฑฐ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
๋ค์์คํ์ด์ค๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ์ด๋ป์ต๋๊น? https://github.com/facebook/jsx/issues/66 ์ key
๋ฐ ref
์ ๋ํ react
๋ค์์คํ์ด์ค ์ถ๊ฐ๋ฅผ ์ ์ํฉ๋๋ค. ๊ฐ์ ๋งฅ๋ฝ์์ react-dom
๊ฒ์ด DOM ์์ฑ์ ์๋ณํ๋ ๋ฐ ์ฌ์ฉํ ์ ์๋ ๊ด์ฐฎ์ ๋ค์์คํ์ด์ค๊ฐ ๋ ๊น์? OP์ ์ต์
3 ์๋ฅผ ์ฌ์ฉํ๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
<custom-img react-dom:src="corgi.jpg" react-dom:hiResSrc="[email protected]" width="100%">
๊ทธ๊ฒ์ ๊ฐ์ฅ ์ธ์ฒด ๊ณตํ์ ์ด์ง ์์ต๋๋ค. dom
์์ผ๋ฉด ๋ ์ข๊ฒ ์ง๋ง React๊ฐ react
์์ํ์ง ์๋ ๋ค์์คํ์ด์ค๋ฅผ ๋ง๋ค๊ณ ์ถ์ดํ๋์ง ํ์คํ์ง ์์ต๋๋ค. ๋ํ ์์ฑ์ผ๋ก ์ค์ ํ๋ ๊ฒ์ด ๋ ์ผ๋ฐ์ ์ธ ๊ฒฝ์ฐ๋ผ๋ ์์ด๋์ด๊ฐ ์๋ค๋ฉด ์ด๊ฒ์ ๋ํ ์๋ชป๋ ์ธ์ฒด ๊ณตํ์ ์ธ์์ ๋์ด ์๋๋๋ค. SSR๊ณผ์ ํจ๋ฆฌํฐ๋ฅผ ์ ๊ณตํ๊ธฐ ๋๋ฌธ์ ์์ฑ์ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ ์ข์ต๋๋ค. ์์ฑ์ผ๋ก ์ค์ ํ๋ ๊ฒ์ ์์ฑ์ ๋ฌธ์ ๊ฐ ์๋ ๊ฒฝ์ฐ(์: ๊ฐ์ฒด๋ฅผ ์ ๋ฌํ๊ฑฐ๋ ์์ฑ์ด ์ง์ํ์ง ์๋ ์์ฑ์ ๋ํ ๊ฒฝ์ฐ)์ฉ์ด๋ฉฐ, ์ด์จ๋ ์์ฑ์ SSR์ ์ ์ฉํ ์ ์๊ณ ์ํํด์ผ ํ๋ ๋ฌธ์ ๊ฐ ์๋ ์์ฑ์ ๋ํ ๊ฒ์
๋๋ค. JS๋ฅผ ํตํด
_๋ถ์์ ํ ํด๊ฒฐ์ฑ _
(Preact๋ ์ฌ์ ํ ์ ํจํ ์น ๊ตฌ์ฑ ์์์ ํ์ ์งํฉ๊ณผ ์ ์ธ์ ์ผ๋ก๋ง ์ํธ ์์ฉํ ์ ์์ต๋๋ค.)
@brainlessbadger ์ด ํ์ ์งํฉ์ด ์ค์ ๋ก ๋ฌด์์ธ์ง ํฌํจํ๋๋ก ์์ ์๊ฒฌ์ ํธ์งํ ์๋ ์์ต๋๊น? ์. ์ด๋ค ์น ๊ตฌ์ฑ ์์/์ฌ์ฉ์ ์ ์ ์์๊ฐ ์ํฅ์ ๋ฐ์ต๋๊น(์์ ํฌํจ)? ๊ทธ๋ฆฌ๊ณ ์ ํํ ์ด๋ป๊ฒ ์ํฅ์ ๋ฐ์ต๋๊น?
@karlhorky ์ค๋ช ์ ์ถ๊ฐํ์ต๋๋ค. ์ธ๋ฐ์์ด ๋ชจํธํด์ ์ฃ์กํฉ๋๋ค.
์น ๊ตฌ์ฑ ์์ ์ด๋ฒคํธ ๊ด๋ จ. ์ด๋ฒคํธ ์ด๋ฆ ์ถฉ๋๋ก ์ธํด ํฅํ ์ฐจ๋จ์ ๋ฐฉ์งํ๋ ๋ฐฉ๋ฒ์ ๋ํ ํฉ์๊ฐ ์์ง ์์ต๋๊น?
๋ค์๊ณผ ๊ฐ์ด HTMLElement์ ์ ์์ฑ์ ์ถ๊ฐํ ์ ์๊ธฐ ๋๋ฌธ์ ์์ฑ ๋ฐ ์์ฑ์๋ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes ์๋ก ์ถ๊ฐ๋ ํญ๋ชฉ๋ ์์ผ๋ฏ๋ก ์ฌ์ ํ ์๋ก์ด ํญ๋ชฉ์ด ์ถ๊ฐ๋๊ณ ์์ต๋๋ค.
์๋ฐํ ๋งํ๋ฉด ์ฌ์ฉ์ ์ ์ ์์ฑ์ด๋ ์ฌ์ฉ์ ์ ์ ์ด๋ฒคํธ์ ์ด๋ฆ์ -
๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
๋ค๋ฅธ ๋ชจ๋ ๊ฒ์ ํด๋น ๊ตฌ์ฑ ์์๊ฐ ํฅํ ์ฌ์์์ ๋ฉ์ง ์ด๋ฆ์ ์ฌ์ฉํ์ง ๋ชปํ๋๋ก ์ฐจ๋จํ๋ ์ํ์ ํ๊ฐํ๋ ์ ์ถฉ์์ ๋๋ค.
์ด๋ฒคํธ๋ ํด๋น ๊ตฌ์ฑ ์์๊ฐ ํธํ๋์ง ์๋ ๋์์ ํ ์ํ์ด ์๊ธฐ ๋๋ฌธ์ ์ ๋ฅผ ๋์ฑ ๊ธด์ฅํ๊ฒ ๋ง๋ญ๋๋ค. ์ ์ด๋ฒคํธ๊ฐ ๋ฒ๋ธ๋ง๋๋ฉด ํด๋น ํธ๋ฆฌ ๊ฒฝ๋ก์ ์๋ ๋ชจ๋ ๊ธฐ์กด ์น ๊ตฌ์ฑ ์์๊ฐ ํธ๋ฆฌ๊ฑฐ๋ฉ๋๋ค.
์ฌ์ฉ์ ์ ์ ์์ฑ ๋ฐ ์ด๋ฒคํธ๊ฐ ์ด๋ฆ์ -
๋ฅผ ์ฌ์ฉํด์ผ ํ๋ ๊ฒฝ์ฐ ์ฌ์ฉํ ํญ๋ชฉ์ ๊ฒฐ์ ํ๊ธฐ ์ํ ๊ฒฝํ์ ๋ฐฉ๋ฒ์ผ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค. ๊ทธ๋ฐ ๋ค์ ๋ด์ฅ๋ ํน์ํ ๊ฒฝ์ฐ๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ด๊ฒ์ด ์ฐ๋ฆฌ๊ฐ ์ฒ์์ ์ฌ์ฉ์ ์ ์ ์์์ธ์ง ์ฌ๋ถ๋ฅผ ์ด๋ฏธ ์๋ ๋ฐฉ๋ฒ์
๋๋ค.
๊ทธ๋ฐ ๋ค์ ์์ฑ์ ํธ์๋ก ์ฌ์ฉํ์ฌ ๋ ์ข์ ์ฝ์์ ์ ๊ณตํ ์ ์์ต๋๋ค. ์ ์ด๋ ๊ทธ๊ฒ๋ค์ ๋ด์ฅ ์์ฑ์ ๊ฐ๋ฆฌ๊ณ ๋ฏธ๋ ์์ฑ๊ณผ ์ถฉ๋ํ์ง ์์ ์ ์์ต๋๋ค.
์๋ฐํ ๋งํ๋ฉด ์ฌ์ฉ์ ์ ์ ์์ฑ์ด๋ ์ฌ์ฉ์ ์ ์ ์ด๋ฒคํธ์ ์ด๋ฆ์ผ๋ก -๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
์ฌ์ฉ์ ์ ์ ์์ ์ฌ์์๋ ์ด๋ฌํ ์ ํ ์ฌํญ์ด ํฌํจ๋์ด ์์ง ์์ผ๋ฏ๋ก React์์ ์ ์ฉํ๋ฉด ์ํธ ์ด์ฉ์ฑ์ ์๋นํ ์ํฅ์ ๋ฏธ์นฉ๋๋ค.
์ฌ์ฉ์ ์ ์ ์์ ์์ฑ์๋ ํ๋ ์์ํฌ์ ์์ ์๊ตฌ ์ฌํญ์ ๊ตฌ๋ ํ ๊ฒ์ผ๋ก ๊ธฐ๋ํด์๋ ์ ๋ฉ๋๋ค. ๋ค์ํ ์๊ฒฌ๊ณผ ๊ด์ต์ผ๋ก ๋ชจ๋ ํ๋ ์์ํฌ๊ฐ ์ด ์์ ์ ์ํํ๋ค๊ณ ์์ํด ๋ณด์ญ์์ค. ์ด๊ฒ์ ์น ๊ตฌ์ฑ ์์๋ฅผ ์ฌ์ฉํ๋ ๋ชฉ์ ์ ๋ฌดํจํํฉ๋๋ค. ๐
์ด์์ ์ผ๋ก๋ ํ๋ ์์ํฌ๊ฐ ํ์ค์ ์์ฉํ๋๋ก ์กฐ์ ๋์ด์ผ ํฉ๋๋ค.
๋ฌผ๋ก . setAttribute()
๋ฐ dispatchEvent()
๋ ์ฒ์๋ถํฐ ์์์ ์ด๋ฆ์ ํ์ฉํ ์น ๊ตฌ์ฑ ์์๊ฐ ์๋ ํน์ API์
๋๋ค. ๋ชจ๋ ์์๋ ๋ชจ๋ ์์ฑ์ ๊ฐ์ง ์ ์๊ณ ๋ชจ๋ ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํฌ ์ ์์ต๋๋ค. ์ด๋ DOM์ ๊ธฐ๋ณธ ์ ๋ณด์ผ ๋ฟ์
๋๋ค.
data-
๋ค์์คํ์ด์ค๊ฐ ์ถ๊ฐ๋ ์ด์ ๊ฐ ์์ต๋๋ค. ๊ธฐ์ ์ ์ผ๋ก ํ ์ ์๋ ๊ฒ๊ณผ ๋ชจ๋ฒ ์ฌ๋ก ์ฌ์ด์๋ ์ฐจ์ด๊ฐ ์์ต๋๋ค. ๊ธฐ์ ์ ์ผ๋ก ํ๋กํ ํ์
์ ํจ์นํ ์๋ ์์ง๋ง ํฌํจ/ํฌํจ ์ํฉ์ด ๋ฐ์ํฉ๋๋ค.
React๋ง์ด ์ด๊ฒ์ ์ถ๊ฐํ๋ ๊ฒ์ด ์๋๋ผ ์ปค๋ฎค๋ํฐ๊ฐ ๋ฏธ๋์ ๋ค์์คํ์ด์ค๋ฅผ ๋ณดํธํ๋ ๋ฐ ๋์์ด ๋๋๋ก ์ด ๊ท์น์ผ๋ก ์ ํํ๋ ๊ฒ์ ์ ์ํ์ง ์์ต๋๋ค. ๋ค๋ง ์ด ๋ฌธ์ ๊ฐ ์ฌ๊ฐํ๊ฒ ๋ฐ์๋ค์ฌ์ง์ง ์๋ ๊ฒ์ด ์ํ๊น์ธ ๋ฟ์ ๋๋ค. ๊ทธ๋ฌ๋ ์๋ง๋ ์น์ ์๋ก์ด API์ ์ด์ํ ์ด๋ฆ๋ง ์ถ๊ฐํ ์ด๋ช ์ ๋๋ค.
๋๋ SSR์์ ๋ด์ฅ๋์ง ์์ ๊ฒ์ ์ ์ธํ๋ค๋ ์์ด๋์ด๋ฅผ ์ข์ํ๊ณ ์ ์ธ์ ๊ทธ๋ฆผ์ DOM์ ์ฌ์ฉํ๋ฉด ์ค์ ์ฝํ ์ธ ๊ฐ ๋ด๋ถ์์ ํ์ฅ๋ ์ ์๊ธฐ ๋๋ฌธ์ ์ํ ์ค์ ์์ฑ์ ์ ํธํฉ๋๋ค.
๊ตฌ์ฒด์ ์ผ๋ก๋ ์์ฑ์ ์ฌ์ฉํ๊ณ AMP ๋ฐํ์์ด ์ด๋ฏธ ๋ก๋๋์๋ค๊ณ ๊ฐ์ ํ ์ ์๊ธฐ ๋๋ฌธ์ ์ฌ๋๋ค์ด SSR + AMP์ ํจ๊ป ์ฌ์ฉํ๋ ํ์ฌ ์ ๊ทผ ๋ฐฉ์์ ๋ฌธ์ ๋ฅผ ์ผ์ผํฌ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
์ต์ 3์์ ๋ฌธ์ด ๋ซํ์ง ์์๋ค๊ณ ๊ฐ์ ํ๋ฉด ์์ ๋จ์ ์ ๋์ด๋์ง ์์ ์ต์ 2์ ๋นํด ์๋นํ ์ด์ ์ด ์์ต๋๋ค. -- ์ต์ 2์์ ๋ฐ๊ฒฌํ ๋ฌธ์ ๋ ์น ๊ตฌ์ฑ ์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ๋น๋๊ธฐ์ ์ผ๋ก ๋ก๋๋๋ ๊ฒฝ์ฐ preact๊ฐ ๊ทธ๋ ์ง ์์ ์ ์๋ค๋ ๊ฒ์ ๋๋ค. ์ ์ ์๋ ์์์ ๊ฒฝ์ฐ "์์ฑ"์ด ์์ฑ์ด ๋ ๊ฒ์์ ์๊ณ ์์ต๋๋ค. unknown ์์์ ์๋ ์์ฑ์ ์ฐพ์ง ๋ชปํ๋ฏ๋ก ๊ธฐ๋ณธ์ ์ผ๋ก ์์ฑ์ด ์ฌ์ฉ๋ฉ๋๋ค. ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ข ์ ์น ๊ตฌ์ฑ ์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ๋ก๋๋ ๋๊น์ง ํด๋น ๊ตฌ์ฑ ์์๋ฅผ ๋ ๋๋งํ์ง ์๋ ๊ฒ์ ๋๋ค. ์ด๋ ๋งค์ฐ ์ฐ์ํ์ง ์๊ฑฐ๋ ์ฑ๋ฅ๋ฉด์์ ์ด์์ ์ด์ง ์์ต๋๋ค. ์ฐ๋ฆฌ ๊ทธ๋ฃน์ node.js๊ฐ ์๋ asp.net์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ์ค์ ๋ก SSR์ ํ์ํ ์ ์ด ์์ผ๋ฏ๋ก ์๋ ๊ด์ฐฐ์ ์ถ์ธก์ ๋๋ค.
React ํ์ ์ ์ฅ์์๋ SSR๊น์ง ๋ค๋ฅธ ํ๋ ์์ํฌ๊ฐ ์ง์ํ๋ ๊ฒ ์ด์์ผ๋ก ์ ์ํ๋ ๊ฒ์ ์ข์ ์ ์ค์ฒ๋ผ๊ณ ์๊ฐํฉ๋๋ค. ์ฌ์ฉ์๊ฐ ๋ ์ข์ต๋๋ค.
๋ปํ ๋ง์ธ์ง ์๋์ง๋ ๋ชจ๋ฅด๊ฒ ์ง๋ง ์ผ๋ถ ์์ฑ์ ๊ฒฝ์ฐ JSON ๋ฌธ์์ด์ ํตํด ์์ฑ์ ์ด๊ธฐ ๊ฐ์ ์ค์ ํ๋ ๊ฒ์ด ํธ๋ฆฌํ๋ค๋ ์น ๊ตฌ์ฑ ์์์ ์ฝ๊ฐ์ ํฉ์ ๊ฐ ์๋ค๊ณ ์๊ฐ ํฉ๋๋ค . ์์๋ฐ์ดํ๋ก ๋ฌถ์ต๋๋ค.
AMP๋ ๋ค๋ฅธ ๊ท์น์ ์ฌ์ฉํฉ๋๋ค. -- ์ด๋ฅผ ์ํํ๊ธฐ ์ํด ์คํฌ๋ฆฝํธ type=application.json ์ ์ฌ์ฉํฉ๋๋ค. ์ด๋ ํฉ๋ฆฌ์ ์ธ(๊ทธ๋ฌ๋ ์ฅํฉํ) ๋์์ ๋๋ค.
๊ทธ๋ฌ๋ ์์ฑ ์ ๊ทผ ๋ฐฉ์์ ๊ณ ์ํฉ๋๋ค.
๊ทธ๋ฐ ๋ค์ ์น ๊ตฌ์ฑ ์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์์ฑ์ ๊ตฌ๋ฌธ ๋ถ์ํ๊ฑฐ๋ ์์ฑ์ ํตํด ๊ฐ์ ์ ๋ฌํ ์ ์์ต๋๋ค.
๋ฐ๋ผ์ ์ํ ์ง์ฐ์ ๋ฐฉ์งํ๋ ค๋ฉด ๋ค์์ ์ค์ ํ๋ ๊ฒ์ด ํธ๋ฆฌํฉ๋๋ค.
<github-icon icon='{"name":"smiley"}'></github-icon>
SSR ์ค. ๊ทธ๋ฌ๋ฉด github-icon์ ์ฆ์ ๊ทธ ์ผ์ ํ ์ ์๊ณ ๋ด๋ถ์ ์ผ๋ก ์์ฑ์ JSON.parse๋ฅผ ์ํํ๊ณ React๊ฐ (๋ ์์ ํ?) ๊ฐ์ฒด ๊ฐ์ ์ ๋ฌํ ๋๊น์ง ๊ธฐ๋ค๋ฆด ํ์๊ฐ ์์ต๋๋ค.
์ด์ ์ฐ๋ฆฌ๋ ๊น๋ค๋ก์ด ์ํฉ์ ์ฒํ์ต๋๋ค. ์๋ฒ์์ ๋ ๋๋งํ๋ ๊ฒฝ์ฐ "์์ด์ฝ"์ด ์์ฑ์ผ๋ก ์ฒ๋ฆฌ๋๊ธฐ๋ฅผ ์ํ์ง๋ง ๊ฐ์ ๊ฐ์ฒด๋ก ์ ๋ฌํ ์ ์๊ธฐ๋ฅผ ์ํฉ๋๋ค. ์ด์์ ์ผ๋ก๋ SSR ๋ฉ์ปค๋์ฆ์ด ์์ฑ์ผ๋ก ๋ฌธ์์ดํํ ๊ฒ์ ๋๋ค. ํด๋ผ์ด์ธํธ์์ ์ฐ๋ฆฌ๋ ๊ฐ์ฒด๋ฅผ ์ง์ ์ ๋ฌํ ์ ์๊ธฐ๋ฅผ ์ํ๋ฉฐ ๋ฌธ์์ดํ ๋ฐ ๊ตฌ๋ฌธ ๋ถ์์ ์ค๋ฒํค๋๋ฅผ ๊ฑฐ์น์ง ์๊ธฐ๋ฅผ ์ํฉ๋๋ค.
๋ฌผ๋ก ์ผ๋ถ ์์ฑ์ ๋ฌธ์์ดํ/ํ์ฑ์ ์ํํ ์ ์๋ ๊ฐ์ฒด์ด๋ฏ๋ก ์ด๋ ์ ์ฉ๋์ง ์์ผ๋ฉฐ ํด๋น ์์ฑ์ ์ํ๊ฐ ์๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ ค์ผ ํฉ๋๋ค.
๋ชจ๋ ์์ฑ๊ณผ ์์ฑ์ด React ํ์ด ์ ํธํ๋ ๋ช ๋ช ๊ท์น(์๋ง๋)์ ๋ฐ๋๋ค๋ฉด -- ๋ชจ๋ ์์ฑ์ ๋์๊ฐ ์๊ณ ๋ชจ๋ ์์ฑ์ด camelCase๋ฅผ ์ฌ์ฉํ๋ ๋ณตํฉ ์ด๋ฆ์ด์๋ค๋ฉด ๋์๊ฐ ์์ผ๋ฉด ์์ฑ๊ณผ ์์ฑ์ ๊ตฌ๋ณํ๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค.
<github-icon my-icon={myStringifiedProperty} myIcon={myObjectProperty}></github-icon>
๋ฌธ์ ๋ ์์ ๊ตฌ๋ฌธ์์ ํด๋ผ์ด์ธํธ์ ์๋ฒ์์ ์ํํ ์์ ์ ๋ํ๋ด์ง ์์ผ๋ฉฐ ์ด์์ ์ผ๋ก๋ ๋ ๋ค์ ๋ํด ํ๋์ ๋ฐ์ธ๋ฉ์ ์ฌ์ฉํ ์ ์๊ณ React๋ ์ด๋ ๊ฒ์ ์ฌ์ฉํ ์ง ์์๋ผ ๋งํผ ์ถฉ๋ถํ ๋๋ํ ๊ฒ์ ๋๋ค.
React๋ ์์ฑ/์์ฑ ํค๊ฐ ์นด๋ฉ ์ผ์ด์ค์ธ ๊ฒฝ์ฐ ํญ์ ํด๋ผ์ด์ธํธ ์ธก์์ ๊ฐ์ฒด๋ก ์ ๋ฌํ๊ณ SSR ์ค์ ์ค์ ๋ ๊ฒฝ์ฐ ๊ฐ์ฒด์ JSON ๋ฌธ์์ด ์ง๋ ฌํ๋ฅผ ์ ๋ฌํ๋ค๊ณ ๊ฐ์ ํ ์ ์์ต๋๋ค. ๋ง์ฐฌ๊ฐ์ง๋ก, ํค์ ๋์๋ (์์ ํ๊ฒ, ์ ์๊ฐ์) ๊ทธ๊ฒ์ด ์์ฑ์ด๋ผ๊ณ ๊ฐ์ ํ๊ณ ๊ฐ์ .toString()์ ์ ๋ฌํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋๋ ์ด๊ฒ์ด ๋๋ฌด ๋ง์ ๊ฒ์ ๊ฐ์ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ HTMLElement๋ฅผ ํ์ฅํ๋ ์น ์ปดํฌ๋ํธ์ ์์ฑ์ ์ ์ฉํ๋ฉด ์ ํจํ HTML๋ก ๊ฐ์ฃผ๋๋ ๋จ์ผ ๋จ์ด ์์ฑ ๋ฐ ์์ฑ์ ์ง์ํ์ง ์๋ ๊ฒ์ ๋๋ฌด ์ ํ์ ์ ๋๋ค. ๋๋ W3C๊ฐ ๋ฏธ๋์ ์ฌ์ฉํ ์ ์๋ "์์ฝ๋" ์์ฑ ์ด๋ฆ ๋ชฉ๋ก์ ๋ฐํํ๋ ๋ฐ ์ฐฌ์ฑํฉ๋๋ค. ์ด๋ JS์ ์์ฝ๋ ํค์๋์ ์ ์ฌํ๋ฉฐ, ์์ฝ๋ ์์ฑ ์ด๋ฆ์ ๋ถ์ ์ ํ๊ฒ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ๊ฐ๋ฐ์์๊ฒ ๊ฒฝ๊ณ ํ๋ ๋ฐฉ๋ฒ์ ์ฐพ๋ ํ๋ ์์ํฌ๋ฅผ ์ฐพ๋ ๊ฒ์ ๋๋ค.
๊ทธ๋ฌ๋ ์ต์ 3์ด ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ๊ทธ๋ฌ๋ ๋ ๋์ ์ฌ์ฉ์ ๊ฒฝํ์ ์ํด @gaearon์ด ์ ์ํ ๋๋ก ํฅ์๋ ์ ์๋ค๋ฉด ์ข์ ๊ฒ์ ๋๋ค.
๋ด ์ ์์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
<github-icon icon={myDynamicIcon}/>
์์ฑ(toString())์ ์๋ฏธํฉ๋๋ค.
<github-icon icon:={myDynamicIcon}/>
์๋ฏธ -- SSR ๋์ ๋ฌด์ํ์ง๋ง ํด๋ผ์ด์ธํธ์์ ๊ฐ์ฒด ์์ฑ์ ๋ฐ์ธ๋ฉํฉ๋๋ค(์ํ ํ).
์ด์ ์๋๋ฆฌ์ค(์ผ๋ถ?)๋ ์ด๋ป์ต๋๊น? React ํ์ด ํด๊ฒฐํ๋ ๋ฐ ๊ด์ฌ์ด ์์ต๋๊น? ๋ด ์ฒซ ๋ฒ์งธ ์๊ฐ์ ๋ ๊ฐ์ ์ฝ๋ก ๊ณผ ๊ฐ์ ๋ค๋ฅธ ๊ธฐํธ์์ต๋๋ค.
<github-icon icon::={myDynamicIcon}/> //Not my final suggestion!
์ฆ, SSR ๋์ JSON.stringify ์์ฑ์ ๋ ๋๋ง๋ HTML์์ ์์ฑ์ผ๋ก ์ค์ ํ๊ณ ์์ฑ์ด ์ํ ํ ๋ณ๊ฒฝ ์ฌํญ์ ๋ฐ์ธ๋ฉ๋ ๋ ํด๋ผ์ด์ธํธ์์ ๊ฐ์ฒด๋ก ์ ๋ฌํฉ๋๋ค.
์ด๊ฒ์ ๋ณตํฉ ์ด๋ฆ์ผ๋ก ๋ฌด์์ ํด์ผ ํ๋์ง์ ๋ํ ๊น๋ค๋ก์ด ์ํฉ์ ๋จ๊น๋๋ค. ์ฆ, ๋ค์์ ์ค์ ํ๋ฉด:
<github-icon iconProps::={myDynamicIconProp}/> //Not my final suggestion!
์์ฑ ์ด๋ฆ iconProps์ ๋ํ ํด๋น ์์ฑ์ด icon-props์ฌ์ผ ํ๋ค๋ ๊ฒ์ ๊ณผ๊ฑฐ์ ๋ ผ๋์ ์ฌ์ง๊ฐ ์์์ต๋๋ค.
์๋ง๋ ์ด๋ฌํ ์น ๊ตฌ์ฑ ์์ ์ค ์ผ๋ถ๊ฐ ๋ณ๊ฒฝ ์์ด ํ๋ซํผ์ ๋ด์ฅ๋ ์ ์๋ค๋ ๋ง๋ น ๋๋ฌธ์ ์ด๊ฒ์ ๋ ๋ ผ๋์ด ๋์์ ๊ฒ์ ๋๋ค. ์์ฑ์๋ ๋์๊ฐ ํฌํจ๋ ์ ์์ต๋๋ค(๊ทธ๋ฌ๋ ์์ฑ์ camelCase์ผ ์ ์์). ๋ด๊ฐ ์๋ ํ JSON ์ญ์ง๋ ฌํ๋ฅผ ํตํด ๋ณต์กํ ๊ฐ์ฒด๋ฅผ ์ ๋ฌํ ์ ์๋ ๊ธฐ๋ณธ ์์๋ ์์ง ์์ง๋ง ๋์ค์ ํ์ํ ๊ฒฝ์ฐ ๋๋ผ์ง ์์ ๊ฒ์ ๋๋ค. ๊ทธ๋ ๋ค๋ฉด React๋ ๋์๋ฅผ ์ธ์ ์ฝ์ ํ ์ง ์ฌ๋ถ๋ฅผ ์ด๋ป๊ฒ ์ ์ ์์๊น์?
๋ด๊ฐ ์๊ฐํด๋ผ ์ ์๋ ์ ์ผํ (์ถํ?) ์ ์์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
<github-icon icon-props:iconProps={myDynamicIconProp}/>
์ฆ, ์๋ฒ์์๋ ์ง๋ ฌํ ํ ์์ฑ icon-props๋ฅผ ์ฌ์ฉํ๊ณ ํด๋ผ์ด์ธํธ์์๋ ์์ฑ iconProps๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ์ฒด๋ฅผ ์ง์ ์ ๋ฌํฉ๋๋ค.
ํ์ด๋ธ๋ฆฌ๋ ์์ฑ/์์ฑ ์์ ํ์ฉํ๋ ๋ ์์ธํ ํ๊ธฐ๋ฒ์ ๋ ๋ค๋ฅธ ์ ์ฌ์ ์ด์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ํนํ ๋ค์๊ณผ ๊ฐ์ ๊ฒฝ์ฐ ํด๋น ์์ฑ๋ณด๋ค ๊ธฐ๋ณธ ์์์ ์์ฑ์ ๋ฐ๋ณต์ ์ผ๋ก ์ค์ ํ๋ ๊ฒ์ด ์กฐ๊ธ ๋ ๋น ๋ฅผ ์ ์์ต๋๋ค. ๋ฌธ์์ด์ด ์๋ ์์ฑ. ๊ทธ๋ ๋ค๋ฉด React๋ ํ์ฌ ์๋ฒ์ ์์ฑ๊ณผ ํด๋ผ์ด์ธํธ์ ์์ฑ์ ์ฌ์ฉํฉ๋๊น? ๊ทธ๋ ์ง ์๋ค๋ฉด ์ด ํ๊ธฐ๋ฒ์ผ๋ก ํด๊ฒฐํ ์ ์๋ ๋ช ๋ช ๋ฒ์ญ์ ์ด๋ ค์๊ณผ ๊ฐ์ ๋ฌธ์ ๋๋ฌธ์ ๋๊น?
@bahrus ๋จ์ํ ํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
<my-element attr='using-quotes' property={thisIsAnObject} />
๊ตฌ์ฒด์ ์ธ ์๋ฅผ ๋ค์ด ๋ฌธ์ ๋ฅผ ์ค๋ช ํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ข์ ๊ฒ ๊ฐ์ต๋๋ค.
HTML Form ์์์๋ ์ฌ๋ฌ ์์ฑ์ด ์์ต๋๋ค. "๋ณตํฉ ์ด๋ฆ"์ด ์๋ ์ด๋ฆ์ ๋ชจ๋ ์ผ๊ด๋ ์ด๋ฆ ์ง์ ํจํด์ ๋ฐ๋ฅด๋ ๊ฒ ๊ฐ์ง ์์ต๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ๋ชจ๋ ์๋ฌธ์๋ฅผ ์ฌ์ฉํ๊ณ ๊ตฌ๋ถ ๊ธฐํธ๊ฐ ์์ง๋ง ๋์ ๊ตฌ๋ถ ๊ธฐํธ๊ฐ ์๋ ๊ฒฝ์ฐ๋ ์์ต๋๋ค. - "๊ฐฑ์ ํ๋ค".
ํด๋น JS ์์ฑ ์ด๋ฆ์ acceptCharset, noValidate์ ๊ฐ์ ๋ฉ์ง ๋ฒ์ฉ ํจํด์๋ ๋ง์ง ์์ต๋๋ค. noValidate ์์ฑ/novalidate ์์ฑ์ ๋ถ์ธ์ด๋ฏ๋ก ํด๋ผ์ด์ธํธ์์ myForm.noValidate = true์ ๋ฐ๋๋ก myForm.setAttribute('novalidate', '')๋ฅผ ์ํํ๋ ๊ฒ์ ๋ญ๋น(์์)์ ๋๋ค.
๊ทธ๋ฌ๋ ์๋ฒ์์ myForm.noValidate = true๋ก ์ค์ ํ๋ ๊ฒ์ ์๋ฏธ๊ฐ ์์ต๋๋ค. DOM์ ๋ฌธ์์ด ํํ์ ๋ณด๋ด๊ณ ์ถ๊ธฐ ๋๋ฌธ์ ์์ฑ์ ์ฌ์ฉํด์ผ ํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
<form novalidate={shouldNotValidate}>
์ฌ์ค, React/JSX๊ฐ boolean ์์ฑ์ ์กฐ๊ฑด๋ถ ๋ก ๊ณ ์ ๋ ์ ์ ์กฐํ ํ ์ด๋ธ ์ ์์กด
๊ฐ๋ฐ์๊ฐ ์ฑ๋ฅ์ ํฌ์ํ์ง ์๊ณ ์๋ฒ(์์ฑ์ ํตํด)์ ํด๋ผ์ด์ธํธ(์์ฑ์ ํตํด)๋ฅผ ์์ ํ ์ ์ดํ ์ ์๋๋ก ์ด๋ฌํ ๋ชจ๋ ์๋๋ฆฌ์ค๋ฅผ ์ด๋ป๊ฒ ๋ํ๋ผ ์ ์์ต๋๊น? novalidate์ ๊ฐ์ ๋ถ์ธ์ ๊ฒฝ์ฐ ๋ค์์ ์ ์ํฉ๋๋ค.
<form novalidate:noValidate?={shouldNotValidate}/>
React๊ฐ DOM์ ์๋ฒฝํ๊ฒ ์ง์ํ๋ค๋ฉด, ์ง์ ๋ถํ์ง๋ง ๊ฐ๋ฅํ ํ ์ฑ๋ฅ์ด ์ข์ ๋ฐฉ์์ผ๋ก, ๋ค์ด๋ฐ ํจํด์์ ๊ทธ๋ค์ง ์ผ๊ด์ฑ์ด ์์ ์๋ ์๋ ์ฌ์ฉ์ ์ง์ ์์๋ฅผ ์ง์ํ๋ ๋ฐ ํฐ ๋์์ด ๋ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
์๋ฒ์์ JSON.stringify๋ฅผ ํตํด ์์ฑ์ ๊ฐ์ฒด ์์ฑ์ ์ ํ์ ์ผ๋ก ์ง๋ ฌํํ๋ ์ง์์ ์ถ๊ฐํ๋ฉด React ๋ฐ ์น ๊ตฌ์ฑ ์์์ ์ถ๊ฐ์ ์ธ ํฐ ์-์์ด ๋ ๊ฒ ๊ฐ์ต๋๋ค.
์๋๋ฉด ๋ด๊ฐ ๋ญ๊ฐ๋ฅผ ๋์น๊ณ ์์ต๋๊น? ( @eavichay , ๊ทํ์ ์๋ฅผ ๋ฐ๋ฅด์ง ์๊ณ ์ด๋ฌํ ์๋๋ฆฌ์ค๋ฅผ ๊ฐ์ฅ ์ ํํํ๋ ๋ฐฉ๋ฒ์ ์ ์ํ์๊ฒ ์ต๋๊น?)
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
์ฌ๋ฌ๋ถ, ๊ธฐ๋ค๋ฆฌ๋ ๋์ React https://www.npmjs.com/package/reactify-wc ์์ ์น ๊ตฌ์ฑ ์์๋ฅผ ๋ํํ๊ธฐ ์ํ shim์ ๋ง๋ค์์ต๋๋ค.
์ด๊ฒ์ด ๋์์ด ๋๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
(์ด๊ฒ์ ๋ด๊ฐ OSS์ ์ฒ์์ผ๋ก ์ง์ถํ ๊ฒ์ด๊ณ , ์ฌ๋ฌด์ค ๋ฐ์์ ๋ฌด์ธ๊ฐ๋ฅผ ๊ณต๊ฐํ ์ต์ด์ ๊ฒ ์ค ํ๋์ ๋๋ค. ๊ฑด์ค์ ์ธ ๋นํ์ ๋ํ ๋์ ์์ด ํ์์ ๋๋ค ๐ )