Search

React Advanced

subtitle
HOC, Reconciliation
Tags
react
Created
2021/04/24
2 more properties

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๋ฅผ ์‚ฌ์šฉํ•  ์ผ์€ ๋ณ„๋กœ ์—†๋‹ค.

references