Redux-saga

kirin.logยท2021๋…„ 9์›” 8์ผ
0
post-custom-banner

๐Ÿถ redux-saga

  • redux-saga๋Š” ๋น„๋™๊ธฐ(=์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ)์˜ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•œ ๋ฏธ๋“ค์›จ์–ด ์ด๋‹ค.
  • ์ƒํƒœ๊ฐ’ ๋ณ€๊ฒฝ์€ ๋น„๋™๊ธฐ๋กœ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค. API ํ˜ธ์ถœ์„ ํ†ตํ•ด์„œ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„ ์˜ค๋Š” ๊ฒƒ์ด ๋Œ€ํ‘œ์ ์ธ ๋น„๋™๊ธฐ ์ฝ”๋“œ์ด๋‹ค. redux-saga๋Š” ์•ก์…˜์„ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜๋‹ค๊ฐ€, ํŠน์ • ์•ก์…˜์ด ๋ฐœ์ƒํ•˜๋ฉด ํŠน์ • ์ž‘์—…(์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ ์‹คํ–‰, ๋‹ค๋ฅธ ์•ก์…˜ ๋””์ŠคํŒจ์น˜, ์ƒํƒœ ์กฐํšŒ ๋“ฑ)์„ ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค.
  • React๋Š” Redux ์•ก์…˜์„ ์ˆ˜ํ–‰ํ•˜๋ฉด Redux-Saga์—์„œ ๋””์ŠคํŒจ์น˜ํ•˜์—ฌ Redux์˜ ์•ก์…˜์„ ๊ฐ€๋กœ์ฑˆ๋‹ค. ์ค‘๊ฐ„์— ๊ฐ€๋กœ์ฑˆ ์•ก์…˜์˜ ์—ญํ• ์„ ์ˆ˜ํ–‰ ํ›„, ๋‹ค์‹œ ์•ก์…˜์„ ๋ฐœํ–‰ํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ์ด๋ฒคํŠธ๋ฅผ ์ˆ˜ํ–‰์‹œํ‚จ๋‹ค. (saga๋Š” ์•ก์…˜์— ๋Œ€ํ•œ ๋ฆฌ์Šค๋„ˆ๋กœ์„œ, ์•ก์…˜์„ ํ†ตํ•œ ์‹คํ–‰/์ค‘๋‹จ/์ทจ์†Œ ๋“ฑ์„ ๊ฐ€๋Šฅ์ผ€ ํ•ด์ฃผ๋Š” ๊ฒƒ)
  • ๋น„์Šทํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ๋Š” Redux-Thunk๊ฐ€ ์žˆ์œผ๋ฉฐ, Saga๊ฐ€ Thunk๋ณด๋‹ค ์•„์ฃผ ์กฐ๊ธˆ ๋” ๋Ÿฌ๋‹ ์ปค๋ธŒ๊ฐ€ ์กด์žฌํ•œ๋‹ค. ์‚ฌ์‹ค์ƒ์˜ ๋‘ ๊ฐœ ๋ชจ๋‘ Redux์˜ ๋ฏธ๋“ค์›จ์–ด๋กœ์„œ ๊ฐ™์€ ์—ญํ• ์„ ํ•˜์ง€๋งŒ Redux-Saga์—์„œ๋งŒ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฐœ๋…์ด ์žˆ๋‹ค. ์ œ๋„ˆ๋ ˆ์ดํ„ฐ์™€ ์ดํŽ™ํŠธ ์ด๋‹ค. (์ œ๋„ˆ๋ ˆ์ดํ„ฐ๋Š” Javascript์— ํฌํ•จ๋œ ๊ธฐ๋Šฅ์ด์ง€๋งŒ Saga์—์„œ๋Š” ์ด๋ฅผ ์ ๊ทน ํ™œ์šฉํ•œ๋‹ค.

๐Ÿช ์ œ๋„ˆ๋ ˆ์ดํ„ฐ
Saga๋Š” ์ œ๋„ˆ๋ ˆ์ดํ„ฐ๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ชจ๋“  ๊ฒƒ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ๋ฌธ๋ฒ•์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ES6์— ํฌํ•จ๋œ ๋ฌธ๋ฒ•์ด๋‹ค. next()๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด {value์™€ done ํ”„๋กœํผํ‹ฐ}๊ฐ€ ํฌํ•จ๋œ Result๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

// generator ๋ฌธ๋ฒ•

function* thisIsGenerator() {
  console.log('First Call');
  yield 'First';
 
  console.log('Second Call');
  yield 'Second';

  console.log('Third Call');
}
const thisIsGeneratorObject = thisIsGenerator();

// next()๋กœ ํ˜ธ์ถœํ•˜์—ฌ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ๊ฐ์ฒด ๋ฐ˜ํ™˜( { value:__, done:__ } )
thisIsGeneratorObject.next();       // First Call { value: 'First', done: false }
thisIsGeneratorObject.next();       // Second Call { value: 'Second', done: false }
thisIsGeneratorObject.next();       // Third Call { value: 'Undefined', done: true }

โ— ์ผ๋ฐ˜ ํ•จ์ˆ˜์™€ ๋‹ค๋ฅธ ์ ์€, ์ฝ”๋“œ ๋ธ”๋ก์ด ํ•œ ๋ฒˆ์— ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค.
์ฒ˜์Œ next()๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ฒซ ๋ฒˆ์งธ yield๊นŒ์ง€ ํ˜ธ์ถœ๋˜๊ณ  ์ผ์‹œ ์ค‘์ง€ ๋œ๋‹ค.
๋‘ ๋ฒˆ์งธ next()๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ๋‘ ๋ฒˆ์งธ yield๊นŒ์ง€ ํ˜ธ์ถœ๋˜๊ณ  ๋˜ ์ผ์‹œ ์ค‘์ง€ ๋œ๋‹ค.
๋งˆ์ง€๋ง‰์œผ๋กœ next()๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์•ผ๋งŒ, Result๊ฐ์ฒด์˜ done ํ”„๋กœํผํ‹ฐ ๊ฐ’์ด true๊ฐ€ ๋œ๋‹ค.

โ— generator ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค ๋•Œ๋Š” function* ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
const generator = generatorFunction() ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ ๋‹ค. generator ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค๊ณ  ํ•ด์„œ ํ•ด๋‹น ํ•จ์ˆ˜์˜ ์ฝ”๋“œ๊ฐ€ ๋ฐ”๋กœ ์‹œ์ž‘๋˜์ง€๋Š” ์•Š๋Š”๋‹ค. generator.next() ๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜๊ณ  yield๋ฅผ ํ•œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์ฝ”๋“œ ํ๋ฆ„์„ ๋ฉˆ์ถ˜๋‹ค. ๋˜๋‹ค์‹œ generator.next()๋ฅผ ํ•ด์•ผ ์ด์–ด์ง„๋‹ค.

๐Ÿช ์ดํŽ™ํŠธ
์ดํŽ™ํŠธ๋Š” ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•  ๋‚ด์šฉ์„ ๋‹ด๊ณ  ์žˆ๋‹ค. ์‚ฌ๊ฐ€๋ฅผ ์‹คํ–‰ํ•˜๋Š” ์‹คํ–‰๋ถ€์—๊ฒŒ ์–ด๋– ํ•œ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ• ์ง€ ์•Œ๋ ค์ฃผ๋Š” ์ผ๋ฐ˜ ๊ฐ์ฒด(Plain Object)์ด๋‹ค.
Redux-Saga์—์„œ๋Š” ์ด๋Ÿฌํ•œ ์ดํŽ™ํŠธ ๋“ค์„ yield๋ฅผ ์ด์šฉํ•˜์—ฌ ํ˜ธ์ถœํ•˜๊ณ  ์ˆ˜ํ–‰๋œ ๋‚ด์šฉ์„ ๋‹ค์‹œ ๋Œ๋ ค ๋ฐ›์•„ ๊ทธ ๋‹ค์Œ ์•ก์…˜๋“ค์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. ๊ฒฐ๊ตญ Redux-Saga๋Š” ์ œ๋„ˆ๋ ˆ์ดํ„ฐ๋ฅผ ํ†ตํ•ด ์ดํŽ™ํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
์ผ๋ฐ˜์ ์œผ๋กœ put(), call(), select() ๋“ฑ์˜ ํ—ฌํผ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•จ์œผ๋กœ์จ ํ•ด๋‹น ์ดํŽ™ํŠธ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
๋Œ€ํ‘œ์ ์ธ ๊ฒƒ๋“ค๋กœ๋Š” take, call, put ๋“ฑ์ด ์žˆ๋‹ค.

๐Ÿ‘‰ redux-saga์™€ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ

๋ฆฌ๋•์Šค ์‚ฌ๊ฐ€๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ๋ฌธ๋ฒ•์„ ์ด์šฉํ•œ๋‹ค(์‚ฌ๊ฐ€ = ์ œ๋„ˆ๋ ˆ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜).

function ํ˜•ํƒœ์˜ ํŠน์ˆ˜ํ•œ ํ•จ์ˆ˜๋กœ ์ƒ์„ฑ๋œ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ๊ฐ์ฒด๋Š” { value, done } ์†์„ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์ •๋ง ํŠน์ˆ˜ํ•œ ๊ฐ์ฒด๋‹ค.

์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ yield๋ผ๊ณ  ํ•˜๋Š” ํ‚ค์›Œ๋“œ๋กœ ๋‹ค์Œ ๊ฐ’, ๋™์ž‘์„ ์ œ์–ดํ•œ๋‹ค(์‚ฌ๊ฐ€๋Š” yield ํ‘œํ˜„์‹์„ ๋งŒ๋‚  ๋•Œ๋งˆ๋‹ค ์‹คํ–‰์ด ์ค‘๋‹จ).
๊ทธ๋ž˜์„œ while(true)์™€ ๊ฐ™์€ ๋ฌดํ•œ๋ฃจํ”„๋„ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. yield ํ‚ค์›Œ๋“œ๋ฅผ ๋งŒ๋‚˜๋ฉด ๋’ค์˜ ๋กœ์ง์ด๋‚˜ ๊ฐ’์„ ์ „๋‹ฌํ•˜๊ณ  ์šฐ์„  ํ•จ์ˆ˜์—์„œ ๋ฒ—์–ด๋‚˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
โ— .next()๋ผ๊ณ  ํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๋ฐ›์•˜์„ ๋•Œ๋งŒ ๋‹ค์Œ ๋™์ž‘์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋น„๋™๊ธฐ์ ์ธ ์ฒ˜๋ฆฌ๋ฅผ ์ œ์–ดํ•˜๊ธฐ ์ข‹๋‹ค. (next() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•จ์œผ๋กœ์จ ์‚ฌ๊ฐ€๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค. next()ํ•จ์ˆ˜์˜ ์ธ์ž๋กœ ๋„˜๊ธฐ๋Š” ๊ฐ’์€ ํ•ด๋‹น ์‚ฌ๊ฐ€์˜ ์‹คํ–‰์ด ์ค‘๋‹จ๋˜์–ด ์žˆ๋Š” ์œ„์น˜์˜ yield ํ‘œํ˜„์‹ ์ž๋ฆฌ๋ฅผ ์ฑ„์›Œ์ค€๋‹ค)

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


๐Ÿˆ Redux ๊ฐ„๋‹จ ์š”์•ฝ

๐Ÿ“Œ ์Šคํ† ์–ด

  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ƒํƒœ๋ฅผ ํŠธ๋ฆฌ ๊ตฌ์กฐ๋กœ ๊ด€๋ฆฌํ•œ๋‹ค.
  • ์ƒํƒœ๋ฅผ ๋ฐ”๊พธ๋ ค๋ฉด dispatch() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด์„œ action์„ ๋””์ŠคํŒจ์น˜ ํ•œ๋‹ค.
  • ๋ฆฌ๋•์Šค๋Š” ์Šคํ† ์–ด๊ฐ€ ์ƒ์„ฑ๋˜๋Š” ์ฆ‰์‹œ ๋”๋ฏธ ์•ก์…˜์„ ๋””์ŠคํŒจ์น˜ ํ•˜์—ฌ ์Šคํ† ์–ด์˜ ์ดˆ๊ธฐ ์ƒํƒœ๋ฅผ ์„ค์ •ํ•œ๋‹ค.

๐Ÿ“Œ ๋ฏธ๋“ค์›จ์–ด store => next => dispatch

  • ๋ฆฌ๋•์Šค์˜ ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•˜๊ธฐ ์œ„ํ•œ ์ˆ˜๋‹จ, dispatch() ํ•จ์ˆ˜๋ฅผ ๋ž˜ํ•‘ํ•˜๋Š” ์—ญํ•  ์ˆ˜ํ–‰.
  • ๋‹ค์Œ ๋ฏธ๋“ค์›จ์–ด์˜ dispatch() ํ•จ์ˆ˜๋ฅผ next ์ธ์ž๋กœ ๋ฐ›์•„์„œ ์ƒˆ๋กœ์šด dispatch() ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด๋‚ธ๋‹ค.
  • ๊ฐ ๋ฏธ๋“ค์›จ์–ด๋Š” ๋””์ŠคํŒจ์น˜ ๋œ ์•ก์…˜์„ ์ง์ ‘ ์ฒ˜๋ฆฌํ•˜๊ฑฐ๋‚˜ ๋‹ค์Œ ๋ฏธ๋“ค์›จ์–ด์˜ dispatch() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.

๐Ÿ“Œ ์Šคํ† ์–ด ์ธํ•ธ์„œ storeCreator => storeCreator

  • ์Šคํ† ์–ด ์ƒ์„ฑ์ž๋ฅผ ์ธ์ž๋กœ ๋ฐ›์•„์„œ ์ƒˆ๋กœ์šด (๊ฐœ์„ ๋œ) ์Šคํ† ์–ด ์ƒ์„ฑ์ž๋ฅผ ๋งŒ๋“ค์–ด๋‚ธ๋‹ค.
  • ์ผ๋ฐ˜์ ์œผ๋กœ, createStore() ํ•จ์ˆ˜์˜ ๋งˆ์ง€๋ง‰ ์ธ์ž๋กœ ์Šคํ† ์–ด ์ธํ•ธ์„œ๋ฅผ ๋„˜๊ฒจ์ค€๋‹ค.

๐Ÿ“Œ ๋ฆฌ๋•์Šค ๋™์ž‘ ์›๋ฆฌ

  • ๋ฆฌ๋•์Šค์˜ ์Šคํ† ์–ด๋Š” Context๋กœ ๊ตฌ์„ฑ๋˜์–ด Provider ์ปดํฌ๋„ŒํŠธ์˜ value props๋กœ ์ „๋‹ฌ๋œ๋‹ค. ( store={store} )
  • ํ•ด๋‹น Context๋Š” ๊ตฌ์ฒด์ ์œผ๋กœ { store, subscription }๊ณผ ๊ฐ™์€ ํ˜•ํƒœ๋ฅผ ๋ ๊ณ  ์žˆ๋‹ค.
  • connect() ํ•จ์ˆ˜์— ์˜ํ•ด ๋งŒ๋“ค์–ด์ง„ ์ปดํฌ๋„ŒํŠธ๋‚˜ useSelector() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ ์ปดํฌ๋„ŒํŠธ๋Š” ์•ก์…˜์ด ๋””์ŠคํŒจ์น˜ ๋œ ํ›„ (์–ด๋– ํ•œ ๊ตฌ๋… ๋ฉ”์ปค๋‹ˆ์ฆ˜์— ์˜ํ•ด) ๊ฐ•์ œ์ ์œผ๋กœ ๋ฆฌ๋ Œ๋”๋ง์ด ์œ ๋ฐœ๋œ๋‹ค. ์ด๋•Œ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋Š” Provider ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ œ๊ณตํ•ด์ฃผ๋Š” ๋ฆฌ๋•์Šค ์Šคํ† ์–ด์˜ ์ƒํƒœ๋ฅผ ์ฝ๋Š”๋‹ค.
  • ์ฐธ๊ณ ๋กœ ์Šคํ† ์–ด๋Š” ๋Š˜ ์ฐธ์กฐ๊ฐ’์ด ๊ฐ™์€ ๊ฐ€๋ณ€ ๊ฐ์ฒด์— ํ•ด๋‹นํ•˜๋ฉฐ, Provider ์ปดํฌ๋„ŒํŠธ๋Š” ์ค‘๊ฐ„์— ์Šคํ† ์–ด๊ฐ€ ๋‹ค๋ฅธ ๊ฑธ๋กœ ๋ฐ”๋€Œ์ง€ ์•Š๋Š” ์ด์ƒ ๋Š˜ ๊ฐ™์€ ์ฐธ์กฐ๊ฐ’์„ ๊ฐ€์ง€๋Š” ๊ฐ์ฒด๋ฅผ Context๋กœ ๊ตฌ์„ฑํ•˜๋„๋ก ๊ตฌํ˜„๋œ๋‹ค. ๋”ฐ๋ผ์„œ ์•ก์…˜์„ ๋””์ŠคํŒจ์น˜ ํ•˜๋“  ๋ฌด์—‡์„ ํ•˜๋“ , Provider ์ปดํฌ๋„ŒํŠธ์— ์˜ํ•ด ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋“ค์ด ์ „๋ถ€ ๋ฆฌ๋ Œ๋”๋ง ๋  ์ผ์€ ์—†๋‹ค. ์ฆ‰, ๋ฆฌ๋ Œ๋”๋ง์€ ์˜ค๋กœ์ง€ ๊ตฌ๋… ๋ฉ”์ปค๋‹ˆ์ฆ˜์— ์˜์กดํ•˜์—ฌ ๋ฐœ์ƒํ•  ๋ฟ์ด๋‹ค.

๐Ÿ‘‰ redux-saga ์„ค์น˜ ๋ฐ ๊ธฐ๋ณธ ์„ธํŒ…

npm i redux-saga

์„ค์น˜ ํ›„ ๋ฏธ๋“ค์›จ์–ด์— ์ง‘์–ด๋„ฃ๋Š”๋‹ค.

๐Ÿ‘‰ redux-saga ์ฝ”๋“œ ๊ตฌํ˜„ํ•ด๋ณด๊ธฐ (react.js๋ฒ„์ „)

// store.js ํŒŒ์ผ ์ƒ์„ฑ

import { createStore, combineReducers, applyMiddleware } from 'redux';
import createSagaMiddleware from 'redux-saga';
import reducer from './reducer';       // reducer๊ฐ€ ์ •์˜๋œ ํŒŒ์ผ import
import rootSaga from './saga';   // index.js์˜ rootSaga ํŒŒ์ผ import

// ์—ฌ๋Ÿฌ ์ƒํƒœ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋Š” ๋ฆฌ๋“€์„œ๋“ค์„ ํ•˜๋‚˜์˜ ๋ฆฌ๋“€์„œ ํ•จ์ˆ˜๋กœ ํ•จ์นœ๋‹ค.
const rootReducer = combineReducers({ reducer });

// ๋ฆฌ๋•์Šค ์‚ฌ๊ฐ€์—์„œ createSagaMiddleware๋ฅผ ๋ถˆ๋Ÿฌ์™€์„œ, sagaMiddleware ๊ฐ์ฒด ์ƒ์„ฑ
const sagaMiddleware = createSagaMiddleware();

// store ์ƒ์„ฑ (sagaMiddleware ๊ฐ์ฒด ์—ฐ๊ฒฐ โžก applyMiddleware ํ•จ์ˆ˜์˜ ์ธ์ž๋กœ ๋„˜๊ฒจ์ฃผ๊ธฐ)
const store = createStore(rootReducer, applyMiddleware(sagaMiddleware));

// ์‚ฌ๊ฐ€ ๋ฏธ๋“ค์›จ์–ด์—์„œ run ๋ฉ”์„œ๋“œ์— "ํ†ตํ•ฉ ์‚ฌ๊ฐ€ ํ•จ์ˆ˜(rootSagaํ•จ์ˆ˜)"๋ฅผ ์—ฐ๊ฒฐ/์‹คํ–‰์‹œํ‚จ๋‹ค.
sagaMiddleware.run(rootSaga);

export default store;
// app.js

import withReduxSaga from 'next-redux-saga';
(...)
export default Wrapper.withRedux(withReduxSaga(App));

๐Ÿ‘‰ sagaํ•จ์ˆ˜ / ๋ถ€์ˆ˜ํšจ๊ณผ ํ•จ์ˆ˜๋“ค

  • ๋ฆฌ๋•์Šค ์‚ฌ๊ฐ€์˜ ๋ถ€์ˆ˜ํšจ๊ณผ ํ•จ์ˆ˜๊ฐ€ ๋Œ€๋ถ€๋ถ„์˜ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ํ•œ๋‹ค.
// saga/index.js

import { all, fork } from 'redux-saga/effects';  // ๋ถ€์ˆ˜ํšจ๊ณผ ํ•จ์ˆ˜(all, fork)
import userSaga from './user';

// yield ํ‚ค์›Œ๋“œ ๋’ค์— ๋ฆฌ๋•์Šค ์‚ฌ๊ฐ€์˜ ๋ถ€์ˆ˜ํšจ๊ณผ ํ•จ์ˆ˜๊ฐ€ ์˜จ๋‹ค.
// rootSaga ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜ ๋‚ด๋ถ€์— ๋“ฑ๋ก๋œ yield ํ‚ค์›Œ๋“œ์—๋Š” all์ด๋ผ๊ณ  ํ•˜๋Š” ๋ถ€์ˆ˜ํšจ๊ณผ ํ•จ์ˆ˜๊ฐ€ ๋ถ™๋Š”๋‹ค. 
// ๋“ฑ๋ก๋œ ํ•จ์ˆ˜๊ฐ€ ๋™์‹œ์— ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋„๋ก ์ฒ˜๋ฆฌํ•œ๋‹ค. (rootSaga๋ฅผ ๋งŒ๋“ค์–ด์„œ ํ•˜๋‚˜๋กœ ํ•ฉ์น˜๋Š” ์ž‘์—…)
export default function* rootSaga() {
  yield all([fork(userSaga)]);
}
// fork ๋ถ€์ˆ˜ํšจ๊ณผ ํ•จ์ˆ˜๋Š” ์•ก์…˜์„ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.

put : dispatch์˜ saga๋ฒ„์ „์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค. Action์„ dispatchํ•œ๋‹ค. ( = store.dispatch()ํ•จ์ˆ˜)

all : ๋ฐฐ์—ด์„ ๋ฐ›์•„์„œ, ๋ฐฐ์—ด์— ๋“ค์–ด์žˆ๋Š” ๊ฒƒ๋“ค์„ ํ•œ๋ฒˆ์— ์‹คํ–‰ํ•œ๋‹ค.

call : ๋™๊ธฐ์ ์œผ๋กœ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.

fork: ๋น„๋™๊ธฐ์ ์œผ๋กœ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.

profile
boma91@gmail.com
post-custom-banner

0๊ฐœ์˜ ๋Œ“๊ธ€