Redux: ์‹ค์ œ ์‚ฌ๋ก€(CRUD, ๊ณ ๊ธ‰ ํŒจํ„ด ๋“ฑ ํฌํ•จ)

์— ๋งŒ๋“  2016๋…„ 02์›” 02์ผ  ยท  45์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: reduxjs/redux

์›๋ž˜ Dan์˜ ํŠธ์œ—์—์„œ ์˜๊ฐ์„ ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค.

TL;DR - ์ด ๋ฆฌํฌ์ง€ํ† ๋ฆฌ ์™€ ์‹ถ์Šต๋‹ˆ๋‹ค . ๊ณผ์ •์˜ ํ…์ŠคํŠธ ๋ฐ ์ฝ”๋“œ๋Š” ์˜คํ”ˆ ์†Œ์Šค์ด๋ฏ€๋กœ(๊ฐ๊ฐ CC ๋ฐ MIT๋กœ ์ƒ๊ฐํ•˜๊ณ  ์žˆ์Œ) ์ด ์ง€์‹์€ ์œ ๋ฃŒํ™” ๋’ค์— ๊ณ ์ •๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํ’๋ถ€ํ•œ ์˜ˆ์ œ๋ฅผ ์ž‘์„ฑํ•˜๋ ค๋ฉด ๋งŽ์€ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฌ๊ณ  ์“ฐ๊ธฐ ๊ฐ€๋Šฅํ•œ API ์—”๋“œํฌ์ธํŠธ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค(๋ฌด์—‡๋ณด๋‹ค๋„). ๊ทธ๋Ÿฌ๋‚˜ ๊ฐœ๋ฐœ์ž๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์ถ•ํ•  ๋•Œ ์ข‹์€ ์ฐธ์กฐ ํ”„๋ ˆ์ž„์„ ๊ฐ–๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด ์ •๋ง ์ค‘์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋˜ํ•œ Redux์— ๋Œ€ํ•œ ์ด๋Ÿฌํ•œ ์ข…๋ฅ˜์˜ ์ž…๋ฌธ์„œ๋ฅผ ์š”์ฒญํ•˜๋Š” ์ˆ˜๋งŽ์€ ์‚ฌ์šฉ์ž๊ฐ€ ์žˆ์œผ๋ฉฐ, ๋”ฐ๋ผ์„œ ์šฐ๋ฆฌ๋Š” ๊ทธ ์ œ์ž‘์— ์ž๊ธˆ์„ ์ง€์›ํ•˜๊ฒŒ ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค.

์ด์— ๋Œ€ํ•œ ์•„์ด๋””์–ด์™€ ์ž‘์—…์— ๊ด€์‹ฌ์ด ์žˆ๋Š” ๊ฒฝ์šฐ lmk๋ฅผ ๋“ฃ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค!

examples

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

๋‹ค์Œ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ณต์‹ CRUD ์˜ˆ์ œ๋ฅผ ๊ฐ–๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

  • ์ž…์ฆ
  • ํ‘œ์ค€ํ™”
  • ๋‚™๊ด€์  ์—…๋ฐ์ดํŠธ
  • ๋กœ์ปฌ ํŽธ์ง‘
  • ์—”ํ‹ฐํ‹ฐ ๊ด€๊ณ„
  • ์ชฝ์ˆ˜ ๋งค๊ธฐ๊ธฐ

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

์ด๊ฒŒ ๋ง์ด ๋ผ?

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

๋‹ค์Œ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ณต์‹ CRUD ์˜ˆ์ œ๋ฅผ ๊ฐ–๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

  • ์ž…์ฆ
  • ํ‘œ์ค€ํ™”
  • ๋‚™๊ด€์  ์—…๋ฐ์ดํŠธ
  • ๋กœ์ปฌ ํŽธ์ง‘
  • ์—”ํ‹ฐํ‹ฐ ๊ด€๊ณ„
  • ์ชฝ์ˆ˜ ๋งค๊ธฐ๊ธฐ

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

์ด๊ฒŒ ๋ง์ด ๋ผ?

๋˜ํ•œ ์‚ฌ๋žŒ๋“ค์ด API์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์œ„์น˜๋ฅผ ์•Œ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

@gaearon ๋‚ด์šฉ/์ฝ”๋“œ๋Š” ์˜คํ”ˆ ์†Œ์Šค์ด๋ฏ€๋กœ ๋ฌธ์ œ ์—†์Šต๋‹ˆ๋‹ค. ํŽ˜์ด์ง€ ์–ด๋”˜๊ฐ€์— ๋‹ค์‹œ ๋งํฌ๋ฅผ ์š”์ฒญํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

@sebastiandeutsch ์ด์— ๋Œ€ํ•ด ์กฐ๊ธˆ ๋” ์ž์„ธํžˆ

์–ผ๋งˆ ์ „ ๋‚˜๋Š” react+redux, monogram ๋ฐ eccrypto๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋น„๋ฐ€๋ฒˆํ˜ธ ๊ด€๋ฆฌ์ž๋ฅผ ์ž‘์„ฑํ•˜๋ฉด์„œ ๋†€๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ECIES๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์•”ํ˜ธํ™”๋˜์ง€ ์•Š์€ ํ˜•์‹์œผ๋กœ ์œ ์„ ์„ ํ†ตํ•ด ์ „์†กํ•˜์ง€ ์•Š๊ณ  ์•”ํ˜ธ๋ฅผ ์ €์žฅํ•˜๊ณ  ๋ชจ๋‘ ๊ณต์œ ํ•˜์‹ญ์‹œ์˜ค. ์ •๋ง ๋๋‚ด๊ธฐ์—๋Š” ์ด๋ฅด์ง€ ๋ชปํ–ˆ์ง€๋งŒ https://github.com/rackt/redux/issues/1353#issuecomment -178760036์˜ ๋ชจ๋“  ํ•ญ๋ชฉ์„ ์•„์ฃผ ์ž˜ ๋งŒ์กฑ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํฅ๋ฏธ๋กญ๊ฒŒ ๋“ค๋ฆฝ๋‹ˆ๊นŒ?

@vkarpov15

์ด๊ฒƒ์€ ๋งค์šฐ ํฅ๋ฏธ๋กญ๊ฒŒ ๋“ค๋ฆฌ์ง€๋งŒ ๋„ˆ๋ฌด ๋„๋ฉ”์ธ์— ๊ตญํ•œ๋œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ๋žŒ๋“ค์€ ์ผ๋ฐ˜์ ์ธ CRUD ์˜ˆ์ œ(์–ด๋Š ํ•ญ๋ชฉ์ด๋“  ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ํŽธ์ง‘ ๊ฐ€๋Šฅํ•œ ํ•ญ๋ชฉ ๋ชฉ๋ก ๋“ฑ)๋ฅผ ๋ณด๊ณ  ์‹ถ์–ดํ•  ๊ฒƒ์ด๋ฉฐ ์•”ํ˜ธํ™” ์ดˆ์ ์œผ๋กœ ์ธํ•ด ์˜ˆ์ œ์— ์ ‘๊ทผํ•˜๊ธฐ ์–ด๋ ค์›Œ์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ €๋Š” ๋‚™๊ด€์ ์ธ ์—…๋ฐ์ดํŠธ๋กœ ๋กœ์ปฌ/์˜คํ”„๋ผ์ธ ํŽธ์ง‘์— ๋งŽ์€ ๊ด€์‹ฌ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์‹œ๊ฐ„์ด ์žˆ์ง€๋งŒ redux ์•ฑ์— ๋Œ€ํ•œ ๊ฒฝํ—˜์ด ๋งŽ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ณต์žกํ•œ ๊ธฐ๋ณธ ์•ฑ๋งŒ ๊ฐ€์ง€๊ณ  ์žˆ์ง€๋งŒ ๊ฑฐ์˜ ์™„์ „ํžˆ ๋กœ์ปฌ/์˜คํ”„๋ผ์ธ์ž…๋‹ˆ๋‹ค.
๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์ž‘์—…ํ•˜๊ณ  ์ ์ง„์ ์œผ๋กœ ๋…ผ์˜ํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”?
๋˜ํ•œ "๋ชจ๋“ˆ์‹" ์•ฑ์€ ์–ด๋–ป์Šต๋‹ˆ๊นŒ?
๋ช‡ ๊ฐ€์ง€ ์•„์ด๋””์–ด๋ฅผ ๊ณต์œ ํ•˜๊ธฐ ์œ„ํ•ด ์ €๋Š” ์˜คํ”„๋ผ์ธ ์ฒซ ๋ฒˆ์งธ ์•ฑ์ด ์–ด๋–ป๊ฒŒ ๋˜์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ๋ช‡ ๊ฐ€์ง€ ์•„์ด๋””์–ด๋ฅผ ์ผ์Šต๋‹ˆ๋‹ค. ์‹œ๊ฐ„์ด ์žˆ๋‹ค๋ฉด ํ•œ ๋ฒˆ ์‚ฌ์šฉํ•ด ๋ณด์„ธ์š”! :)

https://github.com/jsforum/jsforum/issues/7

๋ฌธ์ œ๊ฐ€ ์–ผ๋งˆ๋‚˜ ๊ด‘๋ฒ”์œ„ํ•˜๊ณ  ์ด ๊ณผ์ •์˜ ๊ฐœ๋ฐœ์ž ๋ชฉํ‘œ ์ˆ˜์ค€์ด ๋ฌด์—‡์ธ์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ react+redux์—์„œ ๊ตฌํ˜„๋œ ๋ณต์žกํ•œ ์•ฑ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์„ค๊ณ„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ธํ„ฐ๋„ท ์–ด๋”˜๊ฐ€์—์„œ ๋ณด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค(์˜ˆ: ์—ฌ๋Ÿฌ ๋ฆฌ๋“€์„œ์— ์˜ํ•ด ์ œ์–ด๋˜๋Š” ์ƒํƒœ)์ด๋ฏ€๋กœ ๋‹ค๋ฅธ ์•ฑ์—์„œ ์ „์ฒด์ ์œผ๋กœ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@sompylasar React Redux

์ดˆ๋ณด์ž ์ˆ˜์ค€์˜ crud ์˜ˆ์ œ๋ฅผ ์ฐพ๊ณ  ์žˆ๋‹ค๋ฉด ํ•ญ์ƒ todo-mvc์™€ "babel+redux+react+webpack ์‹œ์ž‘ํ•˜๊ธฐ" ํŠœํ† ๋ฆฌ์–ผ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋˜ ๋‹ค๋ฅธ ๊ฒƒ์— ๋งŽ์€ ๊ฐ€์น˜๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์‹ ํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ๋งค์ฃผ ์ฃผ์ œ์— ๋Œ€ํ•œ ๋ช‡ ๊ฐœ์˜ ์ƒˆ๋กœ์šด ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ์„ ์ฝ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค(ํ•˜์ง€๋งŒ ์•„๋งˆ๋„ ์ด๋Ÿฌํ•œ ํŠœํ† ๋ฆฌ์–ผ์„ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•˜๋Š” ์•ฑ์„ ๋นŒ๋“œํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”? :p ). ์ €๋Š” ์ค‘๊ธ‰ ์ˆ˜์ค€์˜ ํŠœํ† ๋ฆฌ์–ผ์ด ๋” ๊ฐ€์น˜๊ฐ€ ์žˆ๊ณ  IMO์—์„œ ์•”ํ˜ธํ™”์— ๋Œ€ํ•ด ๋ฐฐ์šฐ๋Š” ๊ฒƒ์ด ๋งค๋ ฅ์ ์ธ ๋ถ€์ˆ˜์  ์ด์ ์ด ๋  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ฃผ์žฅํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ดˆ์‹ฌ์ž ์ˆ˜์ค€์˜ ์˜ˆ์ œ๋ฅผ ์ฐพ๊ณ  ์žˆ์ง€ ์•Š์ง€๋งŒ CRUD์˜ ๋ณต์žกํ•œ ๋ถ€๋ถ„(ํŽ˜์ด์ง€ ๋งค๊น€, ์ •๊ทœํ™”, ๋‚™๊ด€์  ์—…๋ฐ์ดํŠธ, ๊ด€๊ณ„)์ด ์˜ˆ์ œ์˜ ์ดˆ์ ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž ์ง€์ • ๋˜๋Š” ๊ธฐ์กด API๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๊นŒ? ์•„๋‹ˆ๋ฉด ์กฐํ•ฉ?

์–ด๋ ค์šด ์งˆ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋ชจ๋ฅด๊ฒ ์–ด์š”. Github API๋Š” ์“ฐ๊ธฐ ๊ฐ€๋Šฅํ•˜๊ณ  ๊ฐœ๋…์ด ๋ชจ๋‘์—๊ฒŒ ์นœ์ˆ™ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ข‹์€ ์•„์ด๋””์–ด์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. @ryanflorence๊ฐ€ ๋น„์Šทํ•œ ์ž‘์—…์„ ํ–ˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

ํ™•์‹คํžˆ ์ด๊ฒƒ์„ ํ†ตํ•ด ์ค‘๊ธ‰ ๊ฐœ๋ฐœ์ž๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค. ์ดˆ์‹ฌ์ž tuts๋Š” ํฌํ™” ์ƒํƒœ์ด๋ฉฐ ์œ„์— ๋‚˜์—ด๋œ Dan์˜ (์‹ค์ œ) ๋” ์–ด๋ ค์šด ์ฃผ์ œ๋ฅผ ๊ฑฐ์˜ ๋‹ค๋ฃจ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž ์ง€์ • ๋ฐ/๋˜๋Š” ๊ธฐ์กด API ๋ชจ๋‘์— ๊ฐœ๋ฐฉ์ ์ž…๋‹ˆ๋‹ค. aws ๊ณ„์ •์—์„œ ๋ชจ๋“  ์‚ฌ์šฉ์ž ์ง€์ • API๋ฅผ ํ˜ธ์ŠคํŒ…ํ•˜๊ฒŒ ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋˜ํ•œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ช‡ ๊ฐ€์ง€ ๋‹ค๋ฅธ ๊ณผ์ •์„ ์œ„ํ•ด ๊ตฌ์ถ• ์ค‘์ธ Medium.com ํด๋ก ์„ ์œ„ํ•œ ์™„์ „ํ•œ API๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ๋žŒ๋“ค์ด ๊ถ๊ธˆํ•ดํ•  ๊ฒฝ์šฐ ๋ฐฑ์—”๋“œ ์†Œ์Šค ์ฝ”๋“œ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํฅ๋ฏธ๋กญ๊ฒŒ ๋“ค๋ฆฌ๋ฉด ์„ธ๋ถ€ ์ •๋ณด๋ฅผ ๊ณต์œ ํ•˜๊ฒŒ ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค.

@EricSimons Medium ํด๋ก ์— ๋Œ€ํ•ด ๋” ์•Œ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

@cshenoy ํ™•์‹คํžˆ. React/Redux๋ฅผ ํ”„๋ก ํŠธ์—”๋“œ๋กœ, Node๋ฅผ ๋ฐฑ์—”๋“œ๋กœ ํ•˜๋Š” ํ’€์Šคํƒ JS ๊ณผ์ •์„ ๊ตฌ์ถ•ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐฑ์—”๋“œ API๋Š” ๋กœ์ปฌ์—์„œ ์‹คํ–‰ํ•˜๊ณ  ์‹ถ์ง€ ์•Š์€ ์‚ฌ๋žŒ๋“ค์„ ์œ„ํ•ด ๋…๋ฆฝ์ ์œผ๋กœ ํ˜ธ์ŠคํŒ…๋˜๋ฏ€๋กœ ์œ„์˜ ๋ณด๋‹ค ๋ณต์žกํ•œ ์ฃผ์ œ๋ฅผ ๊ฐ€๋ฅด์น˜๋Š” ๋ฐ ์ ํ•ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Medium ํด๋ก ์˜ ๊ธฐ๋Šฅ ์„ธํŠธ์—๋Š” ๋‹ค์Œ์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

  • ์ธ์ฆ(์ด๋ฉ”์ผ/ํŒจ์Šค ๋ฐ oAuth, JWT)
  • ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ ๋ฐ ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ ๋Œ“๊ธ€์šฉ CRUD
  • ํŒ”๋กœ์ž‰ ์‚ฌ์šฉ์ž
  • ๋ชจ๋“  ๋ธ”๋กœ๊ทธ์˜ ๊ธ€๋กœ๋ฒŒ ํ”ผ๋“œ ๋ฐ ํŒ”๋กœ์šฐํ•˜๋Š” ์‚ฌ์šฉ์ž์˜ ๋ธ”๋กœ๊ทธ ํ”ผ๋“œ
  • ํƒœ๊น… ์‹œ์Šคํ…œ
  • ์‚ฌ์šฉ์ž ํ”„๋กœํ•„/ํ”„๋กœํ•„ ์ •๋ณด ํŽธ์ง‘

์ตœ์ข… ์ฝ”๋“œ๋ฒ ์ด์Šค์˜ ETA๋Š” ์ด๋ฒˆ ์ฃผ ๋ง๊นŒ์ง€์ด๋ฏ€๋กœ ๊ทธ๋•Œ์ฏค์— ๋” ๋งŽ์€ ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋ชจ๋“  ๊ฒƒ์„ ์Šˆํผ ๋ชจ๋“ˆ์‹์œผ๋กœ ์„ค๊ณ„ํ–ˆ์œผ๋ฏ€๋กœ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์€ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค.

์ž‘์—…ํ‘œ(์‹œ๊ฐ„ ์ถ”์ ๊ธฐ)๋Š” ์‹ค์ œ๋กœ ํ”Œ๋Ÿญ์Šค/๋ฆฌ๋•์Šค ๋ฐ ํฌ๋ฃจ๋“œ์˜ ๋ณต์žกํ•œ ์ธก๋ฉด์„ ๋งŽ์ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ํŽ˜์ด์ง€ ๋งค๊น€๊ณผ ์บ์‹ฑ์€ ๋ฉฐ์น ๊ณผ ๋ช‡ ์ฃผ๋ฅผ ์™”๋‹ค๊ฐ”๋‹ค ํ•  ๋•Œ ํ•„์š”ํ•œ ๋ช…๋ฐฑํ•œ ์š”๊ตฌ ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค. ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ์“ฐ๊ธฐ ๊ฐ€๋Šฅํ•œ API๋„ ๋งŽ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์‹œ๊ฐ„ ์ถ”์  ์™ธ์—๋„ ๋งŽ์€ ๊ฒƒ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ๊ด€๋ฆฌ, ํ”„๋กœ์ ํŠธ ์—”ํ„ฐํ‹ฐ ๋“ฑ

๋‚˜๋Š” ์ด๊ฒƒ์ด ์ข‹์„ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•œ๋‹ค. ๋‚˜๋Š” ํŠนํžˆ ๊ทธ๊ฒƒ์˜ ์ผ๋ถ€๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐ ์•ฝ๊ฐ„ ์–ด๋ ค์›€์„ ๊ฒช์—ˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ƒˆ ๊ธฐ์‚ฌ๋ฅผ ๋งŒ๋“œ๋Š” ArticlePage ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.

// shortened version

import { addArticle } from '../actions'

function doAddArticle(props, handleAdded, values, dispatch) {
  props.addArticle(values)
  .then(handleAdded)
}

class AddArticlePage extends Component {
  handleAdded = () => {
    this.props.pushState(null, '/articles/')
  };

  render() {
    return (
      <div>
        <ArticleForm submit={(values, dispatch) => doAddArticle(this.props, this.handleAdded, values, dispatch)} />
      </div>
    )
  }
}

function mapStateToProps(state) {
  return {}
}

export default connect(mapStateToProps, {
  pushState,
  addArticle
})(AddArticlePage)

  1. ๋ฆฌ๋””๋ ‰์…˜์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ํ•ด๊ฒฐ๋œ ์•ฝ์†์„ ๋ฌถ๋Š” ๊ฒƒ์ด "์˜ฌ๋ฐ”๋ฅธ" ์ผ์ธ์ง€๋„ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.
  2. ์ƒˆ๋กœ ์ƒ์„ฑ๋œ ๊ธฐ์‚ฌ์—์„œ ID๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  ์ธ๋ฑ์Šค ํŽ˜์ด์ง€๋กœ ๋ฆฌ๋””๋ ‰์…˜ํ•˜๋Š” ๋Œ€์‹  /articles/{id}/ ํŽ˜์ด์ง€๋กœ ๋ฆฌ๋””๋ ‰์…˜ํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ฉ๋‹ˆ๊นŒ?
  3. ๋‚ด ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ๋น„๋™๊ธฐ ์ž‘์—…์˜ ๊ฒฐ๊ณผ๋ฅผ ์›ํ•˜๋Š” ๊ฒฝ์šฐ ์–ด๋–ป๊ฒŒ ํ•ฉ๋‹ˆ๊นŒ? ์ €์—๊ฒŒ ์ด๊ฒƒ์€ ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ์–‘์‹ ํ•„๋“œ๊ฐ€ ์žˆ๋Š” ArticleForm ๊ตฌ์„ฑ ์š”์†Œ ๋‚ด์— ๋‚˜ํƒ€๋‚ฌ์Šต๋‹ˆ๋‹ค. "addImage" ์ž‘์—…์„ ์ „๋‹ฌํ•˜๊ณ  ์ด๋ฏธ์ง€๊ฐ€ ๋กœ๋“œ๋˜๋ฉด 1) URL์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์—…๋กœ๋“œ๋œ ์ด๋ฏธ์ง€์˜ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ฅผ ํ‘œ์‹œํ•˜๊ณ  2) ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์–‘์‹์— URL์„ ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ Redux์—์„œ ์ด๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์ด ๋ฌด์—‡์ธ์ง€ ํŒŒ์•…ํ•˜๊ธฐ๊ฐ€ ์–ด๋ ค์› ์Šต๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ์ฐพ์€ ๋ฌธ์ œ๋Š” ์ƒˆ๋กœ ์ถ”๊ฐ€๋œ ์ƒํƒœ/์ด๋ฏธ์ง€๋ฅผ ์–‘์‹ ๊ตฌ์„ฑ ์š”์†Œ์˜ ์†Œํ’ˆ์— ๋งคํ•‘ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜์ง€๋งŒ 1) ์ƒˆ๋กœ ์ถ”๊ฐ€๋œ ์ด๋ฏธ์ง€๋ฅผ ์–ป๋Š” ๋ฐฉ๋ฒ•๊ณผ 2) ๋™์‹œ์— ์—…๋กœ๋“œ๋˜๋Š” 2๊ฐœ์˜ ์ด๋ฏธ์ง€๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ์–ด๋–ป๊ฒŒ ํ•ฉ๋‹ˆ๊นŒ? ์˜ฌ๋ฐ”๋ฅธ ๊ตฌ์„ฑ ์š”์†Œ์— ๋Œ€ํ•œ ์˜ฌ๋ฐ”๋ฅธ ์ด๋ฏธ์ง€ URL์„ ์–ป์—ˆ์Šต๋‹ˆ๊นŒ?

๋ฌผ๋ก  ์ €๋Š” Redux๋ฅผ ์‚ฌ์šฉํ•œ ์ง€ ๋ช‡ ๋‹ฌ๋ฐ–์— ์•ˆ ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์–ด๋ฆฌ์„์€ ๋ฌธ์ œ์ผ ์ˆ˜ ์žˆ์ง€๋งŒ ์ดˆ๋ณด์ž๋กœ์„œ ๊ทธ๋“ค์€ ๋ถ„๋ช…ํžˆ ์ €๋ฅผ ๋„˜์–ด๋œจ๋ ธ๊ณ  ์—ฌ์ „ํžˆ ์ œ ์†”๋ฃจ์…˜์ด "์˜ฌ๋ฐ”๋ฅธ ๋ฐฉ๋ฒ•"์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@jonathaningram redux-thunk๋Š” ์ „ํ˜€ ๋ณด์…จ๋‚˜์š”? ์œ„์—์„œ ์ˆ˜ํ–‰ํ•˜๋Š” ์ž‘์—…์˜ ๋Œ€์•ˆ์œผ๋กœ ์ž‘์—… ๋‚ด์—์„œ ํŒŒ๊ฒฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@babsonmatt ๋„ค ์ด๋ฏธ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ์‚ฌ์šฉํ•˜๋Š” ์‹ค์ œ ์‚ฌ๋ก€๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์•ฑ์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ์–ด์ฉŒ๋ฉด ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ์ „์ฒด ๊ธฐ๋Šฅ์œผ๋กœ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

@jonathaningram ๊ท€ํ•˜์˜ ๋ชจ๋ฒ”์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ์ง€์ ํ–ˆ๋“ฏ์ด ๋ฆฌ๋””๋ ‰์…˜ ๋…ผ๋ฆฌ๋ฅผ ์ž‘์—… ์ž‘์„ฑ์ž์˜ ์ฝํฌ๋กœ ์ด๋™ํ•˜๊ณ  ๊ฑฐ๊ธฐ์—์„œ ๊ฒฝ๋กœ ์—…๋ฐ์ดํŠธ๋ฅผ ์ „๋‹ฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. redux-saga ๋˜๋Š” redux-side-effects์™€ ๊ฐ™์€ ๋ถ€์ž‘์šฉ(๋ฆฌ๋””๋ ‰์…˜์€ ํ•ด๋‹น ์ž‘์—…์œผ๋กœ ์ธํ•œ ์ƒํƒœ ์ „ํ™˜์˜ ๋ถ€์ž‘์šฉ)์„ ๊ด€๋ฆฌํ•˜๋Š” ๋” ๋งŽ์€ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์‹ฌ๋„ ์žˆ๋Š” ๋…ผ์˜๋Š” ์ด ๋ฌธ์ œ์˜ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚ฌ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

@sompylasar ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๋„ค, ์ด ๋ฌธ์ œ๋ฅผ ์šฐํšŒํ•˜๊ณ  ์‹ถ์ง€๋Š” ์•Š์ง€๋งŒ Redux ์ดˆ๋ณด์ž๋กœ์„œ "์‹ค์ œ ์„ธ๊ณ„" ๊ฒฝํ—˜์„ ๊ณต์œ ํ•˜๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค.

@EricSimons ์ €๋Š” ๋•๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์ €๋Š” ํ˜„์žฌ Nuclear-js๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ CRUD ์•ฑ์„ ์œ ์ง€ ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ๋งŽ์€ ์•„์ด๋””์–ด๊ฐ€ redux๋กœ ์ž˜ ๋ฒˆ์—ญ๋  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋ธŒ๋ ˆ์ธ์Šคํ† ๋ฐ์„ ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์•Œ๋ ค์ฃผ์„ธ์š”.

์ €๋Š” ์ตœ๊ทผ์— CRUD(over REST) โ€‹โ€‹์ƒํƒœ ๊ด€๋ฆฌ ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค. Marionette/Backbone ๋ถ€ํ„ฐ React/Redux๋ฅผ ํŒŒํ—ค์น  ๋•Œ REST ๊ทœ์น™์ด ์ •๋ง ๊ทธ๋ฆฌ์› ์Šต๋‹ˆ๋‹ค.

https://github.com/masylum/resting-ducks

์†”๋ฃจ์…˜์ด ์˜ˆ์ธ์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋„์„œ๊ด€์ด ๊ทธ๊ฒƒ์„ ์œ„ํ•ด ๋” ์ž˜ ์ž‘๋™ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ƒํƒœ ๊ด€๋ฆฌ๋Š” ๊ฑฐ์˜ ํ•ญ์ƒ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. 2016๋…„์—๋Š” CRUD ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์ง€ ์•Š๊ณ  ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์— ์ง‘์ค‘ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

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

let routes = <Route path='/' component={Layout}>
  <IndexRoute component={BooksIndex} />
  <Route path='/book/new' component={BooksNew} />
  <Route path='/book/:id' component={BooksShow} loader={BooksLoader} />
  <Route path='/book/:id/edit' component={BooksEdit} loader={BooksLoader} />
</Route>;

BooksLoader๋Š” ๋‘ ๊ฐ€์ง€ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋Š” ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค.

  • NeedsToSyncStore(params, store)๋Š” ์ €์žฅ์†Œ๋ฅผ ๋™๊ธฐํ™”ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ true๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด false๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • syncStore(params, store)๋Š” ์ €์žฅ์†Œ๋ฅผ ๋™๊ธฐํ™”ํ•˜๊ณ  ์•ฝ์†์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ์€ ๋” ๋˜‘๋˜‘ํ•œ ๊ฒƒ์œผ๋กœ ํ™•์‹คํžˆ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ๋Š” ๋งค์šฐ ๊ธฐ๋ณธ์ ์ธ ๊ตฌํ˜„ ์˜ˆ์ž…๋‹ˆ๋‹ค(์˜ˆ: ImmutableJS / Map):

import _ from 'lodash';
import * as Actions from 'actions';
import API from 'api';

export default class BooksLoader {
  needsToSyncStore(params, store) {
    let books = store.getState().books;

    if(books) {
      const book = _.findWhere(books.collection, { isbn: params.id });
      if(book) {
        return false;
      }
    }

    return true;
  }

  syncStore(params, store) {
    let { dispatch } = store;
    let api = new API();

    let loadBooks = Actions.loadBooks();
    return loadBooks(dispatch, store.getState);
  };
}

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

๋‹ค์Œ ์กฐ๊ฐ์€ ReactRouter: https://gist.github์˜ RenderContext๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” @ryanflorence AsyncProps(https://github.com/rackt/async-props)์—์„œ ํฌ๊ฒŒ ์˜๊ฐ์„ ๋ฐ›์€ ๋ฐ˜์‘ ๊ตฌ์„ฑ ์š”์†Œ์ธ ์Šคํ† ์–ด ๋กœ๋”์ž…๋‹ˆ๋‹ค . com/sebastiandeutsch/e6148ca0741cc355248c

๋กœ๋”์— ๋Œ€ํ•œ ReactRouter์˜ ๊ฒฝ๋กœ๋ฅผ ํ™•์ธํ•˜๊ณ  ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ ์ปจํ…์ŠคํŠธ๋ฅผ ํ†ตํ•ด ๋กœ๋”ฉ ์ƒํƒœ๋ฅผ ๋…ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

<Provider store={store}>
  <Router
    history={browserHistory}
    render={(props) => (
      <StoreLoader {...props} store={store} />
    )}>
      {routes}
    </Router>
</Provider>

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

export class BooksShow extends React.Component {
  static contextTypes = {
    storeIsSynchronized: React.PropTypes.bool
  };
  ...
  render() {
    const { book } = this.props;

    if(this.context.storeIsSynchronized) {
      /* display components */
    } else {
      /* display loading spinner */
    }
}

export default connect(
  (state, props) => {
    return {
      book: _.findWhere(state.books.collection, { isbn: props.params.id } )
    }
  },
  (dispatch) => ({
    actions: bindActionCreators(Actions, dispatch)
  })
)(BooksEdit);

@gaearon ์ด ์•„์ด๋””์–ด์— ๋Œ€ํ•ด ์–ด๋–ป๊ฒŒ ์ƒ๊ฐํ•˜์„ธ์š”?

@sebastiandeutsch ๋‚˜๋Š” ๊ทธ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค. ์ €๋„ Async-Props๋กœ ์‹คํ—˜ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—์„œ ๋‹น์‹ ์˜ ์•„์ด๋””์–ด๋Š” ์ •๋ง ๋ฉ‹์ ธ ๋ณด์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด ์˜ˆ์ œ๊ฐ€ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ๋ฅผ ์œ„ํ•œ ์ถ”์ƒํ™”๋ฅผ ์ค‘์‹ฌ์œผ๋กœ ์กฐ์ •๋˜๊ธฐ ๋ณด๋‹ค๋Š” ๋” ์ผ๋ฐ˜์ ์ด์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. Rest API์— ๋Œ€ํ•œ ์ €์žฅ์†Œ ๋ฐ ์ž‘์—…์„ ์„ค์ •ํ•˜๋Š” ์‰ฌ์šด ๋ฐฉ๋ฒ•์˜ ๊ธฐ๋ณธ ์˜ˆ์ œ๋กœ https://github.com/optimizely/nuclear-js/tree/master/examples/rest-api ๋ฅผ ์ •๋ง ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค.

์บ์‹œ๋ฅผ ์ง€์›ํ•˜๊ณ  ์ €์žฅ์†Œ์— ์ง„ํ–‰ ์ค‘์ธ ์š”์ฒญ์„ ์ €์žฅํ•˜๋„๋ก ํ™•์žฅํ–ˆ์Šต๋‹ˆ๋‹ค(์š”์ฒญ์ด ๋‹ค์‹œ ๋ฐœ์ƒํ•˜๋ฉด ํ˜ธ์ถœ์ž๋Š” xhr์„ ๋‹ค์‹œ ์‹œ์ž‘ํ•˜๋Š” ๋Œ€์‹  ๋‹จ์ˆœํžˆ ์ง€์—ฐ๋ฉ๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ๋งํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•œ ๋ณด๋‹ค ๊ฐ•๋ ฅํ•œ ์˜ˆ๋Š” ์—ฌ๊ธฐ์— ์žˆ์Šต๋‹ˆ๋‹ค. : https://github.com/jordangarcia/nuclear-api-module-example/tree/master/rest_api ๊ทธ๋ฆฌ๊ณ  @jordangarcia ์˜ ๊ฐœ๋… ์ค‘ ์ผ๋ถ€๋ฅผ ํฐ ์„ฑ๊ณต์œผ๋กœ ๋ณต์‚ฌํ–ˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์˜ ์ ‘๊ทผ ๋ฐฉ์‹์ด ๋‹ค์Œ๊ณผ ์ž˜ ์ž‘๋™ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. redux๋„ (normalizr ๋“ฑ๊ณผ ํ•จ๊ป˜ ์ œ๊ณต).

@EricSimons ๋Š” ์ฃผ์ œ์™€ ์“ฐ๊ธฐ ๊ฐ€๋Šฅํ•œ ์ข‹์€ API๋ฅผ ์ฐพ๋Š” ๋ฐ ๋” ๋งŽ์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ์•„๋‹ˆ๋ฉด ํŠน์ • ์ ‘๊ทผ ๋ฐฉ์‹์„ ์ฐพ๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

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

์ฐธ๊ณ ๋กœ @dan-weaver ๋ฐ ์ด ์ž‘์—…์— ๊ด€์‹ฌ์ด ์žˆ๋Š” ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค - [email protected] ์— ๋ฉ”๋ชจ๋ฅผ

Meteor ์„ธ๊ณ„์—๋Š” Meteor์— ๋Œ€ํ•œ ์ฑ…์—์„œ ์‹œ์ž‘๋œ ํ•˜๋‚˜์˜ ํฐ ์˜คํ”ˆ ์†Œ์Šค ์˜ˆ์ œ ํ”„๋กœ์ ํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํ”„๋กœ์ ํŠธ๋Š” Reddit ๋˜๋Š” Hacker News์™€ ์œ ์‚ฌํ•œ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ธ Telescope ์ž…๋‹ˆ๋‹ค. Redux์— ๋น„์Šทํ•œ ์˜ˆ๊ฐ€ ์žˆ๋‹ค๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋งŽ์€ ๊ฐœ๋ฐœ์ž๋“ค์ด ์ด ์ฑ…์„ ๋”ฐ๋ฅด๊ณ  ๊ทธ๊ฒƒ๊ณผ ํ•จ๊ป˜ ๋” ์ž‘์€ ๋ฒ„์ „์˜ Telescope๋ฅผ ๊ตฌ์ถ•ํ•จ์œผ๋กœ์จ Meteor๋ฅผ ๋ฐฐ์› ์Šต๋‹ˆ๋‹ค. Telescope์™€ ๊ฐ™์€ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์€ Dan์ด ๋Œ€๋ถ€๋ถ„์˜ ๊ฐœ๋ฐœ์ž์—๊ฒŒ ์ด๋ฏธ ์นœ์ˆ™ํ•œ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์— ๋Œ€ํ•ด ์ œ๊ธฐํ•œ ๋ชจ๋“  ์ฃผ์ œ๋ฅผ ๋‹ค๋ฃน๋‹ˆ๋‹ค(Hacker News, Reddit, .. ๋•Œ๋ฌธ์—).

๋‚˜๋Š” ๋ช‡ ๋‹ฌ ์ „์— webapp *์—์„œ ์œ ์‚ฌํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ธฐ์ดˆ๋ฅผ ๋งŒ๋“ค๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ํ”„๋กœ์ ํŠธ์—๋Š” ๋นŒ๋“œ ํ”„๋กœ์„ธ์Šค, CSS ๋ชจ๋“ˆ, ์ธ์ฆ, API์šฉ ๋ณ„๋„ ์„œ๋ฒ„, MongoDB, ์„œ๋ฒ„ ์ธก ๋ Œ๋”๋ง, GraphQL ๋“ฑ์ด ์ด๋ฏธ ์„ค์ •๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค(์ผ๋ถ€๋Š” ์•ฝ๊ฐ„ ๊ตฌ์‹์ผ ์ˆ˜ ์žˆ๊ณ , ๋” ๋งŽ์€ ์ž‘์—…์ด ํ•„์š”ํ•˜๊ฑฐ๋‚˜ ์™„๋ฃŒ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋” ๋‚˜์€). ๋˜ํ•œ ๋‹ค๋ฅธ ์˜ˆ์—๋Š” ์—†๋Š” ๊ฒƒ์œผ๋กœ ์ƒ๊ฐ๋˜๋Š” ๊ฐ์†๊ธฐ ๋ถ„ํ• ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ถ€์กฑํ•œ ์ ์€ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ, ๋‚™๊ด€์  ์—…๋ฐ์ดํŠธ, ์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ์ข‹์€ ์†”๋ฃจ์…˜์ด๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ ์ง€๊ธˆ ๋ชจ๋“  ๊ฒƒ์ด ์–ผ๋งˆ๋‚˜ ๋นจ๋ฆฌ ์ง„ํ–‰๋˜๊ณ  ์žˆ๋Š”์ง€์— ๋Œ€ํ•ด 2 ๊ฐœ์›”์ด ์˜์›์ฒ˜๋Ÿผ ๋Š๊ปด์ง€๊ธฐ ๋•Œ๋ฌธ์— ์•ฝ๊ฐ„ ๊ตฌ์‹์ž…๋‹ˆ๋‹ค :)

์ฝ”์Šค์˜ ์˜ˆ์ œ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ์ถœ๋ฐœ์ ์„ ์›ํ•œ๋‹ค๋ฉด _webapp_์ด ์˜๊ฐ์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Redux์—์„œ Telescope์™€ ์œ ์‚ฌํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์„ ๋ณด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

*_ ๋…ธํ•˜์šฐ ํด๋”์—๋Š” ์•„ํ‚คํ…์ฒ˜/๊ฒฐ์ •์— ๋Œ€ํ•œ ์ผ๋ถ€ ์ •๋ณด๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค._


_Sidenote:_ Redux์— ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ์— ๋Œ€ํ•œ ์ด์•ผ๊ธฐ๊ฐ€ ์—†๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•˜๊ธฐ ๋•Œ๋ฌธ์— ํ˜„์žฌ Redux์™€ ํ†ตํ•ฉ๋˜๋Š” Relay์™€ ์œ ์‚ฌํ•œ ์‹œ์Šคํ…œ์„ ๋งŒ๋“ค๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์ œ๊ฐ€ 2๊ฐœ์›” ๋™์•ˆ _webapp_์„ ์—…๋ฐ์ดํŠธํ•˜์ง€ ์•Š์€ ์ด์œ ์ž…๋‹ˆ๋‹ค. ํ•ด๋‹น ์‹œ์Šคํ…œ์„ ๋งŒ๋“œ๋Š” ๋ฐ ์„ฑ๊ณตํ•˜๋ฉด _webapp_ ๊ณ„์†ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ง๋ฉดํ•œ ํ•œ ๊ฐ€์ง€ ๋ฌธ์ œ๋Š” Redux๊ฐ€ ๋งค์šฐ ๋‚ฎ์€ ์ˆ˜์ค€์ด๋ฉฐ ๋”ฐ๋ผ์„œ Redux๋ฅผ ์ค‘์‹ฌ์œผ๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ _์‹ค์ œ๋กœ_ ๋นŒ๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์ƒ๋‹นํžˆ ์˜๊ฒฌ์ด ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ redux์™€ ์ตœ์ข… ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค ์‚ฌ์ด์— ์œ ํšจํ•œ ์ถ”์ƒํ™”๊ฐ€ ๋„ˆ๋ฌด ๋งŽ๊ธฐ ๋•Œ๋ฌธ์— ํ•™์Šตํ•  _one_ ์˜ˆ์ œ ์ฝ”๋“œ๋ฒ ์ด์Šค๋ฅผ ๋‹จ์ˆœํžˆ ์œ ์ง€ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์‹ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋ฐ์ดํ„ฐ ๋กœ๋“œ์— ๋Œ€ํ•œ ๋งŽ์€ ๋‹ค๋ฅธ ๊ฐ€๋Šฅ์„ฑ์ด ๋ช…ํ™•ํ•œ ์Šน์ž๊ฐ€ ์—†์ด ์ œ์‹œ๋˜๋Š” ์ด ์Šค๋ ˆ๋“œ์˜ ์ผ๋ถ€ ๋…ผ์˜์— ์˜ํ•ด ์˜ˆ์‹œ๋ฉ๋‹ˆ๋‹ค. ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ ๊ทœ๋ชจ๊ฐ€ ํฌ๊ฒŒ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ์˜ฌ๋ฐ”๋ฅธ ๋ฐฉ๋ฒ• ์€ ์—†์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์ด์œ ๋กœ Dan์ด ์ด์ „์— ์–ธ๊ธ‰ํ•œ ๋ชจ๋“  ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ์„ ์š”๊ตฌํ•˜๋Š” ์‚ฌ์–‘์— "_The_ Advanced TODOMVC of Redux" ๋ฅผ ์ œ์‹œํ•˜๋Š” ๊ฒƒ์ด ๋ฐ”๋žŒ์งํ•ฉ๋‹ˆ๋‹ค.

์•ž์œผ๋กœ ๋‚˜์•„๊ฐ€๋ฉด์„œ ์ด ๊ณ ๊ธ‰ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ฐœ๋… ์ฆ๋ช…์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋” ๋งŽ์€ ์ถ”์ƒํ™”/๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ/ํ”„๋ ˆ์ž„์›Œํฌ _์ฃผ๋ณ€_ Redux๋ฅผ ๋ณด๊ธฐ ์‹œ์ž‘ํ•  ๊ฒƒ์ด๋ผ๊ณ  ๋ฏฟ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ์‹œ๊ฐ„์ด ์ง€๋‚จ์— ๋”ฐ๋ผ ์ด๊ฒƒ์€ Redux์™€ ๊ด€๋ จ์ด ์—†๋Š” ๊ฒƒ์œผ๋กœ ๋ธŒ๋žœ๋“œ๊ฐ€ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

API ์ธก๋ฉด์—์„œ ์ผ์ข…์˜ ํ‘œ์ค€( JSON-API ๋Š” ๋น„์ •๊ทœํ™” ๋ฐ ๊ด€๊ณ„ ์„ค๋ช…์„ ์œ„ํ•œ ํƒ์›”ํ•œ ๊ธฐ๋ฐ˜ ์ œ๊ณต)์„ ๋”ฐ๋ฅด๊ณ  ๊ถ๊ทน์ ์œผ๋กœ ์ด ์•ž์— GraphQL ์„œ๋ฒ„๊ฐ€ ์žˆ๋Š” ๊ฒƒ์„ ๋ณด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

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


ํ•œํŽธ์œผ๋กœ๋Š” ๋ถ€๋ถ„์ ์œผ๋กœ ๊ด€๋ จ๋˜์–ด ์žˆ์ง€๋งŒ ์—ฌ๊ธฐ ํŠน์ • ์ฃผ์ œ์—์„œ ์–ธ๊ธ‰ํ•œ ๋‚ด์šฉ์„ ์ฐธ๊ณ ํ•˜์—ฌ Redux์˜ ๋ฒ”์œ„๋ฅผ ๋ช…ํ™•ํžˆ ํ•˜๋Š” ๋ฐ ์ด ๋ฌธ์ œ์˜ ์šฐ์„ ์ˆœ์œ„๋ฅผ ์ง€์ •ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์„ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ถ”์‹ . ๊ณง React London ์—์„œ "Real World Redux" ๊ฐ•์—ฐ์ด ์—ด๋ฆด ์˜ˆ์ •

๋‚˜๋Š” ์ด ์ž‘์—…์„ ํ•  ์ค€๋น„๊ฐ€ ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ƒˆ ์‚ฌ์šฉ์ž์—๊ฒŒ ํ•  ์ผ ๋ชฉ๋ก์ด ์•„๋‹Œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๊ณ  ์ฃผ์„ ์ฒ˜๋ฆฌ๋˜๊ณ  ์„ค๋ช…๋œ Redux ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์€ ์ข‹์€ ์•„์ด๋””์–ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์•„์ง @EricSimons์— ๋Œ€ํ•œ ์ž‘์—…์ด ์‹œ์ž‘๋˜์—ˆ์Šต๋‹ˆ๊นŒ?

redux ์˜ ์ƒ์šฉ๊ตฌ๋ฅผ ์ค„์ด๊ณ  ์ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹ค์ œ ์„ธ๊ณ„๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ๋น„์Šทํ•œ ์งˆ๋ฌธ์ด ๋งŽ์ด ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋‚ด๊ฐ€ ์—ฌ๊ธฐ์— ๋Œ€ํ•ด ์“ด ๊ฝค ์ข‹์€ ์†”๋ฃจ์…˜(๋ฌด์—‡๋ณด๋‹ค๋„)์„ ์ฐพ์•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

https://medium.com/@timbur/react -automatic-redux-providers-and-replicators-c4e35a39f1

TL; DR : ๋‹น์‹ ์€ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค redux ์ž๋™์œผ๋กœ์— ๋”ฐ๋ผ ๊ตฌ์„ฑ ์š”์†Œ์— ์ž์‹ ์„ ์ผ์น˜ ์ œ๊ณต propTypes . ์ •๋ง ํ•„์š”ํ•œ ๊ฒƒ์€ components ๋””๋ ‰ํ† ๋ฆฌ, providers ๋””๋ ‰ํ† ๋ฆฌ, ์„ ํƒ ์‚ฌํ•ญ์ด์ง€๋งŒ ๊ถŒ์žฅ๋˜๋Š” themes ๋””๋ ‰ํ† ๋ฆฌ์ž…๋‹ˆ๋‹ค. ๋ชจ๋“  ๊ฒƒ์€ ์‰ฝ๊ฒŒ ๊ตํ™˜, ์ดํ•ด, ์œ ์ง€ ๊ด€๋ฆฌ, ํ™•์žฅ ๋ฐ ์žฌ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๋ชจ๋‘ ํ•ซ ๋ฆฌ๋กœ๋”ฉ, ์„œ๋ฒ„ ๋ Œ๋”๋ง ๋“ฑ๊ณผ ๊ฐ™์€ ๋ชจ๋“  ๊ฒƒ์—๋Š” ํ›จ์”ฌ ๋” ๋งŽ์€ ๊ฒƒ์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ €๋Š” ์˜ค๋Š˜ ์ผ์ฐ ํฌํ•จ๋œ ์ƒ์šฉ๊ตฌ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ฒ˜์Œ๋ถ€ํ„ฐ ์•ฑ์„ ๋นŒ๋“œํ–ˆ์œผ๋ฉฐ ์•ฝ 10๋ถ„์ด ๊ฑธ๋ ธ์Šต๋‹ˆ๋‹ค. ๋ณดํ†ต 1์‹œ๊ฐ„ ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค. :)

์–ผ๋ฆฌ ๋ฆฌ์•กํŠธ ์–ด๋‹ตํ„ฐ๋กœ์„œ์˜ ๊ฒฝํ—˜์— ๋”ฐ๋ฅด๋ฉด ๋‚˜๋Š” ์˜ˆ์ œ์—์„œ Github API๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

  • "๊ทธ๋ƒฅ ์ž‘๋™ํ•˜๋Š”" ๊ฒƒ์„ ์ฐพ๋Š” ์‚ฌ๋žŒ์—๊ฒŒ๋Š” ์ธ์ฆ์ด ์ง€๋‚˜์น˜๊ฒŒ ๋ณต์žกํ•ฉ๋‹ˆ๋‹ค.
  • ์‹คํ—˜์— ์ ํ•ฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. API ๋ณ€ํ˜•์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋™์•ˆ ํŒŒ๊ดด์ ์ด์ง€ ์•Š๊ฒŒ ํ•˜๋ ค๋ฉด ๋ณ„๋„/์ผ์‹œ์ ์ธ Github ๊ณ„์ •์„ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋Œ€์‹  ๊ฐ„๋‹จํ•œ ์‚ฌ์šฉ์ž ์ •์˜ API๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค. ์šฐ๋ฆฌ๋Š” ์ œ3์ž์— ์˜์กดํ•˜๊ณ  ์‹ถ์ง€ ์•Š์œผ๋ฉฐ ๋ˆ„๊ตฌ๋‚˜ json-server ์—์„œ ๋‚ด BottledAPI ์˜ˆ์ œ (wip)์™€ ๊ฐ™์€ ์ž์‹ ์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๋˜ํ•œ Javascript, Java, C#, PHP ๋“ฑ์—์„œ ๋‹ค๋ฅธ ๋‚˜๋จธ์ง€ ๋ฐฑ์—”๋“œ ๊ตฌํ˜„์„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๊ฝค ํ„ดํ‚ค ๋ฐฉ์‹์œผ๋กœ ๊ฐœ๋ฐœ์„ ์‹œ์ž‘ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์œ„์˜ ๋‚ด ์˜๊ฒฌ์— ์žˆ๋Š” ๋งํฌ ๋‚ด BTW์—๋Š” ๋ธ”๋กœ๊ทธ ์•ฑ์„ ๋นŒ๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์„ธ๋ถ€ ์ •๋ณด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ์ฃผ ๋‚ด์— ์‚ฌ์šฉ์ž ์ธ์ฆ๊ณผ ๊ทธ ๋ชจ๋“  ๊ฒƒ์„ ์ถ”๊ฐ€ํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค.

์•ˆ๋…• ์–˜๋“ค์•„! ์ €๋Š” ReactJS๋ฅผ ๊ณต๋ถ€ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ React + Redux๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐœ์ธ URL ๋‹จ์ถ•๊ธฐ ๋ฒ„์ „์„ ๊ฐœ๋ฐœํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚ด ์˜ˆ์ œ๋Š” ํ”„๋ŸฐํŠธ์—”๋“œ ๊ฐœ๋ฐœ์„ ์œ„ํ•ด Gulp + Browserify + Babelify๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ตฌ์„ฑ ์š”์†Œ ๋ฐ ์ž‘์—…์— ๋Œ€ํ•ด Mocha ๋ฐ Enzyme์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ์˜ˆ์—๋Š” ๋‹ค์Œ๋„ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

  • ์ƒ์„ฑ, ์ฝ๊ธฐ ๋ฐ ์—…๋ฐ์ดํŠธ ์ž‘์—…
  • Json ์›น ํ† ํฐ์œผ๋กœ ์ธ์ฆ
  • ์ชฝ์ˆ˜ ๋งค๊ธฐ๊ธฐ
  • ํƒœ๊ทธ
  • CORS

์ธํ„ฐํŽ˜์ด์Šค ๋ฐ ์‚ฌ์šฉ์„ฑ์— ์•ฝ๊ฐ„์˜ ๋ฒ„๊ทธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค =)
๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ์‹ค์ œ ์‚ฌ๋ก€์˜ ๊ธฐ๋ฐ˜์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐ๋ชจ: https://gustavohenrique.github.io/gh1
์ถœ์ฒ˜: https://github.com/gustavohenrique/gh1

์ด ์˜ˆ์ œ๋ฅผ ๊ฐœ์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ œ์•ˆ์„ ์ˆ˜๋ฝํ•ฉ๋‹ˆ๋‹ค. ๊ฐ์‚ฌ ํ•ด์š”!

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

์šฐ๋ฆฌ๋Š” ๋น„๋™๊ธฐ ์ž‘์—…์— redux-thunk ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์ตœ์ƒ์œ„ ๋ฆฌ๋“€์„œ๋ฅผ ํ•„ํ„ฐ๋งํ•˜๋Š” ๊ฒƒ๋งŒ์œผ๋กœ ๋†€๋ผ์šด ๊ฐœ์„ (_๋ชจ๋ฐ”์ผ์—์„œ_)์„ ์ œ๊ณตํ•˜๋Š” redux-ignore ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
์›น ์•ฑ์€ 100% ๋ฐ˜์‘ํ•˜๋ฏ€๋กœ ๋ชจ๋ฐ”์ผ์—์„œ ์‚ฌ์šฉ/ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค.

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

์–ด์จŒ๋“ , ์—ฌ๊ธฐ์— ๋งํฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค http://www.handy-erp.com/en/
๊ณ„์ •์„ ๋งŒ๋“ค๊ณ  ์Šค์Šค๋กœ๋ฅผ ๋…ธํฌํ•˜์„ธ์š”.

@SebastienDaniel ์ถ•ํ•˜ํ•ฉ๋‹ˆ๋‹ค! ์•„๋ฆ„๋‹ค์šด ์›น์‚ฌ์ดํŠธ์ž…๋‹ˆ๋‹ค. redux ๋ถ€๋ถ„์„ ๊ณต๊ฐœ ์ €์žฅ์†Œ์— ๋„ฃ์—ˆ์Šต๋‹ˆ๊นŒ?

@gustavohenrique ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค
๋ถˆํ–‰ํžˆ๋„ ์†Œ์Šค๋Š” ๊ณต๊ฐœ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์— ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ €๋Š” ์ด ์†Œ์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์งˆ๋ฌธ์„ ๋‹ค๋ฃจ๊ฑฐ๋‚˜ ์ปค๋ฎค๋‹ˆํ‹ฐ๋ฅผ ๋•๊ธฐ ์œ„ํ•œ ๋ฐ๋ชจ๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๋ฐ ๋งค์šฐ ๊ฐœ๋ฐฉ์ ์ž…๋‹ˆ๋‹ค.

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

๋จผ์ € ๊ณต์œ  ์ฝ”๋“œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!@gustavohenrique
๋‹ค๋ฅธ ๊ฒƒ๋“ค:
์‚ฌ์šฉ์ž ๋ชฉ๋ก์ด ์•„๋‹๊นŒ? ๋กœ๊ทธ์ธ? ๋“ฑ๋กํ•˜๋‹ค...
redux์—๋Š” ์ด๋Ÿฌํ•œ ์˜ˆ์ œ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค!

@gggin ๋ฐ @EricSimons์— ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์˜ ์™„์ „ํ•œ ์ƒ์‚ฐ ์ค€๋น„ ๋ฒ„์ „์€ ๋†€๋ž์Šต๋‹ˆ๋‹ค.

์ธ์ฆ(์ด๋ฉ”์ผ/ํŒจ์Šค ๋ฐ oAuth, JWT)
๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ ๋ฐ ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ ๋Œ“๊ธ€์šฉ CRUD
ํŒ”๋กœ์ž‰ ์‚ฌ์šฉ์ž
๋ชจ๋“  ๋ธ”๋กœ๊ทธ์˜ ๊ธ€๋กœ๋ฒŒ ํ”ผ๋“œ ๋ฐ ํŒ”๋กœ์šฐํ•˜๋Š” ์‚ฌ์šฉ์ž์˜ ๋ธ”๋กœ๊ทธ ํ”ผ๋“œ
ํƒœ๊น… ์‹œ์Šคํ…œ
์‚ฌ์šฉ์ž ํ”„๋กœํ•„/ํ”„๋กœํ•„ ์ •๋ณด ํŽธ์ง‘

์ด ์™ธ์—๋„ ๊ธฐ๋ณธ ์—ญํ•  ๋˜๋Š” ๊ถŒํ•œ ์‹œ์Šคํ…œ์ด ์žˆ์œผ๋ฉด ์ข‹์Šต๋‹ˆ๋‹ค. GitHub์˜ ํŒ€ ๋˜๋Š” Trello์˜ ๊ตฌ์„ฑ์›๊ณผ ๋™๋“ฑํ•œ ๊ฒƒ

ํ—ค์ด ์—ฌ๋Ÿฌ๋ถ„,

์ €๋Š” ์ง€๋‚œ ๋ช‡ ์ฃผ ๋™์•ˆ์˜ ๊ฒฝํ—˜์„ ๋ฐ”ํƒ•์œผ๋กœ ๊ฐ•๋ ฅํ•œ redux crud api ์— ๋Œ€ํ•œ ๋Š์Šจํ•œ ์ œ์•ˆ์„ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

https://github.com/ppiekarczyk/redux-crud-api-middleware/blob/master/README.md

์–ด๋–ค ํ”ผ๋“œ๋ฐฑ์ด๋“  ๊ฐ์‚ฌํžˆ ๋ฐ›๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ฐ์‚ฌ ํ•ด์š”!

์ €๋Š” ์ง€๊ธˆ ๋งŒ๋“ค๊ณ  ์žˆ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์˜คํ”ˆ ์†Œ์Šค ์˜ˆ์ œ ํ”„๋กœ์ ํŠธ๋กœ ๋ณ€ํ™˜ํ•  ์˜ํ–ฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š”. ์˜ˆ์ œ ์ฝ”๋“œ๋ฒ ์ด์Šค๋ฅผ ๊ฑฐ์˜ ๊ฒ€ํ† ํ•  ์ค€๋น„๊ฐ€ ๋˜์—ˆ์Œ์„ ์•Œ๋ ค๋“œ๋ฆฌ๊ฒŒ ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค. ๋งค์šฐ ์ฒ ์ €ํ•˜๋ฉฐ ์ด ์Šค๋ ˆ๋“œ์—์„œ ์ด์•ผ๊ธฐํ•œ ๋Œ€๋ถ€๋ถ„์˜ ์‹ค์ œ ์‚ฌ์šฉ ์‚ฌ๋ก€(์ธ์ฆ, CRUD, ํŽ˜์ด์ง€ ๋งค๊น€ ๋“ฑ)๋ฅผ ๋‹ค๋ฃน๋‹ˆ๋‹ค. @vkarpov15 ์—์„œ ๋งˆ๋ฌด๋ฆฌํ•ด์•ผ ํ•  ๋ช‡ ๊ฐ€์ง€ ์ž‘์—…์ด ์žˆ์ง€๋งŒ ๋‹ค์Œ ์ฃผ ์ดˆ์ฏค์— ์ค€๋น„๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ฝ”๋“œ๋ฒ ์ด์Šค๋ฅผ ๊ฒ€ํ† ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜์—ˆ์œผ๋ฉด ํ•ฉ๋‹ˆ๋‹ค. @gaearon ์ด ๋ช‡ ๋‹ฌ ์ „ ๊ธฐ๊บผ์ด ์‚ดํŽด๋ณด๊ณ  ์žˆ์œผ๋ฉฐ ์—ฌ๊ธฐ ์ปค๋ฎค๋‹ˆํ‹ฐ์˜ ๋ชจ๋“  ํ”ผ๋“œ๋ฐฑ์€ ํ›Œ๋ฅญํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ฒ€ํ†  ๋ฐ ๋ฐ˜๋ณตํ•˜๋Š” ๋™์•ˆ ์ดˆ๊ธฐ ์ฝ”๋“œ๋ฒ ์ด์Šค์— ์ด ๋ฆฌํฌ์ง€ํ† ๋ฆฌ ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , ์ค€๋น„๊ฐ€ ๋˜๋ฉด ์ตœ์ข… ์ฝ”๋“œ๋ฅผ ๊ณต์‹ redux ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์— ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค. ์ž์œ ๋กญ๊ฒŒ ๋ณ„ํ‘œ๋ฅผ ํ‘œ์‹œํ•˜๊ฑฐ๋‚˜ ์‹œ์ฒญํ•˜๊ณ  ์ฝ”๋“œ๋ฒ ์ด์Šค๊ฐ€ ์˜จ๋ผ์ธ ์ƒํƒœ์ด๊ณ  ๊ฒ€ํ† ํ•  ์ค€๋น„๊ฐ€ ๋˜๋ฉด ์ด ์Šค๋ ˆ๋“œ์— ์—…๋ฐ์ดํŠธ๋ฅผ ๊ฒŒ์‹œํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์งˆ๋ฌธ์— ๋‹ต๋ณ€ํ•ด ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค. ํ›Œ๋ฅญํ•œ ํ† ๋ก ์„ ํ•ด์ฃผ์‹  ๋ชจ๋“  ๋ถ„๋“ค๊ป˜ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค!

์ž˜ ๋“ค๋ฆฐ๋‹ค. ์ค€๋น„๊ฐ€ ๋˜๋ฉด ๊ด€๋ จ Redux FAQ ์งˆ๋ฌธ์— ์–ธ๊ธ‰๊ณผ ๋งํฌ๋ฅผ ์ถ”๊ฐ€ํ•˜์„ธ์š”.

์•ฝ์†ํ•œ ๋Œ€๋กœ ์ฝ”๋“œ๋ฒ ์ด์Šค๋Š” https://github.com/GoThinkster/redux-review ์—์„œ ๊ฒ€ํ† ํ•  ์ค€๋น„๊ฐ€ ๋˜์—ˆ์œผ๋ฉฐ ๋ชจ๋“  ์‚ฌ๋žŒ์˜ ํ”ผ๋“œ๋ฐฑ์„ ๋“ฃ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ ๋ฐ ํ™๋ณด๋ฅผ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค!

์—ฌ๋Ÿฌ๋ถ„, ๋ฉ‹์ง„ ํ† ๋ก ๊ณผ ํ›Œ๋ฅญํ•œ ์‹ค์ œ ์‚ฌ๋ก€๋ฅผ ์ œ์‹œํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์˜ˆ์ œ ๋ชฉ๋ก์— ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด ์ด ์˜ˆ์ œ https://github.com/andrewngu/sound-redux , ์ž‘์—… ๋ฐ๋ชจ๊ฐ€ https://soundredux.io/์— ๋ฐฐํฌ๋œ ๊ฒƒ์„ @gaearon ์ด ๋งํ•œ ๊ธฐ์ค€์—๋„ ๋ถ€ํ•ฉํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ™•์‹คํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ๋ˆ„๊ตฐ๊ฐ€ ํ”ผ๋“œ๋ฐฑ์„ ์ค„ ์ˆ˜ ์žˆ๋‹ค๋ฉด ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ž๊ฒฉ์ด ๋˜๋Š” ๊ฒฝ์šฐ ๋ชฉ๋ก์— ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ ์ง€๋‚œ 1๋…„ ๋ฐ˜ ๋™์•ˆ ์ ๊ทน์ ์œผ๋กœ ์œ ์ง€ ๊ด€๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค.

๋งˆ์ง€๋ง‰์œผ๋กœ ๋ฉ‹์ง„ ์‹ค์ œ ์‚ฌ๋ก€๋ฅผ ์ œ๊ณตํ•œ @EricSimons ์—๊ฒŒ ํŠน๋ณ„ํ•œ ๊ฐ์‚ฌ๋ฅผ ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

์‹ค์ œ๋กœ http://redux.js.org/docs/faq/Miscellaneous.html#miscellaneous -real-projects ์—์„œ ์—ฌ๋Ÿฌ ์‹ค์ œ React ๋ฐ Redux ์•ฑ์„ ๊ฐ€๋ฆฌํ‚ค๋Š” FAQ ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. (์‚ฌ์‹ค ๊ทธ Sound-Redux ์•ฑ์„ ๋ณธ ์ ์ด ์žˆ๋Š” ๊ฑธ๋กœ ์•„๋Š”๋ฐ, ๋‚ด ๋ชฉ๋ก์— ์ถ”๊ฐ€ํ•œ ๊ฒƒ ๊ฐ™์ง€๋Š” ์•Š๋‹ค. ํ•ด๋ด์•ผ๊ฒ ๋‹ค.)

์šฐ๋ฆฌ๊ฐ€ ํ•  ์ˆ˜ ์žˆ๋Š” "์‹ค์ œ" ์•ฑ์˜ ์ˆ˜๋ฅผ ๊ณ ๋ คํ•  ๋•Œ ๋” ์ด์ƒ ๋” ํฐ ์˜ˆ์ œ๋ฅผ Redux ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์— ์ง์ ‘ ์ถ”๊ฐ€ํ•  ์ฆ‰๊ฐ์ ์ธ ํ•„์š”์„ฑ์ด ์—†์–ด ๋ณด์ธ๋‹ค๋Š” ์ด์œ ๋กœ ์ด ๋ฌธ์ œ๋ฅผ ์ข…๋ฃŒํ•˜๊ณ  ์ข…๋ฃŒํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ฐ€๋ฆฌํ‚ค๋‹ค. ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ํŠน์ • ์˜ˆ๋ฅผ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์— ์ ๊ทน์ ์œผ๋กœ ๊ธฐ์—ฌํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ ๋ฌด์–ธ๊ฐ€๋ฅผ ๋งํ•˜๋ฉด ์ด๋ฅผ ๋‹ค์‹œ ์—ด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์˜ˆ, ํ† ๋ก ๊ณผ ์˜ˆ์— ๊ธฐ์—ฌํ•œ ๋ชจ๋“  ๋ถ„๋“ค๊ป˜ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค!

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