Skip to content

sangmin802/sangmin802.github.io

Repository files navigation

SangMin ๊ฐœ๋ฐœ์ด์•ผ๊ธฐ

ํ…œํ”Œ๋ฆฟ ์ œ์ž‘์ž : Jbee
ํ…œํ”Œ๋ฆฟ : [gatsby-starter-bee](https://github.com/JaeYeo pHan/gatsby-starter-bee)
๋„ˆ๋ฌด๋‚˜๋„ ๋ฉ‹์ง„ ๋ฒ ์ด์Šค ๋งŒ๋“ค์–ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

ํฌ์ŠคํŠธ๋กœ ์ž‘์„ฑํ•˜๊ธฐ์—๋Š” ๋ถ€์ •ํ™•ํ•˜๊ฑฐ๋‚˜ ๋‹จ์ˆœํ•œ ์†Œ์Šค๋“ค

React.createElement, jsx

  • React์˜ UI๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ์š”์†Œ๋ฅผ js ๋‚ด๋ถ€์— ํฌํ•จ์‹œ์ผœ ํ•˜๋‚˜์˜ ์ปดํฌ๋„ŒํŠธ๋ผ๊ณ  ๋ถˆ๋ฆฌ๋Š” jsx๋ฅผ ์‚ฌ์šฉํ•จ. babel์„ ํ†ตํ•ด React.createElement๋กœ ์ปดํŒŒ์ผ ํ•œ๋‹ค๊ณ  ํ•จ

  • ReactDOM.render๋Š” ๋‹จ ํ•œ๋ฒˆ๋งŒ ํ˜ธ์ถœ์ด ๋˜๋ฉฐ, ReactDOM์€ ํ•ด๋‹น ์—˜๋ฆฌ๋จผํŠธ์™€ ์ž์‹ ์—˜๋ฆฌ๋จผํŠธ๋“ค์—์„œ ๋ณ€๊ฒฝ์ด ๋˜๋Š” ๋ถ€๋ถ„๋งŒ์„ ์—…๋ฐ์ดํŠธ ํ•œ๋‹ค.

    • ์—ฌ๊ธฐ์„œ ์—˜๋ฆฌ๋จผํŠธ๋Š” ์ปดํฌ๋„ŒํŠธ์™€ ๋‹ค๋ฅด๊ณ , ์ปดํฌ๋„ŒํŠธ์˜ ๊ตฌ์„ฑ์š”์†Œ์ด๋‹ค.

      function tick() {
        const element = (
          <div>
            <h1>Hello, world!</h1>
            <h2>It is {new Date().toLocaleTimeString()}.</h2>
          </div>
        )
        ReactDOM.render(element, document.getElementById('root'))
      }
      setInterval(tick, 1000)

      ์œ„์˜ ๋ฉ”์†Œ๋“œ๋ฅผ setInterval๋กœ ๋ฐ˜๋ณตํ•˜์—ฌ ์‹คํ–‰ํ•˜์—ฌ ์ „์ฒด์˜ UI๋ฅผ render ์‹œ์ผœ๋„ ์˜ค๋กœ์ง€ h2์˜ ํ…์ŠคํŠธ๋งŒ ๋ณ€๊ฒฝ๋œ๋‹ค.

  • ReactDOM.render์— ์‚ฌ์šฉ๋˜๋Š” ์—˜๋ฆฌ๋จผํŠธ๋Š” <Welcome />๊ณผ ๊ฐ™์€ ์‚ฌ์šฉ์ž ์ •์˜ ์ปดํฌ๋„ŒํŠธ๋กœ๋„ ๊ฐ€๋Šฅํ•จ

React ์ง„ํ–‰๊ณผ์ •

  • ReactDOM.render๋Š” <div>{word}</div>์™€ ๊ฐ™์€ React ์—˜๋ฆฌ๋จผํŠธ(jsx)๋ฅผ ๋ฐ›๋Š”๋‹ค.
  • ReactDOM.render์— ์—˜๋ฆฌ๋จผํŠธ๊ฐ€ ์ „๋‹ฌ๋˜๋ฉด, React ์—˜๋ฆฌ๋จผํŠธ ํŠธ๋ฆฌ(virtual dom)๊ฐ€์ƒ์„ฑ๋˜๊ณ , ์‹ค์ œ DOM์„ ์ƒ์„ฑํ•œ๋‹ค(๋Š๋‚Œ์ด ๊ธฐ๋ณธ์ ์œผ๋กœ ๋˜์–ด์žˆ๋Š” document.getElementById('root')์˜ ๋‚ด๋ถ€ DOM์„ ์ƒ์„ฑํ•˜๋Š”๊ฒƒ ๊ฐ™์Œ). ์ดํ›„์—๋Š” ๋น„๊ต, ์—…๋ฐ์ดํŠธ๋ฅผ ํ•จ
  • ์—˜๋ฆฌ๋จผํŠธ๋Š” <Welcome/>๊ณผ ๊ฐ™์€ ์‚ฌ์šฉ์ž ์ •์˜ ์ปดํฌ๋„ŒํŠธ๋กœ ๋Œ€์ฒด๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋Ÿฌํ•œ ์ปดํฌ๋„ŒํŠธ๋“ค์€ ํ•˜๋‚˜ ํ˜น์€ ์—ฌ๋Ÿฌ๊ฐœ์˜ ์—˜๋ฆฌ๋จผํŠธ ๋˜๋Š” ๋˜ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž ์ •์˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ return ํ•œ๋‹ค.
  • ์ฒ˜์Œ ReactDOM.render ๋กœ ์ƒ์„ฑ๋œ ์ดํ›„๋กœ๋Š” ์ „์ฒด๊ฐ€ ์•„๋‹Œ ๋ถ€๋ถ„์ ์œผ๋กœ ์—…๋ฐ์ดํŠธ๋ฅผ ์ง„ํ–‰ํ•จ. ์ด๋•Œ Lane : number์ด๋ผ๋Š” ๊ฐ’์„ ํ†ตํ•ด ๋Œ€์ƒ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ฐพ๋Š”๊ฒƒ๊ฐ™์Œ
  • ์ฒซ ์ƒ์„ฑ ์ดํ›„ setState๋ฅผ ํ†ตํ•ด ์ƒํƒœ๊ฐ’์— ๋ณ€ํ™”๊ฐ€ ์ƒ๊ธด๋‹ค๋ฉด ์ „์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š”๊ฒƒ์ด ์•„๋‹Œ React๋Š” ๋ณ€๊ฒฝ๋œ ์š”์†Œ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๋ฐ˜์˜ํ•˜๊ธฐ ์œ„ํ•ด diff ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๊ทœ์น™์— ๋”ฐ๋ผ ์ƒˆ๋กœ์šด virtual dom๊ณผ ์ด์ „์˜ dom์„ ๋น„๊ต๋ฅผ ํ•˜๊ณ  ๋ณ€๊ฒฝ๋œ ๋ถ€๋ถ„๋งŒ ๋ชจ์•„์„œ ํ•˜๋‚˜๋กœ ๋ฌถ์–ด์„œ ์‹ค์ œ DOM ํŠธ๋ฆฌ๋ฅผ ์—…๋ฐ์ดํŠธ ํ•จ
    1. ์—˜๋ฆฌ๋จผํŠธ์˜ ํƒ€์ž…์ด ์™„์ „ ๋‹ค๋ฅผ ๋•Œ, <div> -> <span>์—๋Š” ํ•ด๋‹น ์—˜๋ฆฌ๋จผํŠธ์™€ ์ž์‹๋“ค์„ ๋ชจ๋‘ ๋ฒ„๋ฆฌ๊ณ  ์ƒˆ๋กญ๊ฒŒ ์ƒ์„ฑํ•จ. ์ด ๋•Œ๋ฌธ์—, unmount, mount๊ฐ€ ๋‹ค์‹œ ํ˜ธ์ถœ๋˜๋Š” ๊ฒƒ
    2. ์—˜๋ฆฌ๋จผํŠธ์˜ ํƒ€์ž…์ด ๊ฐ™์„ ๋•Œ, ๋ณ€๊ฒฝ๋˜๋Š” prop๋งŒ ๋ฐ”๋€œ
    3. ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋™์ผํ•  ๋•Œ, ๋ณ€๊ฒฝ์ด ์žˆ๋Š” prop๋งŒ ์—…๋ฐ์ด๋“œ ๋จ. ์ด๋•Œ componentDidUpdate ํ˜ธ์ถœ๋จ (์ด๊ฑฐ๋Š” hook์—์„œ ์กฐ๊ธˆ ๋ฐ”๋€๊ฒƒ๊ฐ™์Œ)
    4. ์ž์‹์— ๋Œ€ํ•ด์„œ๋Š” key๋ฅผ ๊ธฐ์ค€์œผ๋กœ
  • React์—์„œ์˜ ์ปดํฌ๋„ŒํŠธ๋“ค์€ ์ž์‹ ์ด ๋ฐ›์€ ๋ฐ์ดํ„ฐ๊ฐ€ ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์˜ props๋กœ ๋ฐ›์€๊ฒƒ์ธ์ง€, ์ž์ฒด state์ธ์ง€ ์•Œ์ง€ ๋ชปํ•œ๋‹ค. ์˜ค๋กœ์ง€ ์ž์‹ ์ด ๋ฐ˜ํ™˜ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ ํ˜น์€ ์—˜๋ฆฌ๋จผํŠธ๋“ค์—๊ฒŒ ์–ด๋– ํ•œ ์†์„ฑ์„ ์ „๋‹ฌํ• ๊ฒƒ์ธ์ง€์—๋งŒ ์ง‘์ค‘ํ•˜๊ณ , ๋ณ€ํ™”๋ฅผ ์ค€๋‹ค.

    ์ด๋Ÿฌํ•œ ํŠน์ง• ๋•Œ๋ฌธ์—, React๋Š” ๋‹จ๋ฐฉํ–ฅ์‹ ๋ฐ์ดํ„ฐ ํ๋ฆ„์ด๋ผ๊ณ  ํ•œ๋‹ค.

jsx

  • HTML๊ณผ ํ‘œํ˜„์‹์ด ํ•จ๊ป˜ ์‚ฌ์šฉ๋˜์–ด React Element๋ฅผ ์ƒ์„ฑํ•œ๋Š” ์‹. React.createlement๋กœ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๊ณ  ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ๋กœ ์ปดํŒŒ์ผ๋˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•
  • React์—์„œ ์ž‘์„ฑํ•œ <Component id={1} /> ๋“ฑ๋“ฑ๋“ค์€ React.createElement(์—˜๋ฆฌ๋จผํŠธ, ์†์„ฑ, ์ž์‹๋“ค) ์œผ๋กœ ์ปดํŒŒ์ผ ๋˜์–ด ์ž‘๋™๋œ๋‹ค
  • ์ฒซ๋ฒˆ์งธ ์—˜๋ฆฌ๋จผํŠธ์—์„œ ์†Œ๋ฌธ์ž๊ฐ€ ์ „๋‹ฌ๋˜๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณต๋˜๋Š” div, span๋“ฑ์˜ ํƒœ๊ทธ๋“ค์ด๋ฉฐ ๋Œ€๋ฌธ์ž์ด๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ์ƒ์„ฑํ•œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ง€์นญํ•˜๊ฒŒ ๋œ๋‹ค
    • ์ปดํŒŒ์ผ ๋‹จ๊ณ„์—์„œ ์‚ฌ์šฉ์ž๊ฐ€ ์ƒ์„ฑํ•œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ฐพ๊ธฐ ๋•Œ๋ฌธ์—, ํ•ด๋‹น ์Šค์ฝ”ํ”„ ๋‚ด์—์„œ๋Š” import ๋˜์–ด ์•Œ๊ณ ์žˆ๋Š” ์ƒํƒœ์—ฌ์•ผ ํ•œ๋‹ค.
    • createElement๋˜ํ•œ, ์ปดํŒŒ์ผ ๋‹จ๊ณ„์—์„œ ์ฐพ๊ธฐ ๋•Œ๋ฌธ์— React๋ฅผ import ํ•ด๋†“์•„์•ผ ํ•œ๋‹ค.
  • ํ‘œํ˜„์‹์˜ ๊ฒฝ์šฐ ์œ„์˜ Component์ฒ˜๋Ÿผ ์†์„ฑ์„ ์ง์ ‘ ์ „๋‹ฌํ•  ์ˆ˜์žˆ์ง€๋งŒ, for๋‚˜ if ๊ฐ™์€ ๊ตฌ๋ฌธ์€ ์ง์ ‘ ์ „๋‹ฌ๋  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์—, ์ด๋Ÿฌํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ํ•ด๋‹น ์†์„ฑ์„ ์ „๋‹ฌํ•˜๋Š” React.createElement๋กœ ์ปดํŒŒ์ผ๋˜๋Š” return๋ฌธ์„ ์ž‘์„ฑํ•˜๋Š”๊ฒƒ์ด๋‹ค.

Hook์˜ ๋“ฑ์žฅ

class๊ฐ€ ์•„๋‹Œ ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์— React์˜ state์™€ ์ƒ๋ช…์ฃผ๊ธฐ ๊ธฐ๋Šฅ์„ ์—ฐ๋™์‹œ์ผœ์ฃผ๋Š” ํ•จ์ˆ˜์ด๋‹ค.

useState

  • React๋Š” Hook ํ˜ธ์ถœ์„ ์ปดํฌ๋„ŒํŠธ์™€ ์–ด๋–ป๊ฒŒ ์—ฐ๊ด€์‹œํ‚ค๋Š”๊ฐ€? https://ko.reactjs.org/docs/hooks-faq.html#how-does-react-associate-hook-calls-with-components
  • React๋Š” ํ˜„์žฌ ๋ Œ๋”๋ง์ค‘์ธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ถ”์ ํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ํ•จ ์ฝ”๋“œ๋ฅผ ๋ณด๋‹ˆ ์—…๋ฐ์ดํŠธ๋˜๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ Lane(number ํƒ€์ž…) ์ด๋ผ๋Š” ๊ฐ’์œผ๋กœ ์ฐพ๋Š”๊ฒƒ ๊ฐ™์Œ
  • ๊ฐ ์ปดํฌ๋„ŒํŠธ๋งˆ๋‹ค ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ๊ฐ–๊ณ ์žˆ๊ณ , useState์™€ ๊ฐ™์€ hook์ด ์ž‘๋™๋˜์—ˆ์„ ๋•Œ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ฐพ์•„์„œ ์‹คํ–‰ํ•˜๋Š”๊ฒƒ ๊ฐ™์Œ
  • React ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋Š” ์ƒํƒœ๊ฐ’์„ ํ•˜๋‚˜์˜ key์™€ value ํ•œ ์Œ์œผ๋กœ ๊ธฐ์–ต์„ ํ•œ๋‹ค๊ณ  ํ•จ
  • react hook ์ž‘๋™์›๋ฆฌ์˜ ์˜ˆ์ œ์—์„œ ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์˜ hook๋“ค์ด ์ž‘์„ฑ๋œ ์ˆœ์„œ๋กœ์˜ index๋กœ ๊ธฐ์–ตํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ. ์•„๋งˆ ์˜ˆ์ œ์—์„œ๋Š” ์ƒ๋‹นํžˆ ์ผ๋ถ€๋ถ„๋งŒ ๊ตฌํ˜„๋œ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์—, ์ถ”์ ํ•˜๋Š” key-value๋„ ์ƒ์œ„์— ์žˆ์„๊ฒƒ ๊ฐ™์Œ

๋ฐฐํฌ๋œ ๋ชจ๋“ˆ๋“ค์˜ ์„ ์–ธํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์œ„ํ•œ useContext ์‘์šฉ

React์—์„œ ์ „์—ญ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” hook์ธ๋ฐ, ๋ชจ๋“ˆ์„ ๋ฐฐํฌํ•  ๋•Œ ์‚ฌ์šฉ๋œ ๋ฐฉ์‹์ด ์ธ์ƒ๊นŠ์–ด์„œ ๊ธฐ๋ก์— ๋‚จ๊น€.

K?????F????

์ƒ์„ฑ๋œ context์˜ ๋ฒ”์œ„๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” Provider๋‚ด๋ถ€์— ์œ„์น˜ํ•˜๋Š” ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋“ค์ด ์˜ค๋กœ์ง€ null๋งŒ์„ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ์„ค์ •๋˜์–ด์žˆ์Œ ์ด ์ปดํฌ๋„ŒํŠธ๋“ค์€ ReactElement๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š”๊ฒƒ์ด ์•„๋‹ˆ๋ผ ํ•˜๋‚˜์˜ ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœ์ด๋˜์—ˆ์„ ๋•Œ, ์ „์—ญ์ƒํƒœ์— ์–ด๋– ํ•œ ์ƒํƒœ๊ฐ’์„ ํ• ๋‹นํ•˜๋Š” ์—ญํ• ๋กœ๋งŒ ์ˆ˜ํ–‰๋จ.

์ƒ๊ฐํ•ด๋ณด๋‹ˆ ๊ทธ๋Ÿฌํ•œ ๋ฐฉ๋ฒ•์ด React-Router์™€ ๊ฐ™์ด ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“ˆ์—์„œ๋„ ๊ฐ–๊ณ ์žˆ๋Š” ํŠน์ง• ๊ฐ™์Œ.

return (
  <Router>
    <Route path="/" component={Home} />
    <Route path="/something" component={Something} />
  </Router>
)

์‹ค์ œ๋กœ ReactElement๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์•„๋‹ˆ๋ผ Router Provider๊ฐ€ ๊ด€๋ฆฌํ•˜๋Š” ์ „์—ญ ์ƒํƒœ์˜ ์ƒํƒœ๊ฐ’์„ ์—…๋ฐ์ดํŠธ ํ•˜๋Š” ๋กœ์ง๋“ค์ด ๋‚ด๋ถ€์— ํฌํ•จ๋˜์–ด์žˆ๋Š” ์‚ฌ์šฉ์ž์ •์˜ ์ปดํฌ๋„ŒํŠธ

์ „์—ญ์ƒํƒœ์˜ ์ตœ์‹ ์ƒํƒœ๋ฅผ ์•Œ ๊ธฐ ์œ„ํ•ด, ํ•ด๋‹น ์ƒํƒœ๊ฐ’์„ ์‚ฌ์šฉํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋“ค์€ ๋ชจ๋‘ Provider๋‚ด๋ถ€์— ์œ„์น˜ํ•ด์•ผ ํ•˜๋Š” ํŠน์„ฑ์„ ๊ณ ๋ คํ•˜์˜€์„ ๋•Œ, ๋งŒ์•ฝ, ์ด๋ฅผ ์ปดํฌ๋„ŒํŠธ ํ˜•์‹์ด ์•„๋‹ˆ๋ผ hookํ˜•์‹์œผ๋กœ ๋ชจ๋“ˆ์„ ์ œ๊ณตํ–ˆ๋”๋ผ๋ฉด, ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ๋žŒ์€ Provider์—ญํ• ์„ ํ•˜๋Š” Router๋‚ด๋ถ€์—, ์ „์—ญ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธ์‹œ์ผœ์ฃผ๋Š” ๋กœ์ง์„ ์Šค์Šค๋กœ ๋งŒ๋“ค๊ณ  ๊ทธ๊ฒƒ๋“ค์„ ๊ฐ–๊ณ ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ๋“ค์„ ๋ณ„๋„๋กœ ์ƒ์„ฑํ•ด์•ผ ํ–ˆ์„ ๊ฒƒ์ด๋‹ค.

์—ฌ๋Ÿฌ๊ณณ์— ํ•ด๋‹น ๋ชจ๋“ˆ์˜ hook๋“ค์ด ๋ฟŒ๋ ค์งˆ์ˆ˜๋„ ์žˆ๊ณ , ๊ทธ ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ์ปดํฌ๋„ŒํŠธ๋“ค์ด ๋” ์ƒ์„ฑ๋  ์ˆ˜ ๋„ ์žˆ๋Š” ์ƒํ™ฉ

๊ทธ๋Ÿฌํ•œ๊ฒƒ์„ ๋Œ€์‹ ํ•ด์ฃผ๊ธฐ ์œ„ํ•ด ์ด๋Ÿฌํ•œ ๋กœ์ง์„ ๋‚ด์žฌํ•˜๊ณ ์žˆ์ง€๋งŒ, ReactElement๋Š” ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š๋Š” ์‚ฌ์šฉ์ž์ •์˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ชจ๋“ˆ๋กœ ๋งŒ๋“ค์–ด์„œ ์œ„์˜ ๋ฌธ์ œ๋ฅผ ๋Œ€์‹ ํ•ด์ฃผ๋„๋ก ํ•œ๊ฒƒ ๊ฐ™๋‹ค. ๋˜ํ•œ, path๋‚˜ render ๋  ์ปดํฌ๋„ŒํŠธ์™€ ๊ฐ™์ด ํ•ต์‹ฌ์ ์ธ ์š”์†Œ๋งŒ์„ ์‚ฌ์šฉ์ž๊ฐ€ ์ง€์ •ํ•˜๋„๋ก ํ•˜์—ฌ, ๋ถ€๊ฐ€์ ์ธ ๋กœ์ง์„ ์ž‘์„ฑํ•  ํ•„์š” ์—†์ด ์„ ์–ธํ˜•์˜ ์ปดํฌ๋„ŒํŠธ๋งŒ์„ ์ž‘์„ฑํ•˜์—ฌ๋„ ๋˜๋„๋ก ํ•ด์ค€๊ฒŒ ์•„๋‹๊นŒ?

Suspense

Suspense๋Š” React์—์„œ ์‚ฌ์šฉ๋˜๊ณ ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์‚ฌ์šฉํ•˜๊ณ ์žˆ๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์•„์ง ์ค€๋น„๋˜์ง€ ์•Š์•˜๋‹ค๋Š”๊ฒƒ์„ React์— ์•Œ๋ ค์ค„ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•.

React-query์™€ ๊ฐ™์ด ๋น„๋™๊ธฐ๊ณผ์ •์—์„œ loading๊ณผ๊ฐ™์€ ์ƒํƒœ๋ฅผ ์žก์„์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด ๋•Œ์˜ ๋น„๋™๊ธฐ์ž‘์—…๋“ค์€ ์ผ๋ฐ˜ Promise๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š”๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ƒํƒœ, ๊ฒฐ๊ณผ, ์‹ค์ œ promise๋‚˜ ํ•ด๋‹น promise์˜ ์ƒํƒœ๋ฅผ ๋ณ€์ˆ˜๋กœ์„œ ํด๋กœ์ €๋กœ ๊ธฐ์–ตํ•˜์—ฌ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š”๊ฒƒ ๊ฐ™์Œ

promise์˜ resolve, reject ์ƒํƒœ์— ๋”ฐ๋ผ ํด๋กœ์ €๋กœ์„œ ์ฐธ์กฐ์ค‘์ธ ์ƒํƒœ๋ณ€์ˆ˜๋„ ์—…๋ฐ์ดํŠธ์‹œํ‚ด

์ด ๋•Œ, ๋งŒ์•ฝ ์ƒํƒœ๊ฐ€ ์ฒ˜์Œ์˜ pending์ด๋ผ๋ฉด throw๋ฅผ ํ†ตํ•ด ์ค‘๋‹จ์‹œํ‚ค๊ณ  ํ•ด๋‹น promise๋ฅผ ์—๋Ÿฌ์˜ ๊ฐ’์œผ๋กœ ์ „๋‹ฌํ•˜์—ฌ Suspense๊ฐ€ ํฌ์ฐฉํ•˜์—ฌ fallback ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š”๊ฒƒ ๊ฐ™์Œ

์‹ค์ œ๋กœ, Suspense๋กœ ๊ฐ์‹ผ ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ Promise์ž์ฒด๋ฅผ throw๋ฅผ ํ†ตํ•ด ์—๋Ÿฌ์˜ ๊ฐ’์œผ๋กœ ์ „๋‹ฌํ•˜๋ฉด error๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”๊ฒƒ์ด ์•„๋‹Œ, Suspense์— ์ง€์ •ํ•œ fallback์ด ๋ฐ˜ํ™˜๋˜๋Š”๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Œ

๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ค๋Š” ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ throw๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ค‘์ง€์‹œํ‚ค๋Š”๊ฒŒ ํ•ต์‹ฌ์ธ๊ฒƒ ๊ฐ™์Œ. ๋˜ํ•œ ๊ทธ throw ์ž์ฒด๋ฅผ Suspense๊ฐ€ ๊ฐ์ง€ํ•˜์—ฌ fallback์„ ๋ฐ˜ํ™˜ํ•˜๋Š”๊ฒƒ๋„

unmount๊ฐ€ ์•„๋‹Œ ์ค‘์ง€์ž„ mount ์กฐ์ฐจ๋„ ๋˜์ง€ ์•Š์Œ

  • ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ ์ •์ง€ํ•˜๊ณ  ๋‹ค์Œ ์ปดํฌ๋„ŒํŠธ์˜ ๋ Œ๋”๋ง์„ ์‹œ๋„ํ•จ

    ์ผ์ข…์˜ ๋น„๋™๊ธฐ ์ž‘์—…์ฒ˜๋Ÿผ ์ค‘์ง€ํ•˜๊ณ  ์ดํ›„๋กœ ๋ฏธ๋ฃจ๋Š”๊ฒƒ ๊ฐ™์Œ

  • ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ์˜ ๋ Œ๋”๋ง์ด ์ข…๋ฃŒ๋˜๋ฉด ์ค‘์ง€๋˜์–ด์žˆ๋˜ ์ปดํฌ๋„ŒํŠธ์˜ ์ƒ์œ„์— ์žˆ๋˜ Suspense์— ์ „๋‹ฌ๋œ fallback์„ ์ฐพ๊ณ  ๊ทธ๊ฒƒ์„ ๋ Œ๋”๋งํ•จ

    ํ”ํžˆ ...loading ๊ฐ™์€๊ฒƒ๋“ค

    import React from 'react'
    
    let resolve = null
    
    const promise = new Promise(res => {
      resolve = res
    }).then(() => {
      data = 'success data'
    })
    
    function async() {
      if (!data) throw promise
      return data
    }
    
    export default function App() {
      return (
        <div className="App">
          <React.Suspense
            fallback={
              <button
                onClick={() => {
                  resolve?.()
                }}
              >
                resolve!
              </button>
            }
          >
            <InnerApp />
          </React.Suspense>
        </div>
      )
    }
    
    function InnerApp() {
      const data = async()
    
      return <>{data}</>
    }

    codeSandbox์—์„œ ์ •๋ง์ •๋ง๋กœ ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ตฌํ˜„ํ•ด๋ด„

์ด์ฒ˜๋Ÿผ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์„ ๋•Œ, ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ ์ž์ฒด์˜ ๋ Œ๋”๋ง์„ ์ผ์‹œ ์ค‘๋‹จ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Œ

ErrorBoundary

React์˜ ์ปดํฌ๋„ŒํŠธ ๊ธฐ๋ฐ˜ ์„ ์–ธํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ render ๊ณผ์ • ์ค‘ ๋ฐœ์ƒํ•œ ์—๋Ÿฌ๋ฅผ ํ•ธ๋“ค๋งํ•  ์ˆ˜ ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ

๋‚ด๋ถ€์˜ getDerivedStateFromError ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ๊ฐ–๊ณ ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ ํ•˜์œ„์— ์กด์žฌํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ ๋‚ด์—์„œ ๋ฐœ์ƒํ•œ ์—๋Ÿฌ๋ฅผ ํฌ์ฐฉํ•˜๊ณ , ์ค‘๋‹จ์‹œํ‚จ ๋‹ค์Œ ์ง€์ •ํ•œ fallback์„ ๋ Œ๋”๋ง ํ•จ

mount๊ฐ€ ์•ˆ๋œ๋‹ค๋Š” ์†Œ๋ฆฌ

try catch์™€ ๊ฐ™์€ ๋ฐฉ๋ฒ•์œผ๋กœ ์—๋Ÿฌ๋ฅผ ํ•ธ๋“ค๋งํ•  ์ˆ˜ ์—†๋‚˜? ์•ž์„œ ๋งํ–ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ, ReactElement๋ฅผ ์ƒ์„ฑํ•˜๋Š”๋ฐ ์„ ์–ธํ˜•์˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•  ๋•Œ try catch๋กœ๋Š” ์—๋Ÿฌ๋ฅผ ํ•ธ๋“ค๋งํ•  ์ˆ˜ ์—†์Œ

return์„ ํ†ตํ•ด ๋ Œ๋”๋ง ํ•  ๋•Œ, ReactElement๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์‚ฌ์šฉ์ž ์ •์˜ ์ปดํฌ๋„ŒํŠธ๋“ค ์‚ฌ์ด์‚ฌ์ด์— try catch๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•  ์ˆ˜๊ฐ€ ์—†์Œ

try catch๋Š” ๋‚ด๋ถ€์˜ ๋ช…๋ นํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ๋Œ€ํ•œ ์—๋Ÿฌ๋ฅผ ํ•ธ๋“ค๋ง ํ•˜๊ธฐ ์œ„ํ•จ์ด๋ผ๊ณ  ํ•จ

์‚ฌ์šฉ์ž ์ •์˜ ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ try catch๋กœ ๋‹ค๋ฅธ๊ฒƒ์„ returnํ•˜๋Š”๊ฒƒ์€ ๋˜๋Š”๊ฒƒ ๊ฐ™๊ธด ํ•จ.

ErrorBoundary๋Š” ์‚ฌ์šฉ์ž์˜ ์ด๋ฒคํŠธ(์‚ฌ์‹ค ์ด๋ฒคํŠธ๋„ ๋น„๋™๊ธฐ๋‹ˆ๊น), ๋น„๋™๊ธฐ์ž‘์—… ๋“ฑ ํ˜„์žฌ ํ™˜๊ฒฝ์—์„œ ๋ฒ—์–ด๋‚˜๊ฒŒ ๋œ๋‹ค๋ฉด ์—๋Ÿฌ๋ฅผ ํ•ธ๋“ค๋งํ•  ์ˆ˜ ์—†๋‹ค๊ณ  ํ•จ.

function App() {
  const [handleContinue, handleMount, handleFetch, handleCancel] = useAsync()

  return (
    <div className="App">
      <button onClick={handleMount}>Mount</button>
      <button onClick={handleFetch}>Fetch</button>
      <button onClick={handleContinue}>Continue</button>
      <button onClick={handleCancel}>Cancel</button>
      <InnerApp />
    </div>
  )
}

function InnerApp() {
  const [render, setRender] = useState(false)

  throw new Error()

  return <div>innerApp</div>
}

export default App

์œ„์™€๊ฐ™์€ ์ƒํ™ฉ์—์„œ๋Š” InnerApp์˜ ๋ Œ๋”๋ง ๊ณผ์ •์—์„œ ๋ฐœ์ƒํ•œ ์—๋Ÿฌ๋กœ ์ค‘๋‹จ๋˜์—ˆ์„ ๋•Œ, ์ƒ์œ„ App์˜ ๋ Œ๋”๋ง๊นŒ์ง€๋„ ๋˜์ง€ ์•Š๊ฒŒ๋จ.

ํ•˜์ง€๋งŒ

function App() {
  const [handleContinue, handleMount, handleFetch, handleCancel] = useAsync()

  return (
    <div className="App">
      <button onClick={handleMount}>Mount</button>
      <button onClick={handleFetch}>Fetch</button>
      <button onClick={handleContinue}>Continue</button>
      <button onClick={handleCancel}>Cancel</button>
      <ErrorBoundary>
        <InnerApp />
      </ErrorBoundary>
    </div>
  )
}

function InnerApp() {
  const [render, setRender] = useState(false)

  throw new Error()

  return <div>innerApp</div>
}

export default App

์œ„์™€๊ฐ™์ด ErorrBoundary๋กœ ํ•˜์œ„์˜ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ Œ๋”๋ง์ค‘ ๋ฐœ์ƒํ•˜๋Š” ์—๋Ÿฌ์— ๋Œ€ํ•ด ๋ฏธ๋ฆฌ ํฌ์ฐฉ์„ ํ•˜๊ณ  ๊ทธ์— ๋งž๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ง€์ •ํ•ด์ค€๋‹ค๋ฉด, App์˜ ๋‹ค๋ฅธ ReactElement๋“ค์€ ์ •์ƒ์ ์œผ๋กœ ๋ Œ๋”๋ง ๋˜๊ณ , ErrorBoundary๋‚ด๋ถ€์˜ ReactElement๋“ค๋งŒ ์ง€์ •ํ•œ ์—๋Ÿฌ ์ „์šฉ ๋ Œ๋”๋ง์ด ์ง„ํ–‰๋จ

์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์˜€์„ ๋•Œ ์ „์ฒด UI๊ฐ€ ๊นจ์ง€๋Š”๊ฒƒ์ด ์•„๋‹Œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ ์ผ๋ถ€๋ถ„๋งŒ ๋Œ€์ฒดํ•˜๋„๋ก ๋„์™€์ฃผ๋Š”๊ฒƒ์ด ํฐ ๊ฒƒ ๊ฐ™์Œ

๊ทผ๋ฐ React Query์™€ ๊ฐ™์€ ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•  ๋•Œ์—๋Š”, ๋น„๋™๊ธฐ ์ž‘์—…์ด์—ฌ๋„ ์—๋Ÿฌ๋ฅผ ์ž˜ ์žก๋Š”๋ฐ?

React Query๋“ฑ์˜ ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋น„๋™๊ธฐ์ž‘์—…์„ ๊ด€๋ฆฌํ•  ๋•Œ, Promise๊ฐ์ฒด๋ฅผ ์ฆ‰์‹œ ๋ฐ˜ํ™˜ํ•˜๋Š”๊ฒƒ์ด ์•„๋‹Œ ์—ฌ๋Ÿฌ ์ƒํƒœ๋ฅผ ํด๋กœ์ €๋กœ์„œ ์ฐธ์กฐํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š”๊ฒŒ ์•„๋‹๊นŒ ์‹ถ์Œ

๋”ฐ๋ผ์„œ, ๋ฐ์ดํ„ฐ์˜ ์š”์ฒญ, ์—๋Ÿฌ, ์„ฑ๊ณต์„ ํ•˜๋‚˜์˜ ๊ฐ’์œผ๋กœ ๊ธฐ์–ตํ•˜๊ณ  ์—…๋ฐ์ดํŠธ๋  ๋•Œ๋งˆ๋‹ค ์ผ๋ฐ˜ ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ throw๋ฅผ ์‹œํ‚ค๊ธฐ ๋•Œ๋ฌธ์— ErrorBoundary๊ฐ€ ์—๋Ÿฌ๋ฅผ ์žก์„์ˆ˜ ์žˆ๋Š”๊ฒƒ ์•„๋‹๊นŒ?

throw๋  ๋•Œ ์ „๋‹ฌํ•˜๋Š” ๊ฐ’์„ ๊ฐ์ฒด๋กœ ํ•˜๋ฉด ErrorBoundary์˜ ์œ ์—ฐํ•จ์„ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Œ

๊ฐ๊ฐ์˜ ์—๋Ÿฌ์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋ง ํ•˜๊ณ ์ž ํ•  ๋•Œ, ๊ทธ์— ๋งž๋Š” Fallback์ปดํฌ๋„ŒํŠธ๋ฅผ ์ „๋‹ฌํ•˜์—ฌ getDerivedStateFromError ์—์„œ ๋ Œ๋” ์ด์ „ ์ƒํƒœ๊ฐ’์— ํ• ๋‹น์‹œํ‚ฌ ์ˆ˜ ์žˆ์Œ

Promise์™€ callback ์ฐจ์ด

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

React๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ? ํ”„๋ ˆ์ž„์›Œํฌ?

  • React๋งŒ์˜ jsxํŒŒ์ผ์„ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ํŠน์ง•, ๊ธฐ์ค€์ด ์žˆ๊ณ  React๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์–ด๋Š์ •๋„ ๋น„์Šทํ•œ ๊ตฌ์กฐ๋ฅผ ๊ฐ–๊ฒŒ๋˜๋Š”์ ์—์„œ ํ”„๋ ˆ์ž„์›Œํฌ์— ๋” ๊ฐ€๊น๋‹ค๋Š” ์–˜๊ธฐ๋ฅผ ํ•จ
  • ๊ฐœ๋ฐœ์ž๊ฐ€ ์ œ์ž‘ํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์ด ๊ฐ–๊ณ ์žˆ๋Š” ๊ธฐ์ค€์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•„์š”ํ•œ ๊ธฐ๋Šฅ์„ ๋ถ€๋ถ„๋ถ€๋ถ„๋ณ„ ๊ฐ€์ ธ๋‹ค ์“ธ ์ˆ˜ ์žˆ๋‹ค๋ฉด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
  • ์ •ํ•ด์ ธ์žˆ๋Š” ๊ธฐ์ค€, ๊ทœ์น™, ํ๋ฆ„์ด ์žˆ๊ณ  ๊ทธ๋Ÿฌํ•œ ๊ธฐ๋ฐ˜์„ ๋ฐ”ํƒ•์œผ๋กœ ๊ฐœ๋ฐœ์ž๊ฐ€ ํ”„๋กœ๊ทธ๋žจ์„ ์ œ์ž‘ํ•œ๋‹ค๋ฉด ํ”„๋ ˆ์ž„์›Œํฌ

์™œ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ?

  • https://dzone.com/articles/what-is-typescript-and-why-use-it
  • ์ปดํŒŒ์ผ ๋‹จ๊ณ„์—์„œ ์˜ˆ์ƒ ์™ธ์˜ ๊ฒฐ๊ณผ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ๋“ค์„ ๋ฏธ๋ฆฌ ์•Œ๋ ค์ค˜์„œ ๋Ÿฐํƒ€์ž„ ๋•Œ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋„๋ก ์˜ˆ๋ฐฉ์„ ํ•ด์คŒ
  • ๋งŒ์•ฝ, ํ˜‘์—…์„ ํ•˜๋Š” ๊ณผ์ •์—์„œ ํŠน์ • ํ•จ์ˆ˜์— ์–ด๋– ํ•œ ํƒ€์ž…์˜ ๊ฐ’์ด ์ „๋‹ฌ๋˜์–ด์•ผ ํ•˜๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ์–ด์„œ, ๋ฒ„๊ทธ๋ฅผ ์˜ˆ๋ฐฉํ•  ์ˆ˜ ์žˆ์Œ

history.replace vs history.go

  • ๊ธฐ๋ณธ์ ์œผ๋กœ history ๊ฐ์ฒด๋Š” ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‚ฌ์šฉ์ž์˜ ๋ฐฉ๋ฌธ๊ธฐ๋ก์— ์ ‘๊ทผํ•˜๊ณ , ์ด๋™ํ•˜๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฐ์ฒด
  • history.replace : ํ˜„์žฌ ๊ฒ€์ƒ‰ ์Šคํƒ์— ์ตœ์ƒ์œ„์˜ ์œ„์น˜๋ฅผ ๋Œ€์ฒดํ•จ
  • history.push : ๋ˆ„์ ๋œ ๊ฒ€์ƒ‰ ์Šคํƒ ์œ„์— ํ•˜๋‚˜๋ฅผ ๋” ์Œ“์Œ
  • history.go(์ˆซ์ž) : -์ด๋ฉด ํ˜„์žฌ ๊ฒ€์ƒ‰์Šคํƒ์—์„œ ๋’ค๋กœ๊ฐ€๊ธฐ +๋ฉด ํ˜„์žฌ ๊ฒ€์ƒ‰์Šคํƒ์—์„œ ์•ž์œผ๋กœ์ด๋™

๋น„๋™๊ธฐ๋ฅผ ํ†ตํ•œ ์„ฑ๋Šฅ๊ฐœ์„ 

  • ๊ฒ€์ƒ‰ ์ž๋™์™„์„ฑ์„ ์‚ฌ์šฉํ•  ๋•Œ, ๋””๋ฐ”์šด์‹ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ setTimeout์˜ ๋น„๋™๊ธฐ๋ฅผ ์ด์šฉํ•ด ์ตœ์‹ ์˜ ์š”์ฒญ์—๋งŒ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ค๋Š” ๋กœ์ง์„ ์‹คํ–‰

๋น„๋™๊ธฐ๋ฅผ ํ†ตํ•œ ๊ฒฝํ—˜ ๊ฐœ์„ 

  • ์›๋ž˜๋Œ€๋กœ๋ผ๋ฉด, ์ฒ˜์Œ ๋ฐ์ดํ„ฐ๋ฅผ ๋น„๋™๊ธฐ๋กœ ๋ฐ›์•„์˜ค๊ณ , ๋ฐ›์•„์˜จ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒˆ๋กญ๊ฒŒ ์š”์ฒญ์„ ํ•˜๋Š” ๊ณผ์ •์— ์žˆ์–ด์„œ, ์‚ฌ์šฉ์ž๊ฐ€ ์ฒซ ํ™”๋ฉด์„ ๋ณด๋Š”๋ฐ ๋„ˆ๋ฌด ์˜ค๋žœ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฐ๋‹ค๊ณ  ํŒŒ์•…๋˜์–ด

    ์ฒซ ๋ฐ์ดํ„ฐ๊ฐ€ ์ˆ˜์‹ ๋œ๋‹ค๋ฉด, ํ™”๋ฉด์„ ๊ทธ๋ฆฌ๊ณ  ์ดํ›„์˜ ๋ฐ์ดํ„ฐ๋Š” ๋ณ„๋„์˜ ๋น„๋™๊ธฐ ์ž‘์—…์œผ๋กœ ์ง„ํ–‰ํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ค๋„๋ก ์ฒ˜๋ฆฌ

resolve์˜ ํ˜ธ์ถœ์‹œ๊ธฐ

๋น„๋™๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ง„ํ–‰์ค‘์ธ ์ด๋ฒคํŠธ๋ฅผ ์ผ์‹œ ์ค‘๋‹จํ•˜๊ณ , ๋‹ค๋ฅธ ํ™˜๊ฒฝ์—์„œ resolve๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ค‘๋‹จ๋œ ์ด๋ฒคํŠธ๋ฅผ ์ด์–ด์„œ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ์Œ

  • ์ง„ํ–‰์ค‘์ธ ์ด๋ฒคํŠธ์—์„œ, ๋‚˜๋จธ์ง€๋Š” ๋‚˜์ค‘์— ์‹คํ–‰์‹œํ‚ค๊ณ  ์‹ถ๋‹ค ๋ผ๋Š” ๊ฒฝ์šฐ, Promise๋ฅผ ํ†ตํ•ด ์ธ์ž๋กœ ๋ฐ›์€ resolve๋ฅผ ์›ํ•˜๋Š” ํƒ€์ด๋ฐ์— ํ˜ธ์ถœ์‹œ์ผœ์„œ ๊ทธ ์ดํ›„์— ์ง„ํ–‰์‹œํ‚ฌ ์ˆ˜ ์žˆ์Œ(React context๋‚˜ ์ „์—ญ๋ณ€์ˆ˜๋กœ ๊ธฐ์–ตํ•ด์„œ ๋‹ค๋ฅธ ํ™˜๊ฒฝ์—์„œ๋„ ๊ฐ€๋Šฅ.)
  • ํŠน์ •ํ”„๋กœ์ ํŠธ์—์„œ a select๋ฐ•์Šค์—์„œ ํŠน์ • ์˜ต์…˜์„ ์„ ํƒํ–ˆ์„ ๋•Œ๋งŒ b select ๋ฐ•์Šค๊ฐ€ ํ™œ์„ฑํ™” ๋˜๋Š” ์ƒํƒœ์—์„œ b select ์˜ ์˜ต์…˜์„ ์„ ํƒํ–ˆ์„ ๋•Œ a select๋ฅผ ์ดˆ๊ธฐํ™”์‹œํ‚ค๊ณ  ์‹ถ์—ˆ๊ธฐ ๋•Œ๋ฌธ์—, a select์—์„œ ์ดˆ๊ธฐํ™” ์‹œํ‚ค๋Š” ๋กœ์ง ์ด์ „์„ ์ค‘๋‹จํ‚ค๊ธฐ ์œ„ํ•ด ๋กœ์ง๋“ค์„ ๋น„๋™๊ธฐ๋กœ ์ฒ˜๋ฆฌํ•˜๊ณ , b select๋ฅผ ํ™œ์„ฑํ™”์‹œํ‚ค๋Š” ์˜ต์…˜์„ ์„ ํƒํ•˜์˜€์„ ๋•Œ์—๋Š” ์ฆ‰์‹œ resolve์‹œํ‚ค๋Š”๊ฒƒ์ด ์•„๋‹Œ b select ๋ฐ•์Šค์—์„œ์˜ ์˜ต์…˜์„ ์„ ํƒํ–ˆ์„ ๋•Œ resolve ์‹œ์ผœ์„œ a select box์˜ ๋‚˜๋จธ์ง€ ์ด๋ฒคํŠธ๋ฅผ ์ด์–ด์„œ ์ง„ํ–‰ํ•˜๋„๋ก ํ•˜์˜€์Œ

๋ธŒ๋ผ์šฐ์ € ์ž‘๋™ ๊ณผ์ •

  • ๋‚ด ๋ธ”๋กœ๊ทธ

react flux? ๋””์ž์ธํŒจํ„ด?

  • ๋งํฌ
  • ๋ทฐ์—์„œ๋„ ๋ฐ์ดํ„ฐ ๋ชจ๋ธ์„ ์—…๋ฐ์ดํŠธ ํ•  ์ˆ˜ ์žˆ๊ณ , ๊ทธ ์—…๋ฐ์ดํŠธ๋œ ๋ชจ๋ธ์„ ์˜์กดํ•˜๋Š” ๋‹ค๋ฅธ ๋ชจ๋ธ์ด ์—…๋ฐ์ดํŠธ๋˜๋Š”๋“ฑ... ๋์ด์—†์Œ
  • ์ƒํƒœ์— ๋ณ€ํ™”๋ฅผ ์ฃผ๊ณ ์ž ํ•˜๋ฉด ์–ด๋–ค์ผ์„ ํ•˜๋Š”์ง€, ์ฐธ๊ณ ํ•  ๋ฐ์ดํ„ฐ์˜ ์ •๋ณด๋ฅผ ํ†ตํ•ด ํ•˜๋‚˜์˜ ์•ก์…˜์„ ์ƒ์„ฑํ•œ๋‹ค.(ํ”ํžˆ action๊ณผ payload)
  • ์ƒ์„ฑ๋œ ์•ก์…˜์„ ๋””์ŠคํŒจ์ณ๋กœ ๋„˜๊ฒจ์ค€๋‹ค. dispatch({type : ...})
  • ๋””์ŠคํŒจ์ณ๋Š” ์•ก์…˜์„ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋ชจ๋“  ์Šคํ† ์–ด์—๋Œ€ํ•ด ์•Œ๊ณ ์žˆ๊ณ , ์•ก์…˜์ด ๋„˜์–ด์˜ค๊ฒŒ๋œ๋‹ค๋ฉด ์Šคํ† ์–ด์— ์•ก์…˜์„ ์ „๋‹ฌํ•ด์ค€๋‹ค.
  • ์Šคํ† ์–ด๋Š” ๋””์ŠคํŒจ์ณ๋กœ๋ถ€ํ„ฐ ๋ชจ๋“  ์•ก์…˜๋“ค์„ ์ „๋‹ฌ๋ฐ›๊ณ , ํƒ€์ž…์— ๋”ฐ๋ผ ์ˆ˜ํ–‰ํ• ์ง€ ํ•˜์ง€ ์•Š์„์ง€ ํ˜น์€ ์–ด๋–ค์‹์œผ๋กœ ์ฒ˜๋ฆฌํ• ์ง€ ๊ตฌ๋ถ„ํ•˜์—ฌ ์ƒํƒœ๊ฐ’์„ ์—…๋ฐ์ดํŠธํ•œ๋‹ค.
  • ๋ทฐ๋Š” ๊ทธ๋ƒฅ ์ „๋‹ฌ๋ฐ›์€ ์ƒํƒœ๊ฐ’์„ ๋ณด์—ฌ์ฃผ๊ธฐ๋งŒ ํ•œ๋‹ค.

virtual dom, ๋ฉ”๋ชจ์ด์ œ์ด์…˜๊ณผ diff

  • React๋Š” ๋ณ€๊ฒฝ๋œ ์š”์†Œ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๋ฐ˜์˜ํ•˜๊ธฐ ์œ„ํ•ด diff ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๊ทœ์น™์— ๋”ฐ๋ผ ์ƒˆ๋กœ์šด virtual dom๊ณผ ์ด์ „์˜ dom์„ ๋น„๊ต๋ฅผ ํ•˜๊ณ  ๋ณ€๊ฒฝ๋œ ๋ถ€๋ถ„๋งŒ์„ ํ†ตํ•ด ์‹ค์ œ DOM์— ์ตœ์†Œํ•œ์˜ ์ˆ˜์ •์„ ๊ฐ€ํ•จ
    1. ์—˜๋ฆฌ๋จผํŠธ์˜ ํƒ€์ž…์ด ์™„์ „ ๋‹ค๋ฅผ ๋•Œ, <div> -> <span>์—๋Š” ํ•ด๋‹น ์—˜๋ฆฌ๋จผํŠธ์™€ ์ž์‹๋“ค์„ ๋ชจ๋‘ ๋ฒ„๋ฆฌ๊ณ  ์ƒˆ๋กญ๊ฒŒ ์ƒ์„ฑํ•จ. ์ด ๋•Œ๋ฌธ์—, unmount, mount๊ฐ€ ๋‹ค์‹œ ํ˜ธ์ถœ๋˜๋Š” ๊ฒƒ
    2. ์—˜๋ฆฌ๋จผํŠธ์˜ ํƒ€์ž…์ด ๊ฐ™์„ ๋•Œ, ๋ณ€๊ฒฝ๋˜๋Š” prop๋งŒ ๋ฐ”๋€œ
    3. ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋™์ผํ•  ๋•Œ, ๋ณ€๊ฒฝ์ด ์žˆ๋Š” prop๋งŒ ์—…๋ฐ์ด๋“œ ๋จ. ์ด๋•Œ componentDidUpdate ํ˜ธ์ถœ๋จ (์ด๊ฑฐ๋Š” hook์—์„œ ์กฐ๊ธˆ ๋ฐ”๋€๊ฒƒ๊ฐ™์Œ)
    4. ์ž์‹์— ๋Œ€ํ•ด์„œ๋Š” key๋ฅผ ๊ธฐ์ค€์œผ๋กœ
  • memo๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„, ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์†์„ฑ์— ์˜ํ•ด ์ž์‹์ด rerendere๋˜์–ด ๋งŽ์€ ํšŸ์ˆ˜์˜ ๋ณ€ํ™”๊ฐ€ ์žˆ๋Š”๊ฒƒ ๊ฐ™์•„๋ณด์—ฌ๋„ ์œ„์™€๊ฐ™์€ diff ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ํ†ตํ•ด ์„ฑ๋Šฅ์—๋Š” ํฐ ๋ฌธ์ œ๊ฐ€ ์—†์Œ
  • ๋‹จ์ˆœํžˆ rerender๋ฅผ ์˜ˆ๋ฐฉํ•˜๋Š”๊ฒƒ์ด์ง€, DOM ๋ณ€๊ฒฝ๊ณผ ๊ด€๋ จ๋œ ์„ฑ๋Šฅ์—๋Š” ํฐ ์ฐจ์ด ์—†๋‹ค๊ณ  ํ•จ. ํ•˜์ง€๋งŒ, render๋ฅผ ํ•œ๋‹ค๋Š”๊ฒƒ์€ ์ด์ „ vdom๊ณผ render๋œ vdom์„ ๋น„๊ตํ•˜๊ธฐ ์œ„ํ•œ diff ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ํ•œ๋ฒˆ ๋” ์‹คํ–‰๋˜์–ด์•ผ ํ•จ

    ๋ฌผ๋ก , diff ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ๋งค์šฐ ํšจ์œจ์ ์ด๋ผ ํฐ ๋ฌธ์ œ๋Š” ์•ˆ๋˜์ง€๋งŒ, ์šฐ๋ฆฌ๊ฐ€ React ๋‚ด๋ถ€์—์„œ ์ž‘์„ฑํ•œ ๋กœ์ง๋“ค์ด ๋‹ค์‹œ ์‹คํ–‰๋œ๋‹ค๋Š”๊ฒƒ์€ ์–˜๊ธฐ๊ฐ€ ๋‹ค๋ฆ„

why parse block

document.write์™€ ๊ฐ™์ด html์„ ์ฆ‰์‹œ ์ƒ์„ฑํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์–ด์„œ(๊ทธ ์ˆœ์„œ๋ฅผ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด?)

Promise ์‹คํ–‰ํ•จ์ˆ˜์™€ try catch ๋ฒ”์œ„

new Promise์˜ ์ธ์ž๋กœ ์ „๋‹ฌ๋˜๋Š” ์ฝœ๋ฐฑํ•จ์ˆ˜๋Š” ํ•˜๋‚˜์˜ ์‹คํ–‰ํ•จ์ˆ˜๋กœ์„œ ํ”„๋กœ๋ฏธ์Šค์˜ ์‹คํ–‰, ๊ฑฐ์ ˆ์„ ์˜๋ฏธํ•˜๋Š” ๋‘๊ฐ€์ง€ ์ธ์ž๋ฅผ ๋ฐ›๋Š” ํ•จ์ˆ˜์ด๋‹ค. ์ด ์‹คํ–‰ํ•จ์ˆ˜๋Š” Promise ๊ฐ์ฒด๊ฐ€ ๋ฐ˜ํ™˜๋˜๊ธฐ ์ด์ „์— ๋จผ์ € ์‹คํ–‰์ด ๋œ๋‹ค.

๋Œ€๊ฒŒ, ์–ด๋– ํ•œ ๋น„๋™๊ธฐ๋กœ ์ง„ํ–‰๋œ ์ž‘์—…์ด ์™„๋ฃŒ๋˜๊ณ  ๋‚ด๋ถ€์—์„œ resolve ํ˜น์€ reject๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ดํ›„์˜ ๋กœ์ง์„ ๋งˆ์ดํฌ๋กœํƒœ์Šคํฌํ์— ๋„˜๊ฒจ ์ด๋ฒคํŠธ๋ฃจํ”„๋ฅผ ํ†ตํ•ด ์ฝœ์Šคํƒ์— ๋„˜๊ฒจ์ง€๋„๋ก ํ•œ๋‹ค.

await์ด ์—†๋‹ค๋ฉด try catch๋กœ ์žก์„ ์ˆ˜ ์—†๋Š” ์ด์œ ๋Š”, Promise ๋‚ด๋ถ€์—์„œ ๋ฐœ์ƒํ•œ throw๋Š” ํ•˜๋‚˜์˜ reject์™€ ๋™์ผํ•˜๊ฒŒ ์ž‘๋™๋˜์–ด Promise๊ฐ€ ๊ฑฐ์ ˆ๋˜์—ˆ๋‹ค๋Š” ๊ฒƒ์€, ํ•ด๋‹น ์—๋Ÿฌ๋Š” ์ด๋ฏธ ๋น„๋™๊ธฐ๋กœ์„œ try catch์˜ ์˜ํ–ฅ๊ถŒ์„ ๋ฒ—์–ด๋‚œ ์ƒํƒœ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

  • ์‹คํ–‰ํ•จ์ˆ˜ ์ฃผ์œ„์—๋Š” '์•”์‹œ์  try..catch'๊ฐ€ ์กด์žฌํ•˜๊ณ  ์žˆ๊ณ , ์Šค์Šค๋กœ ์—๋Ÿฌ๋ฅผ ์žก๊ณ , ์—๋Ÿฌ๋ฅผ ๊ฑฐ๋ถ€์ƒํƒœ์˜ ํ”„๋ผ๋ฏธ์Šค๋กœ ๋ณ€๊ฒฝ์‹œํ‚จ๋‹ค.

    (throw error -> reject)

  • ๋‹น์—ฐํžˆ Promise ๋‚ด๋ถ€์˜ setTimout ์•ˆ์—์„œ ๋ฐœ์ƒํ•œ ์—๋Ÿฌ๋Š” await ๋˜์–ด์žˆ๋Š” try catch๋ผ๋„ ์žก์ง€ ๋ชปํ•œ๋‹ค.

    setTimout์ด๋ผ๋Š” ๋ณ„๋„์˜ ๋น„๋™๊ธฐ ํ™˜๊ฒฝ์—์„œ ๋ฐœ์ƒํ•œ ์—๋Ÿฌ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋‚ด๋ถ€์— try catch๋กœ ๊ฐ์‹ธ๊ณ  catch ์‹œ Promise์˜ reject๋ฅผ ํ˜ธ์ถœํ•ด์ค˜์•ผ ํ•œ๋‹ค.

๋ Œ๋”๋ง ํŒŒ์ดํ”„๋ผ์ธ

๋ธŒ๋ผ์šฐ์ €๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ๊ณผ์ •๋“ค ํŒŒ์‹ฑ, ๋ Œ๋”ํŠธ๋ฆฌ ๊ตฌ์ถ•, ๋ ˆ์ด์•„์›ƒ ํ˜•์„ฑ, ํŽ˜์ธํŠธ, ์ปดํฌ์ง€ํŠธ๋‹จ๊ณ„ (์ปดํฌ์ง€ํ„ฐ ์Šค๋ ˆ๋“œ ์ž‘์—…)์„ ํ•˜๋‚˜์˜ ๋ Œ๋”๋ง ํŒŒ์ดํ”„๋ผ์ธ์ด๋ผ๊ณ  ํ•œ๋‹ค.

css-in-js

  1. ํด๋ž˜์Šค๋ช…์—๋Œ€ํ•œ ๊ณ ๋ฏผ์„ ์ค„์ผ ์ˆ˜ ์žˆ์Œ

  2. ํ˜„์žฌ์˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ™˜๊ฒฝ์— ์‰ฝ๊ฒŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ณ , ๋™์ ์œผ๋กœ ์ƒ์„ฑ๋œ ๊ฐ’์— ์ž์œ ๋กญ๊ฒŒ ์Šคํƒ€์ผ๋ง์„ ํ•  ์ˆ˜ ์žˆ์Œ

    • ๋™์ ์ธ ์Šคํƒ€์ผ์„ ์œ„ํ•ด ์–ด์ฉ”์ˆ˜ ์—†์ด ์ธ๋ผ์ธ์Šคํƒ€์ผ์„ ์‚ฌ์šฉํ•ด์•ผํ•˜๋Š” ์ƒํ™ฉ์ด ์ƒ๊ธด๋‹ค.

      ์—ฌ๊ธฐ์„œ ์ธ๋ผ์ธ์Šคํƒ€์ผ์ด ์™œ ๋ฌธ์ œ๊ฐ€ ์žˆ์„๊นŒ๋ผ๋Š” ์ƒ๊ฐ์„ ํ•ด๋ณด์•˜๋Š”๋ฐ, reflow๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ๋ ˆ์ด์•„์›ƒ ๊ณ„์‚ฐ์„ ๋‹ค์‹œ ํ•  ๋•Œ ์ธ๋ผ์ธ์œผ๋กœ ์ž‘์„ฑ๋˜๋Š” ์Šคํƒ€์ผ์€ ์—ฌ๋Ÿฌ ์Šคํƒ€์ผ์ด ํ•ฉ์ณ์ ธ์žˆ๋Š” ํด๋ž˜์Šค๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š”๊ฒƒ์œผ๋กœ ํ•œ๋ฒˆ์— ๋ถ€์—ฌํ•˜์—ฌ ์ผ๊ด„ ๊ณ„์‚ฐํ•˜๋Š”๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์Šคํƒ€์ผ์„ ํ•˜๋‚˜์”ฉ ํ•˜๋‚˜์”ฉ ๋ฐ˜์˜ํ•˜์—ฌ ๊ฐ๊ฐ ๊ณ„์‚ฐํ•˜๊ธฐ ๋•Œ๋ฌธ์— reflow์˜ ๋น„์šฉ์ด ๋น„๊ต์  ๋” ํฌ๋‹ค๋Š”๊ฒƒ ๊ฐ™๋‹ค.

  3. ๋ณ„๋„์˜ ์Šคํƒ€์ผ ํŒŒ์ผ์„ ๊ด€๋ฆฌํ•  ํ•„์š”๊ฐ€ ์—†์Œ

    • ๊ทผ๋ฐ ์ƒ๊ฐํ•ด๋ณด๋ฉด css-in-js๋ฅผ ์‚ฌ์šฉํ•˜๋”๋ผ๋„ ์Šคํƒ€์ผ์„ ๋ณ„๋„์˜ ํŒŒ์ผ๋กœ ๊ด€๋ฆฌํ•˜๋ฉฐ import ํ•ด ์‚ฌ์šฉํ•˜๊ธด ํ•จ..
  4. ๊ฒฐ๊ตญ ์˜์กดํ•˜๋Š” ์ƒˆ๋กœ์šด ๋ชจ๋“ˆ์ด ์ถ”๊ฐ€๋˜๋Š” ๊ฒƒ

  5. css-in-css๋ฅผ ํ†ตํ•ด ์™„์„ฑ๋˜์–ด์žˆ๋Š” ํด๋ž˜์Šค๋ฅผ ์ฆ‰์‹œ ๋ฐ˜์˜ํ•˜๋Š”๊ฒƒ๊ณผ, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ๋œ ์ƒˆ๋กœ์šด ์Šคํƒ€์ผ์„ ์ฝ๊ณ  ๊ณ„์‚ฐํ•˜์—ฌ ๋ฐ˜์˜ํ•˜๋Š”๊ฒƒ์— ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•จ

    • ์–ด์จŒ๋“  ๊ฒฐ๊ตญ ์Šคํƒ€์ผ์„ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ•œ๋ฒˆ ๋” ์ฝ๊ณ  ๊ณ„์‚ฐํ•˜๊ณ  ํ•ด์„ํ•ด์•ผ ํ•˜๋Š” ์ 

TDD - Test-driven development

๋ณ„๋‹ค๋ฅธ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์•„๋‹Œ ํ…Œ์ŠคํŠธ ๊ธฐ๋ฐ˜ ๊ฐœ๋ฐœ ๊ธฐ๋ฒ•์„ ์˜๋ฏธํ•œ๋‹ค. A๋ผ๋Š” ๊ธฐ๋Šฅ์„ ๊ฐœ๋ฐœํ•œ๋‹ค๊ณ  ํ•˜์˜€์„ ๋•Œ, ์‹ค์ œ ์ฝ”๋“œ์— ์ฆ‰์‹œ ๊ฐœ๋ฐœ์„ ํ•˜๋Š”๊ฒƒ์ด ์•„๋‹Œ ๋‹ค๋ฅธ ์ˆœ์„œ๋กœ ์ง„ํ–‰์ด ๋œ๋‹ค.

  1. ํ…Œ์ŠคํŠธ์ฝ”๋“œ์— A ๊ธฐ๋Šฅ์—๋Œ€ํ•œ ํ…Œ์ŠคํŠธ ์ž‘์„ฑ
  2. ํ…Œ์ŠคํŠธ ์‹คํ–‰
  3. ํ…Œ์ŠคํŠธ ์˜ค๋ฅ˜

    ์•„์ง ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์ž‘์„ฑ์ด ๋˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ๋‹น์—ฐํ•œ ์˜ค๋ฅ˜

  4. ๋”ฑ ํ…Œ์ŠคํŠธ๋ฅผ ํ†ต๊ณผํ•  ์ˆ˜์ค€์˜ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑ
  5. ํ…Œ์ŠคํŠธ ์‹คํ–‰
  6. ํ…Œ์ŠคํŠธ ์„ฑ๊ณต
  7. B ๊ธฐ๋Šฅ ๊ฐœ๋ฐœ์„ ์œ„ํ•ด 1๋ฒˆ๋ถ€ํ„ฐ ๋‹ค์‹œ ์ง„ํ–‰

์žฅ์ 

  1. ๊ตฌํ˜„ํ•˜๊ณ ์ž ํ•˜๋Š” ๊ธฐ๋Šฅ์˜ ํŠน์ง• ๋ฐ ํ•ต์‹ฌ์ ์ธ ๋ถ€๋ถ„๋งŒ์„ ๊ณ ๋ คํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋จ

    ํ…Œ์ŠคํŠธ๋ฅผ ์„ฑ๊ณต์‹œํ‚ค๊ธฐ ์œ„ํ•œ ์ตœ์†Œํ•œ์˜ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ฒŒ๋˜์–ด, ๋ถˆํ•„์š”ํ•œ ์ฝ”๋“œ๋“ค์€ ์ƒ์„ฑ๋˜์ง€ ์•Š์„๊ฒƒ ๊ฐ™์Œ.

  2. ์ง์ ‘ ์ด๋ฒคํŠธ๋ฅผ ํ˜ธ์ถœํ•˜๋Š”๋“ฑ์˜ ํ…Œ์ŠคํŠธ๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž ์ž…์žฅ์—์„œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋จ.

  3. ๊ฐœ๋ฐœ์„ ์™„๋ฃŒํ•œ ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด ํ…Œ์ŠคํŠธ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์ง€ ์•Š๋”๋ผ๋„ ๋กœ์ปฌํ™˜๊ฒฝ์—์„œ ์‹คํ–‰์‹œ์ผœ ์ง์ ‘ํ™•์ธํ•˜๋Š”ํ‹์˜ ํ…Œ์ŠคํŠธ๋Š” ํ•„์ˆ˜์ ์ด๋‹ค. ํ•˜์ง€๋งŒ, ํด๋ฆญ ๊ณผ ๊ฐ™์€ ์ด๋ฒคํŠธ๋“ฑ์„ ํ…Œ์ŠคํŠธํ•˜๊ณ ์ž ํ•  ๋•Œ, ๋‹ค์‹œ ํ…Œ์ŠคํŠธํ•˜๊ธฐ์œ„ํ•ด ์›๋ž˜๋Œ€๋กœ ๋Œ์•„์™€์•ผ ํ•˜๋Š” ๋“ฑ ๋ถ€์ˆ˜์ ์ธ ์ž‘์—…๋“ค์ด ์ƒ๊ธธ ์ˆ˜ ์žˆ๋Š”๋ฐ, ํ…Œ์ŠคํŠธ์ฝ”๋“œ๋Š” ๊ทธ๋Ÿด ํ•„์š”๊ฐ€ ์—†๋‹ค.

์ฃผ์˜์ 

์ด์ „์— ์—ฐ์Šตํ•ด๋ณธ๋‹ค๊ณ  ์ž‘์„ฑํ–ˆ๋˜ ํ…Œ์ŠคํŠธ์ฝ”๋“œ๋“ค์˜ ๋ช‡๋ช‡์€ ์ž˜๋ชป๋œ, ์‹คํŒจํ•œ ํ…Œ์ŠคํŠธ์ฝ”๋“œ์ธ๊ฒƒ ๊ฐ™์Œ.

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

    ์˜๋ฏธ์—†์ด ๋‹จ์œ„ํ…Œ์ŠคํŠธ์˜ ๊ทœ๋ชจ๊ฐ€ ์ปค์กŒ์—ˆ์Œ.

์•„๋ฌด๋ž˜๋„ 1๋ฒˆ๊ณผ ๊ฐ™์ด ๋ฆฌํŒฉํ† ๋ง์„ ํ•˜์˜€์„ ๋•Œ, ํ…Œ์ŠคํŠธ์ฝ”๋“œ๊ฐ€ ๊นจ์ง„๋‹ค๋Š”์ ์€ ์น˜๋ช…์ ์ด์˜€๊ณ  ์ด๋Š” ์–ด๋–ค ๊ธฐ๋Šฅ์„ ๋‹ด๋‹นํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ ์ž์ฒด๋ฅผ ํ…Œ์ŠคํŠธํ•˜๋Š”๊ฒƒ์ด ์•„๋‹Œ ๋‚ด๋ถ€์˜ ์ž‘์€ ๊ธฐ๋Šฅ๋“ค ์ž์ฒด๋ฅผ ํ…Œ์ŠคํŠธํ•˜์˜€๊ธฐ ๋•Œ๋ฌธ์ด์˜€๋˜๊ฒƒ ๊ฐ™๋‹ค.

ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ชฉํ‘œ๋ฅผ ์ƒ๊ฐํ•˜๊ณ  ๋‹ค์‹œ์ž‘์„ฑํ•ด๋ด์•ผํ• ๊ฒƒ ๊ฐ™๋‹ค. ์‚ฌ์šฉ์ž์˜ ์ž…์žฅ์—์„œ ์–ด๋– ํ•œ ํ–‰์œ„(์ด๋ฒคํŠธ)๋ฅผ ํ•˜์˜€์„ ๋•Œ ๊ฐœ๋ฐœ์ž๊ฐ€ ์˜๋„ํ•œ ๋Œ€๋กœ ์ž‘๋™๋˜๋Š”์ง€๋ฅผ ํ™•์ธํ•˜์ž

์‚ฌ์šฉ์ž์˜ ์ž…์žฅ์—์„œ ๋™์ ์ธ ์š”์†Œ๋งŒ(์‚ฌ์šฉ์ž์˜ ์ด๋ฒคํŠธ ํ˜น์€ ๋ฐ˜๋ณต์ ์ธ ๋ณ€ํ™” ๋“ฑ๋“ฑ)์„ ํ…Œ์ŠคํŠธํ•˜๊ณ , ์š”์†Œ์š”์†Œ์— ์ง‘์ค‘ํ•˜๊ธฐ๋ณด๋‹ค๋Š” ๊ฒฐ๊ณผ๊ฐ€ ์ฐธ์ธ์ง€๋ฅผ ํ™•์ธํ•˜๊ธฐ

import React from "react";
import { render } from "utils/test";
import TimerContainer from "./timerList";
import List from "components/list/list";

const initialData = [
  {
    name: "๋ฌด๋ฆ‰๋„์›",
    src: "/img/island/island_04.png",
    time: ["00:00", "06:00", "12:00", "18:00"],
    endTime: "18:00",
    lv: 400,
    position: "๋Œ€ํ•ญํ•ด",
    contType: "ISLAND",
  },
  {
    name: "๊ธฐ์—๋‚˜",
    contType: "CO_OCEAN",
    lv: "-",
    src: "/img/ocean/ocean_01.png",
    position: ["์•„๋ฅด๋ฐํƒ€์ธ", "๋ฒ ๋ฅธ", "์• ๋‹ˆ์ธ "],
    endPosition: "์• ๋‹ˆ์ธ ",
    time: ["00:00", "12:00", "18:00"],
    endTime: "18:00",
  },
];

const expectData = [
  {
    name: "๋ฌด๋ฆ‰๋„์›",
    src: "/img/island/island_04.png",
    time: ["18:00"],
    endTime: "18:00",
    lv: 400,
    position: "๋Œ€ํ•ญํ•ด",
    contType: "ISLAND",
  },
  {
    name: "๊ธฐ์—๋‚˜",
    contType: "CO_OCEAN",
    lv: "-",
    src: "/img/ocean/ocean_01.png",
    position: ["์• ๋‹ˆ์ธ "],
    endPosition: "์• ๋‹ˆ์ธ ",
    time: ["18:00"],
    endTime: "18:00",
  },
];

// ํ˜ธ์ด์ŠคํŒ…๋จ
jest.mock("components/list/list.tsx", () => (props: any) => (
  <div data-testid={JSON.stringify(props.data)} />
));

describe("TimerContainer", () => {
  afterEach(() => {
    jest.clearAllMocks();
    jest.restoreAllMocks();
  });

  it("์ปจํ…์ธ ์—์„œ ์ข…๋ฃŒ๋˜์ง€ ์•Š์€ ์‹œ๊ฐ„๋Œ€๋งŒ ์œ ์ง€ ๋ฐ ๋น ๋ฅธ์ˆœ์œผ๋กœ ์ •๋ ฌ", () => {
    const notification = jest.fn();
    // mock ํ•จ์ˆ˜๊ฐ€ ๋˜๊ธฐ ์ „์— date ์บ์‹ฑ
    const mockDateObject = new Date(2021, 1, 1, 17);
    jest
      .spyOn(global, "Date")
      .mockImplementation(() => (mockDateObject as unknown) as string);

    const { getByTestId } = render(
      <TimerContainer data={initialData} notification={notification} />
    );

    expect(getByTestId(JSON.stringify(expectData))).toBeTruthy();
  });

  it("clear", () => {});
});

๋Š˜ ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ํ…Œ์ŠคํŠธ ๋Œ€์ƒ ๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์ปดํฌ๋„ŒํŠธ, ํ˜น์€ ๋ณ€ํ™”๊ฐ€ ์žฆ์€ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์†Œ๋“œ๋“ค์€ mockingํ•˜์˜€๋‹ค.

ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๊ณ , ์‚ฌ์šฉ์ž์˜ ์‹œ์„ ์—์„œ ๊ฒฐ๊ณผ๋ฌผ์ด ์›ํ•˜๋Š” ๊ฐ’๊ณผ ๋™์ผํ•œ์ง€ true ์ฐธ์ธ์ง€๋งŒ์„ ํ™•์ธํ•˜์˜€๋‹ค.

React์—์„œ ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ ํŠน์ง•

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

    ์™ธ๋ถ€์˜ ๋ณ€ํ•˜์ง€ ์•Š๋Š” ์ƒ์ˆ˜๋ฅผ ์ฐธ์กฐํ•˜์—ฌ ์ƒˆ๋กœ์šด ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š”๊ฒƒ์€ ๊ดœ์ฐฎ๋‹ค๋Š”๊ฒƒ ๊ฐ™์Œ

    • ์ด ์ ์— ์žˆ์–ด์„œ, ๋‹ค์†Œ ํ˜ผ๋™๋˜๋Š”์ ์ด ์žˆ๋Š”๋ฐ React ์—์„œ๋Š” useEffect์™€ ๊ฐ™์ด ๊ณต๋ฌธ์—์„œ ๋Œ€๋†“๊ณ  ์„ค๋ช…ํ•˜๊ธฐ๋ฅผ ์‚ฌ์ด๋“œ์ดํŽ™ํŠธ๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ hook์ด๋ผ๊ณ  ์„ค๋ช…ํ•˜๊ณ  ์žˆ๊ณ , ํ•ด๋‹น ํ•จ์ˆ˜ ์™ธ๋ถ€์˜ ์ปจํ…์ŠคํŠธ์— ์ ‘๊ทผํ•˜๋Š” ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. ์˜ค๋กœ์ง€ return๋งŒ ์ˆ˜ํ–‰ํ•˜๋Š” ์ˆœ์ˆ˜ํ•จ์ˆ˜์™€ ๋‹ค๋ฅด๊ฒŒ useEffect๋ฅผ ํ†ตํ•ด DOM์กฐ์ž‘์„ ํ•˜๊ฑฐ๋‚˜ ์™ธ๋ถ€ ์ปจํ…์ŠคํŠธ์— ์ ‘๊ทผํ•˜๋Š”๋“ฑ์˜ ํ–‰์œ„๊ฐ€ ๊ฐ€๋Šฅํ•ด์กŒ๋‹ค..

    ์—ฌ๊ธฐ์„œ React์˜ ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ๋Š” ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด ์•„๋‹ˆ๋ž€๊ฒƒ์ด ๋ณด์—ฌ์ง

  4. ๋‚ด๋ถ€์˜ ์ƒํƒœ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์—†๋‹ค.
    • ํ•˜๋‚˜์˜ ๋ชฉ์ ์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ์—ฌ๋Ÿฌ๊ฐœ์˜ ์ƒํƒœ(์†์„ฑ), ๋ฉ”์†Œ๋“œ๋“ค์„ ํ•˜๋‚˜๋กœ ์บก์Šํ™” ํ•˜์—ฌ ์ƒํƒœ๋ฅผ ๋ณ€ํ™”์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” ๊ฐ์ฒด์ง€ํ–ฅ๊ณผ ๋‹ค๋ฅด๊ฒŒ ํ•จ์ˆ˜ํ˜•์€ ํ•จ์ˆ˜ ๋‚ด๋ถ€์— ์ƒํƒœ๋ฅผ ๊ฐ€์งˆ์ˆ˜ ์—†๊ณ , ์™ธ๋ถ€์˜ ์ƒํƒœ์— ๋ณ€ํ™”๋ฅผ ์ฃผ์–ด์„œ๋„ ์•ˆ๋œ๋‹ค. ๋‚ด๋ถ€์˜ ์ƒํƒœ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์—†๋‹ค๋Š”๊ฒƒ์ด ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๊ธฐ ์œ„ํ•œ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ ๋งˆ๋‹ค ์ƒํƒœ๊ฐ€ ์ดˆ๊ธฐํ™”๋˜๋Š” ๋•Œ๋ฌธ์ด ์•„๋‹๊นŒ ์‹ถ๋‹ค.
    • ์ด ๋˜ํ•œ ์˜๋ฌธ์ธ ์ ์ด, useState๋ฅผ ํ†ตํ•ด ๊ณ ์œ ํ•œ ์ƒํƒœ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค. hook์˜ ๋™์ž‘ ์›๋ฆฌ๋ฅผ ๊ณ ๋ คํ•ด๋ณด์•˜์„ ๋•Œ, ํ•จ์ˆ˜ ์™ธ๋ถ€์˜ ์ปจํ…์ŠคํŠธ์—์„œ ๊ณต๋ฌธ์—์„œ ์†Œ๊ฐœ๋œ ๊ฐ์ฒด ์ž๋ฃŒ๊ตฌ์กฐ์—์„œ ์ˆœ์„œ๋Œ€๋กœ ์ €์žฅ๋˜์–ด์žˆ๋Š” ์ƒํƒœ๊ฐ’์„ ์—…๋ฐ์ดํŠธํ•˜๋Š”์ ์ด ์ˆœ์ˆ˜ํ•จ์ˆ˜์˜ ์‚ฌ์ด๋“œ์ดํŽ™ํŠธ๋‚˜, ์ƒํƒœ๊ฐ’์„ ๊ฐ€์งˆ ์ˆ˜ ์—†๋‹ค๋Š” ํŠน์ง•๊ณผ๋Š” ๋‹ค๋ฅธ ๋ชจ์Šต์„ ๋ณด์—ฌ์คŒ.

requestAnimationFrame

๋Œ€๋ถ€๋ถ„์˜ ๋””์Šคํ”Œ๋ ˆ์ด๋Š” ์ดˆ๋‹น 60๋ฒˆ (์ด๋ฅผ 60fps) ํ™”๋ฉด์„ ์ƒˆ๋กœ๊ณ ์นœ๋‹ค๊ณ  ํ•œ๋‹ค.

๋ธŒ๋ผ์šฐ์ €๋˜ํ•œ ๋‹ค๋ฅด์ง€ ์•Š๋‹ค๊ณ  ํ•˜๋Š”๋ฐ ์ด ํšŸ์ˆ˜๊ฐ€ ์‚ฌ์šฉ์ž์—๊ฒŒ ์žˆ์–ด ์ž์—ฐ์Šค๋Ÿฌ์šด ํ™”๋ฉด์„ ๋ณด์—ฌ์ฃผ๋Š” ๋ฐฉ๋ฒ•์ด๋ผ๊ณ  ํ•œ๋‹ค.

ํ•˜์ง€๋งŒ, ๋งŒ์•ฝ ์š”์†Œ์— ํ• ๋‹นํ•œ ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ๊ทธ 1/60์ดˆ ๋‚ด์— ๋ชจ๋‘ ํ•ด๊ฒฐ๋˜์ง€ ์•Š์œผ๋ฉด ํŽ˜์ด์ง€๊ฐ€ ํ˜น์€ ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ๋ฒ„๋ฒ…๊ฑฐ๋ฆฌ๋Š”๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์—ฌ์ง„๋‹ค.

๋ Œ๋”๋ง์ž‘์—…๊ณผ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ์‹คํ–‰์€ ๋ชจ๋‘ ๋ Œ๋”๋งํ”„๋กœ์„ธ์Šค์˜ ๋ฉ”์ธ์Šค๋ ˆ๋“œ์—์„œ ์ž‘๋™๋˜๊ธฐ ๋•Œ๋ฌธ์—, ๊ธด ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฌ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ์‹คํ–‰๋œ๋‹ค๋ฉด ์œ„์˜ ์ดˆ๋‹น 60๋ฒˆ์˜ ๊ฒŒ์‚ฐ์ด ์ค‘๋‹จ๋  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค.

requestAnimationFrame์€ ์ด๋Ÿฐ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ž‘์—…์„ ์ž‘์€ ๋ฉ์–ด๋ฆฌ๋กœ ๋‚˜๋ˆ„์–ด์„œ ๋ชจ๋“  ํ”„๋ ˆ์ž„์— ์‹คํ–‰๋˜๋„๋ก ๋„์™€์ค€๋‹ค๊ณ  ํ•œ๋‹ค.

60fps๋ฅผ ์œ ์ง€ํ•˜๋Š” ํ™”๋ฉด์˜ ์ƒˆ๋กœ๊ณ ์นจ ์ž‘์—…์ด 1/60์ดˆ ์ด์ƒ์˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ž‘์—…์— ์ค‘๋‹จ๋˜์–ด ๋Œ€๊ธฐํ•˜์ง€ ์•Š๋„๋ก ๋‚˜๋ˆ„๋Š”๊ฒƒ ๊ฐ™์Œ

setInterval์ด๋‚˜ setTimeout๊ณผ ๊ฐ™์€ ๋ฐ˜๋ณต์ ์ธ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์‚ฌ์šฉํ•˜๊ณ ์ž ํ•  ๋•Œ ์ง„ํ–‰๋˜๋Š” ์ฝœ๋ฐฑํ•จ์ˆ˜๊ฐ€ ํ”„๋ ˆ์ž„์˜ ์ข…๋ฃŒ์‹œ์— ์‹œ์ž‘๋  ์ˆ˜ ์žˆ์–ด์„œ ๋ˆ„๋ฝ๋  ์ˆ˜ ๋„ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค.

requesetAnimationFrame์„ ์‚ฌ์šฉํ•˜๋ฉด ํ”„๋ ˆ์ž„ ์‹œ์ž‘ ์‹œ์— ์‹คํ–‰๋˜๋„๋ก ๋ณด์žฅํ•ด์ค€๋‹ค๊ณ  ํ•จ.

requesetAnimationFrame ๋˜ํ•œ ๋น„๋™๊ธฐ๋กœ ์ž‘์—…์ด ์ฒ˜๋ฆฌ๋˜์ง€๋งŒ, ๋งคํฌ๋กœํƒœ์Šคํฌ ํ๊ฐ€ ์•„๋‹Œ ๋ณ„๋„์˜ ์• ๋‹ˆ๋ฉ”์ด์…˜ ํ์— ์ €์žฅ๋˜์–ด ์Šคํฌ๋ฆฝํŠธ์˜ ์ง„ํ–‰์ƒํ™ฉ์— ์˜ํ–ฅ์„ ๋ฐ›์ง€์•Š๋Š”๊ฒƒ์ด ํ•ต์‹ฌ์ธ๊ฒƒ ๊ฐ™๋‹ค.

Vue, React

Vue์˜ ํŠน์ง•์„ ๋น„๊ต์  ์ž˜ ์•Œ๊ณ ์žˆ๋Š” React์™€ ๋น„๊ตํ•˜์—ฌ ์ƒ๊ฐํ•ด๋ด„

MVVM

Vue๋Š” MVVM๋””์ž์ธ ํŒจํ„ด์„ ๊ฐ–๊ณ ์žˆ๊ณ , Model, View, ViewModel์˜ ์•ฝ์–ด๋ผ๊ณ  ํ•จ. Model๊ณผ View๋Š” ๋‹ค๋ฅธ ๋””์ž์ธํŒจํ„ด๊ณผ ๋™์ผํ•˜๊ณ , ViewModel์˜ ๊ฒฝ์šฐ Vue Instance๋กœ ๊ตฌ์„ฑ๋˜๋Š” View์—์„œ ์‚ฌ์šฉ๋˜๋Š” Model์˜ ๋ฐ์ดํ„ฐ๋“ค์„ View์— ๋„˜๊ฒจ์ฃผ๋Š” ์—ญํ• ์„ ํ•˜๊ณ , View์™€ ๊ด€๋ จ๋œ ๋กœ์ง๋“ค์„ ๊ด€๋ฆฌํ•˜๊ธฐ๋„ ํ•จ.

Controller๊ฐ™์€๊ฑด๊ฐ€?

Vue์—์„œ template์ด view Vue instance์—์„œ data๊ฐ€ model, View instance์˜ ๋‚˜๋จธ์ง€๊ฐ€ ViewModel์ธ๋“ฏ ํ•จ.

useEffect, watch

React์˜ hook์ค‘ useEffect์™€ ๊ฐ™์ด ํŠน์ • ์ƒํƒœ์˜ ๋ณ€ํ™”๋ฅผ ๊ฐ์ง€ํ•˜๊ณ  ์ดํ›„์˜ ์‚ฌ์ด๋“œ์ดํŽ™ํŠธ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๋Š”๊ฒƒ์€ watch๊ฐ€ ๋Œ€์‹ ํ•  ์ˆ˜ ์žˆ์„๊ฒƒ ๊ฐ™์Œ. ๋‹ค๋งŒ ๋ฐฐ์—ดํ˜•์‹์ด ์•„๋‹Œ ๋‹จ์ผ ์ƒํƒœ๊ฐ’์„ key๋กœ ํ•˜์—ฌ ์ž‘๋™๋˜๋Š”๋“ฏ ํ•จ.

JSX

React์—์„œ๋Š” HTML๊ณผ JS๊ฐ€ ํ•จ๊ป˜ ์ž‘์„ฑ๋˜์–ด ํ•˜๋‚˜์˜ createElement์˜ ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•˜๋Š” JSX๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ, Vue๋Š” ํ•˜๋‚˜์˜ ํŒŒ์ผ์— HTML, CSS, JS๊ฐ€ ๋ชจ๋‘ ์‚ฌ์šฉ๋จ.

template, css, script

ReactDOM.render, vue mount

Vue Cli๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ๋  ๊ฒฝ์šฐ, new Vue๋กœ ํ•˜๋‚˜์˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ์ƒ์„ฑ๋˜๊ณ  ๊ทธ ๋‚ด๋ถ€๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ํ˜•์‹์ธ๋“ฏ ํ•จ. ์ดํ›„์˜ ์ปดํฌ๋„ŒํŠธ๋‹จ์œ„๋Š” export๋˜๋Š” ๋‹จ์ผ ๊ฐ์ฒด๋กœ ์ง„ํ–‰

๋‹จ ํ•˜๋‚˜์˜ ์ธ์Šคํ„ด์Šค

new Vue({
  render: h => h(App),
}).$mount('#app')
ReactDOM.render(
  <App />
  document.getElementById('root')
)

React์˜ ReactDOM.render๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ ์ž‘๋™๋˜๋Š”๋“ฏ ํ•จ.

slot, children

React์˜ ๊ฒฝ์šฐ ์ž์‹ ์š”์†Œ๋“ค์„ ๊ทธ๋Œ€๋กœ ์ž‘์„ฑํ•ด, ์ž์‹์š”์†Œ๋“ค์„ ๊ฐ–๋Š” ์ปดํฌ๋„ŒํŠธ์˜ children์†์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ์œ ์—ฐํ•œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Œ Vue์˜ ๊ฒฝ์šฐ, slot์ด๋ผ๋Š” ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŠน์ • slot์— name์†์„ฑ์„ ๋ถ€์—ฌํ•˜์—ฌ 1๋Œ€1 ๋งค์นญ์„ ํ•ด์ค˜์„œ ์œ ์—ฐํ•œ ์ปดํฌ๋„ŒํŠธ๋กœ ๋งŒ๋“œ๋Š”๊ฒƒ ๊ฐ™์Œ.

<template #main>
  <p>๋ฉ”์ธ ์ปจํ…์ธ </p>
  <p>๋ฉ”์ธ ์ปจํ…์ธ </p>
  <p>๋ฉ”์ธ ์ปจํ…์ธ </p>
</template>
  components: {
    "my-component": {
      template: `
        <slot name="main">๋ฉ”์ธ์ปจํ…์ธ 1์ด ์—†์Šต๋‹ˆ๋‹ค</slot>
      `,
    },
  },

๊ดœ์ฐฎ์€ ์ ์€, slot์— ๋งค์นญ๋˜๋Š” ์š”์†Œ๊ฐ€ ์—†๋‹ค๋ฉด ๋Œ€์ฒด๋˜๋Š” ๋‚ด์šฉ์„ ์ง€์ •ํ•ด์ค„ ์ˆ˜ ์žˆ์—ˆ์Œ.

๋จ„์•ฝ, pํƒœ๊ทธ์˜ ๋ฉ”์ธ์ปจํ…์ธ  3๊ฐœ๊ฐ€ ์—†๋‹ค๋ฉด ๋ฉ”์ธ์ปจํ…์ธ 1์ด ์—†์Šต๋‹ˆ๋‹ค๊ฐ€ ๋ Œ๋”๋จ

<div id="slot3">
  <my-list :items="arr">
    <template #item="{item : {id, text}}">
      <li>{{id}}, {{text}}</li>
    </template>
  </my-list>
</div>
new Vue({
  el: '#slot3',
  data: {
    arr: [
      { id: 1, text: 'banana' },
      { id: 2, text: 'apple' },
      { id: 3, text: 'grapes' },
    ],
  },
  components: {
    'my-list': {
      props: ['items'],
      template: `
        <ul>
          <slot
            name="item"
            v-for="item in items"
            :item="item"
          >
          </slot>
        </ul>
      `,
    },
  },
})

vue๋Š” v-for๋””๋ ‰ํ‹ฐ๋ธŒ๋ฅผ ํ†ตํ•ด React์—์„œ์˜ .map์ฒ˜๋Ÿผ ์—ฌ๋Ÿฌ๊ฐœ์˜ ์ž์‹์š”์†Œ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด ๋–„์˜ ์ƒํ™ฉ์—์„œ๋„ v-slot์„ ์‚ฌ์šฉํ•˜์—ฌ ์œ ์—ฐํ•˜๊ฒŒ ์„ค๊ณ„ํ•˜๋„๋ก ๋„์›€์„ ์ฃผ์—ˆ์Œ. ํŠน์ดํ–ˆ๋˜์ ์€, ๋ฐฐ์—ด์„ ์†์„ฑ์œผ๋กœ ์ „๋‹ฌํ•œ๊ฒƒ๊นŒ์ง€๋Š” ๋‹น์—ฐํ•œ๋ฐ, ๋ฐ˜๋ณตํ•˜์—ฌ ์กฐํšŒํ•˜๋Š” ๋ฐฐ์—ด ๋‚ด ๋‹จ์ผ ์š”์†Œ๋ฅผ ๋งˆ์น˜ ์ƒ์œ„์ปดํฌ๋„ŒํŠธ์˜ slot์— ๋งค์นญ๋œ ์š”์†Œ๋กœ ์ „๋‹ฌํ•ด์ฃผ๋Š” ๋Š๋‚Œ์ฒ˜๋Ÿผ ์ž‘๋™๋จ.

์•„๋งˆ template ํƒœ๊ทธ์˜ ๋‚ด์šฉ์ด ๋งค์นญ๋œ slot๊ณผ ๋Œ€์ฒด๋˜๋ฉด์„œ ์†์„ฑ์„ ๊ณต์œ ํ•œ๋‹ค๋Š”๊ฒŒ ์•„๋‹๊นŒ ๋ผ๋Š” ์ƒ๊ฐ?

์žก๋™์‚ฌ๋‹ˆ

  • ํ‘œํ˜„์‹(expression)์€ ๋ณ€์ˆ˜ํ• ๋‹น, * +์™€ ๊ฐ™์€ ์ˆ˜์‹๋“ค์„ ์˜๋ฏธํ•œ๋‹ค.
  • ๊ตฌ๋ฌธ(statement)์€ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ์ตœ์†Œ์˜ ๋…๋ฆฝ์ ์ธ ์กฐ๊ฐ์„ ์˜๋ฏธํ•œ๋‹ค.
  • ์ปดํ“จํ„ฐ๊ฐ€ ์‹คํ–‰์„ ํ•˜๋Š”๊ฒƒ์€ ๊ตฌ๋ฌธ ๋‹จ์ˆœ ํ• ๋‹น๊ณผ๊ฐ™์€๊ฒƒ์€ ํ‘œํ˜„์‹์ธ๋“ฏ ํ•จ. ๋”ฐ๋ผ์„œ ๋ชจ๋“  ํ‘œํ˜„์‹๋“ค์€ ๊ตฌ๋ฌธ์— ํฌํ•จ๋จ
  • es6 -> es5์™€ ๊ฐ™์ด ํ•˜๋‚˜์˜ ์–ธ์–ด๋ฅผ ๋‹ค๋ฅธ ์ˆ˜์ค€์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š”๊ฒƒ์„ ํŠธ๋žœ์ŠคํŒŒ์ผ
  • ์•„์˜ˆ ๋‹ค๋ฅธ ์–ธ์–ด๋กœ ๋ณ€ํ™˜ํ•˜๋Š”๊ฒƒ์„ ์ปดํŒŒ์ผ
  • 100~500 ์ƒํƒœ์ฝ”๋“œ
  • type alias vs interface

    ํฐ ์ฐจ์ด๋กœ interface๋Š” ๋™์ผํ•œ ํ‚ค์›Œ๋“œ๋กœ ๋‘๋ฒˆ ์„ ์–ธ๋˜์—ˆ์„ ๋•Œ, ๋ณ‘ํ•ฉ์„ ํ•˜์ง€๋งŒ type alias๋Š” ๊ทธ๋ ‡์ง€ ์•Š์Œ. ๋˜๋„๋ก interface์‚ฌ์šฉ์„ ๊ถŒ์žฅํ•˜๊ณ  ๋ฐฐ์—ด๊ณผ ๊ฐ™์€ ๊ตฌ์กฐ์˜ ๊ฐฏ์ˆ˜์™€ ์œ„์น˜์— ๋งž๋Š” ํƒ€์ž…์„ ๊ณ ์ •ํ•˜๋Š” ํŠœํ”Œ๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ์— type alias๋ฅผ ์‚ฌ์šฉ

  • http header

About

๐Ÿ“Œ ๊ฐœ์ธ ๊ธฐ์ˆ ๋ธ”๋กœ๊ทธ

Topics

Resources

License

Security policy

Stars

Watchers

Forks