Virtual DOM
๋ธ๋ผ์ฐ์ DOM์์ 10๊ฐ์ ๋ณ๊ฒฝ์ฌํญ์ด ๋ฐ์ํ๋ฉด, 10๋ฒ์ ๋ฆฌ๋ ๋๋งํ๋ค. ๋ธ๋ผ์ฐ์ ๋ ๋๋ง์์ layout(๋ฐฐ์น)๊ณผ paint(๊ทธ๋ฆฌ๊ธฐ)๋ ์๊ฐ์ด ๋ง์ด ๊ฑธ๋ฆฌ๋ ์ฐ์ฐ์ด๋ฉฐ ๋ณ๊ฒฝ์ฌํญ์ด ๋ฐ์ํ ๋๋ง๋ค ๊ณ์ํด์ ๋ฆฌ๋ ๋๋งํ๋ฏ๋ก ์๋๋ ๋๋ฆฌ๊ณ ๋ฉ๋ชจ๋ฆฌ ๋ญ๋น๋ ํฌ๋ค.
๊ทธ๋์ ๋ฆฌ์กํธ์์๋ Virtual DOM(๊ฐ์ DOM)์ ๋ง๋ค์ด ๋ณ๊ฒฝ๋ ๋ถ๋ถ์ ๋ชจ์ ์ค์ DOM์ ์
๋ฐ์ดํธ ํ๋ค. ์ดํ๋ฆฌ์ผ์ด์
์์ ๋ณ๊ฒฝ์ฌํญ์ด ๋ฐ์ํ๋ฉด Virtual DOM์ ์ ์ฒด UI๊ฐ ๋ฆฌ๋ ๋๋ง ๋๋ฉฐ ์ด์ DOM๊ณผ ์๋ก์ด DOM์ ์ฐจ์ด๋ฅผ ์ฒดํฌํ๋ค. ๊ทธ ๋ค์ ์ค์ DOM์ ๋ณ๊ฒฝ๋ ๋ถ๋ถ๋ง ์
๋ฐ์ดํธํ๋ค. ์ฌ๋ฌ ๊ฐ์ ๋ณ๊ฒฝ์ฌํญ์ด ๋ฐ์ํด๋ ์ด๋ฅผ ๋ชจ์ ํ ๋ฒ๋ง ์
๋ฐ์ดํธํ๊ธฐ ๋๋ฌธ์ ๋ ๋๋ง ์๋๋ฅผ ๋์ด๊ณ , ๋ฉ๋ชจ๋ฆฌ ๋ญ๋น๋ ์ค์ผ ์ ์๋ค.
HOC(Higher Order Component)
์๋ฐ์คํฌ๋ฆฝํธ์ HOF(Higher Order Function)์ฒ๋ผ HOC๋ ์ปดํฌ๋ํธ๋ฅผ ์ธ์๋ก ๋ฐ์ ์ปดํฌ๋ํธ๋ฅผ ๋ฐํํ๋ ํจ์์ด๋ค. HOC๋ ์๋ณธ ์ปดํฌ๋ํธ๋ฅผ ๋ณ๊ฒฝํ์ง ์๊ณ ์กฐํฉํ์ฌ ๋ฐํํ๋ ํจ์๋ก์ ์ด๋ *์์ ํจ์์ ์ผ์ข
์ด๋ค.
*์์ ํจ์(pure function): ํจ์ ๋ด๋ถ์์ ์ธ๋ถ ๋ฐ์ดํฐ์ ์ง์ ์ ๊ทผํ์ง ์๊ณ ํ๋ผ๋ฏธํฐ๋ก ๋ฐ์์ ์ฌ์ฉํ๋ค. ๋๋ฌธ์ ์๋ณธ ๋ฐ์ดํฐ๋ ๋ถ๋ณ์ฑ์ ์ ์งํ ์ ์๋ค. ๋จ, ์ธ๋ถ ๋ฐ์ดํฐ๋ผ ํด๋ ๋ณ๊ฒฝ ๊ฐ๋ฅ์ฑ์ด ์๋ค๋ฉด(ex. Object.freeze๋ก ๋๊ฒฐ, ์ค์นผ๋ผ ํ์
์ ์์ ๋ฑ) ํจ์ ๋ด๋ถ์์ ์ ๊ทผํด๋ ๋ถ๋ณ์ฑ์ด ์ ์ง๋๋ฏ๋ก ์์ ํจ์์๋ ๊ฐ๋ค.
HOC์ ์ฌ๋ฌ ์ปดํฌ๋ํธ๋ค ์ฌ์ด์์ ๋น์ทํ ๋ก์ง์ด ๋ฐ๋ณต๋ ๋ ์ฌ์ฉํ๋ค. ์๋ฅผ ๋ค์ด ์ธ๋ถ ๋ฐ์ดํฐ DataSource์ ์ ๊ทผํด์ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ์ป๊ณ , ๋ณ๊ฒฝ์ฌํญ์ ์
๋ฐ์ดํธ ํ๋ ์ปดํฌ๋ํธ๋ค์ด ์ฌ๋ฌ ๊ฐ ์๋ค๊ณ ํ์. withSubscription ์ด๋ผ๋ HOC์ ๋ง๋ค์ด์ ์ปดํฌ๋ํธ์ ๋ฐ์ดํฐ์ ์ ๊ทผํ๋ ํจ์ selectData๋ฅผ ์ธ์๋ก ๋ฐ๋๋ค. HOC ๋ด์์๋ selectData๋ฅผ ํตํด ์ปดํฌ๋ํธ๊ฐ ํ์๋ก ํ๋ ๋ฐ์ดํฐ๋ง ๊ฐ์ ธ์ ํด๋น ์ปดํฌ๋ํธ์ props์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ค.
const CommentListWithSubscription = withSubscription(
CommentList,
(DataSource) => DataSource.getComments()
);
const BlogPostWithSubscription = withSubscription(
BlogPost,
(DataSource, props) => DataSource.getBlogPost(props.id)
);
function withSubscription(WrappedComponent, selectData) {
return class extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.state = {
data: selectData(DataSource, props)
};
}
componentDidMount() {
DataSource.addChangeListener(this.handleChange);
}
componentWillUnmount() {
DataSource.removeChangeListener(this.handleChange);
}
handleChange() {
this.setState({
data: selectData(DataSource, this.props)
});
}
render() {
return <WrappedComponent data={this.state.data} {...this.props} />;
}
};
}
JavaScript
๋ณต์ฌ
source of code : react document - HOC
HOC์ render ๋ฉ์๋ ์, ํน์ function ์ปดํฌ๋ํธ ์์์ ์ฌ์ฉ๋์ด์ ์๋๋ค. ๋ฆฌ๋ ๋๋งํ ๋๋ง๋ค ๊ณ ์ฐจ์ปดํฌ๋ํธ๊ฐ ํธ์ถ๋๋ฉด์ ๊ณ ์ฐจ์ปดํฌ๋ํธ๊ฐ ๋ฐํํ๋ ์ปดํฌ๋ํธ์ ๋ณ๊ฒฝ์ฌํญ์ด ์๋๋ผ๋ ๊ธฐ์กด๊ณผ ๋ค๋ฅธ ํ์
์ ์ปดํฌ๋ํธ๋ก ์ทจ๊ธ๋ฐ๊ฒ ๋๋ค.
render () {
EnhancedComponent = withSubscription(WrappedComponent, selectData)
}
JavaScript
๋ณต์ฌ
reconciliation(์ฌ์กฐ์ )์ ์ปดํฌ๋ํธ์ identity๋ฅผ ํตํด ๊ธฐ์กด ์๋ธํธ๋ฆฌ๋ฅผ ์
๋ฐ์ดํธํ ์ง ์๋๋ฉด unmount ์ํค๊ณ ์๋ก์ด ๋
ธ๋๋ฅผ ๋ง์ดํธํ ์ง ๊ฒฐ์ ํ๋ค. ์ฒ์ ๋ ๋๋ง๋ EnhancedComponent์ ๋ฆฌ๋ ๋๋ง์์ ์๋กญ๊ฒ ๋ฐํ๋ EnhancedComponent๊ฐ ๊ฐ์ง ์์ผ๋ฏ๋ก reconciliation์ ํตํด subtree๋ง ์
๋ฐ์ดํธํ๋ ๊ฒ ์๋๋ผ ์ ์ฒด ์ปดํฌ๋ํธ๋ฅผ ์๋ก ๋ง์ดํธ ์์ผ๋ฒ๋ฆฐ๋ค. ๋ ๋๋งํ ๋๋ง๋ค ๋ณ๊ฒฝ๋ ๋ถ๋ถ๋ง์ด ์๋ ์ปดํฌ๋ํธ์ ์ ์ฒด ๋
ธ๋๋ฅผ ๋ค์ ๋ง์ดํธํ๋ฏ๋ก ์ฑ๋ฅ์์ ๋ฌธ์ ๋ ์์ง๋ง, state๋ฅผ ์ ์งํ์ง ๋ชปํ๋ค๋ ๋ฌธ์ ๋ ์๋ค. ๊ทธ๋ฌ๋ฏ๋ก ์ปดํฌ๋ํธ ์ ์ ๋ฐ๊นฅ์์ HOC์ ์ ์ฉ์์ผ์ผ ํ๋ค.
HOC๋ ์ปดํฌ๋ํธ๋ค ์ฌ์ด์์ ๋ฐ๋ณต๋๋ ๋ก์ง์ ์ฌ์ฌ์ฉํ๊ธฐ ์ํด ์ฌ์ฉํ๋ค๊ณ ํ๋ค. ๋ง์ฐฌ๊ฐ์ง๋ก hook ์ญ์ ์ปดํฌ๋ํธ์์ ๋ฐ๋ณต๋๋ ๋ก์ง์ ์ฌ์ฌ์ฉํ๊ธฐ ์ํด ์ฌ์ฉํ๋ค. ์ปค์คํ
ํ
์ ๋ง๋ค์ด HOC์ ์ฌ์ฉํ๋ ๋๋ถ๋ถ์ ๊ฒฝ์ฐ๋ฅผ ๋์ฒดํ ์ ์๋ค. ํ
์ ๋ง๋๋ ๊ฒ์ ๊ฐ๋จํ๋ฉฐ HOC์ ์ฌ์ฉํ ๋์ ์ค์ฒฉ๋ ์ปดํฌ๋ํธ๋ฅผ ์ค์ผ ์ ์๋ค๋ ์ฅ์ ์ด ์๋ค.
Reconciliation (์ฌ์กฐ์ )
๋ ๋๋งํ ๋ ๋ชจ๋ ํธ๋ฆฌ๋ฅผ ์๋ก ๋ง์ดํธํ์ง ์๊ณ , ๋ณ๊ฒฝ์ด ํ์ํ ๋ถ๋ถ๋ง ๋ง์ดํธํ๋ค. ๋ฆฌ์กํธ์์๋ ์ด๋ฅผ ์ํด ๋น๊ต ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ์ฌ ๋ถํ์ํ ์
๋ฐ์ดํธ๋ฅผ ์ค์ธ๋ค. ์ด ์๊ณ ๋ฆฌ์ฆ์๋ ๋ ๊ฐ์ง ์ฌ์ค์ ๊ฐ์ ํ๋ค.
1.
์๋ก ๋ค๋ฅธ ํ์
์ ๋ ์๋ฆฌ๋จผํธ๋ ์๋ก ๋ค๋ฅธ ํธ๋ฆฌ๋ฅผ ๋ง๋ค์ด๋ธ๋ค.
2.
๊ฐ๋ฐ์๊ฐ key prop์ ํตํด, ์ฌ๋ฌ ๋ ๋๋ง ์ฌ์ด์์ ์ด๋ค ์์ ์๋ฆฌ๋จผํธ๊ฐ ๋ณ๊ฒฝ๋์ง ์์์ผ ํ ์ง ํ์ํด ์ค ์ ์๋ค.
UI์ ๋ณ๊ฒฝ์ฌํญ์ด ์๊ธฐ๋ฉด ๋ฆฌ์กํธ๋ ๊ธฐ์กด ์ปดํฌ๋ํธ์ ์๋ก์ด ์ปดํฌ๋ํธ์ ํธ๋ฆฌ๋ฅผ ๋น๊ตํ๋ค. ๋น๊ต ์๊ณ ๋ฆฌ์ฆ์ ๋ฃจํธ ์๋ฆฌ๋จผํธ๋ถํฐ ๋น๊ตํ๋ฏ๋ก ์๋์ ๊ฐ์ด ๋ฃจํธ ์๋ฆฌ๋จผํธ๊ฐ ๋ฐ๋ ๊ฒฝ์ฐ ์ด์ ์ปดํฌ๋ํธ์ ํธ๋ฆฌ๋ฅผ ๋ชจ๋ ๋ฒ๋ฆฌ๊ณ ์๋ก ๋ง์ดํธํ๋ค. ๊ธฐ์กด์ ์ปดํฌ๋ํธ๋ฅผ ๋ชจ๋ ๋ฒ๋ ธ๊ธฐ ๋๋ฌธ์ state ์ญ์ ์์ค๋๋ค.
<div>
<Counter />
</div>
<span>
<Counter />
</span>
TypeScript
๋ณต์ฌ
๋ฐ๋ฉด, ๊ธฐ์กด ์๋ฆฌ๋จผํธ ํ์
์ด ๊ฐ๊ณ ์์ฑ๋ง ๋ฌ๋ผ์ง ๊ฒฝ์ฐ, ์์ฑ๋ง ์
๋ฐ์ดํธํ๋ค. ์ด๋๋ ์ปดํฌ๋ํธ๊ฐ ์ ์ง๋์ด ๋ฆฌ๋ ๋๋ง ํ์๋ ์ปดํฌ๋ํธ์ state๋ ์ ์ง๋๋ค.
๋ฆฌ์กํธ๋ ๋ฃจํธ ์๋ฆฌ๋จผํธ์์๋ถํฐ ํธ๋ฆฌ๋ฅผ ๋น๊ตํ๋ฉฐ ์์ ์๋ฆฌ๋จผํธ๋ฅผ ์ฌ๊ท์ ์ผ๋ก ์ํํ๋ฉฐ ๋น๊ตํ๋ค. ์ด๋ ์์ ์์์ ์ฒซ๋ฒ์งธ ์๋ฆฌ๋จผํธ์ ๋ณ๊ฒฝ์ฌํญ์ด ์๊ธฐ๋ฉด ๊ฐ์ ๋ ๋ฒจ์ ํ์ ์๋ฆฌ๋จผํธ๊น์ง ๋ฒ๋ ค์ง๊ณ ๋ค์ ๋ง์ดํธ๋ ์ ์๋ค. ๊ทธ์ ์์์ ์ํด์ ๋ณ๊ฒฝํ ํ์๊ฐ ์๋ ๋ค๋ฅธ ์๋ฆฌ๋จผํธ๊น์ง ์
๋ฐ์ดํธ๋๋ ๊ฒ์ด๋ค. ๋ฆฌ์กํธ์์๋ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด key ์์ฑ์ ์๋ฆฌ๋จผํธ์ ๋ํ id๋ฅผ ๋ถ์ฌํด ์๋ก ์ถ๊ฐ๋ ์๋ฆฌ๋จผํธ์ ๋ณ๊ฒฝ์ด ํ์์๋ ๊ธฐ์กด ์๋ฆฌ๋จผํธ๋ฅผ ๊ตฌ๋ณํ๋ค. key๋ก ๊ตฌ๋ถํ๊ธฐ ๋๋ฌธ์ ์ด๋ค ์๋ฆฌ๋จผํธ๊ฐ ์๋ก ์ถ๊ฐ๋์๋์ง ์์ด์ก๋์ง ํ๋จํ ์ ์๋ค.
references
โข
โฆ
useSelector, useDispatch ์ ๊ฐ์ hook๋ค์ด ๋ง๋ค์ด์ก๊ธฐ ๋๋ฌธ์ connect๋ฅผ ์ฌ์ฉํ ์ผ์ ๋ณ๋ก ์๋ค.

