์ฐ๋ฆฌ ํ์ ์ง๊ธ ๋ช ๋ฌ ๋์ Redux๋ฅผ ์ฌ์ฉํ๊ณ ์์ต๋๋ค. ๊ทธ ๊ณผ์ ์์ ๋๋ ๋๋๋ก ๊ธฐ๋ฅ์ ๋ํด ์๊ฐํ๊ณ "์ด๊ฒ์ด ์ก์ ์์ฑ๊ธฐ ๋๋ ๊ฐ์๊ธฐ์ ์ํฉ๋๊น?" ๋ฌธ์๋ ์ด ์ฌ์ค์ ๋ํด ์ฝ๊ฐ ๋ชจํธํ ๊ฒ ๊ฐ์ต๋๋ค. (์๋๋ฉด ์ ๊ฐ ๋ค๋ฃฌ ๋ถ๋ถ์ ๋์ณค์ ์๋ ์์ต๋๋ค. ์ด ๊ฒฝ์ฐ ์ฌ๊ณผ๋๋ฆฝ๋๋ค.) ๊ทธ๋ฌ๋ ๋ ๋ง์ ์ฝ๋์ ๋ ๋ง์ ํ ์คํธ๋ฅผ ์์ฑํ๋ฉด์ _ํด์ผ ํ๋_ ์์น์ ๋ํด ๋ ๊ฐํ ์๊ฒฌ์ ๊ฐ๊ฒ ๋์๊ณ ๊ฐ์น๊ฐ ์์ ๊ฒ์ด๋ผ๊ณ ์๊ฐํ์ต๋๋ค. ๋ค๋ฅธ ์ฌ๋๋ค๊ณผ ๊ณต์ ํ๊ณ ํ ๋ก ํฉ๋๋ค.
์ฌ๊ธฐ ๋ด ์๊ฐ์ด ์์ต๋๋ค.
์ด ์ฒซ ๋ฒ์งธ ๊ฒ์ Redux์ ์๋ฐํ ๊ด๋ จ์ด ์์ง๋ง ์๋์์ ๊ฐ์ ์ ์ผ๋ก ์ธ๊ธํ๊ธฐ ๋๋ฌธ์ ์ด์จ๋ ๊ณต์ ํฉ๋๋ค. ์ฐ๋ฆฌ ํ์ rackt/reselect ๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ฐ๋ฆฌ๋ ์ผ๋ฐ์ ์ผ๋ก ์ํ ํธ๋ฆฌ์ ์ฃผ์ด์ง ๋ ธ๋(์: MyPageSelectors)์ ๋ํ ์ ํ๊ธฐ๋ฅผ ๋ด๋ณด๋ด๋ ํ์ผ์ ์ ์ํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ "์ค๋งํธ" ์ปจํ ์ด๋๋ ์ด๋ฌํ ์ ํ๊ธฐ๋ฅผ ์ฌ์ฉํ์ฌ "๋ฉ์ฒญํ" ๊ตฌ์ฑ ์์๋ฅผ ๋งค๊ฐ๋ณ์ํํฉ๋๋ค.
์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ (์ฌ์ ํ์ ๋งฅ๋ฝ์์๋ฟ๋ง ์๋๋ผ) ๋ค๋ฅธ ์์น์์ ์ด๋ฌํ ๋์ผํ ์ ํ๊ธฐ๋ฅผ ์ฌ์ฉํ๋ฉด ์ถ๊ฐ ์ด์ ์ด ์์์ ๊นจ๋ฌ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ์๋ํ๋ ํ ์คํธ์์ ์ฌ์ฉํฉ๋๋ค. ์ฐ๋ฆฌ๋ ๋ํ action-creators์ ์ํด ๋ฐํ๋ ์ฝํฌ ์์๋ ์ฌ์ฉํฉ๋๋ค(์๋์์ ์์ธํ).
๋ฐ๋ผ์ ์ฒซ ๋ฒ์งธ ๊ถ์ฅ ์ฌํญ์ ๋๊ธฐ์์ผ๋ก ๋ฐ์ดํฐ์ ์ก์ธ์คํ๋ ๊ฒฝ์ฐ์๋ _๋ชจ๋ ๊ณณ์์_ ๊ณต์ ์ ํ๊ธฐ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์
๋๋ค(์: myValueSelector(state)
๋ณด๋ค state.myValue
myValueSelector(state)
์ ํธ). ์ด๋ ๊ฒ ํ๋ฉด ๋ฏธ๋ฌํ๊ฒ ์ ์๋์ง ์์ ๊ฐ์ผ๋ก ์ด์ด์ง๋ ์๋ชป๋ ์ ํ์ ๋ณ์ ๊ฐ๋ฅ์ฑ์ด ์ค์ด๋ค๊ณ ์์ ๊ตฌ์กฐ ๋ฑ์ ๋ณ๊ฒฝ์ด ๊ฐ์ํ๋ฉ๋๋ค.
๋๋ ์ด๊ฒ์ด ๋น์ฅ ๋ช ๋ฐฑํ์ง ์์์ง๋ผ๋ ์ด๊ฒ์ด ๋งค์ฐ ์ค์ํ๋ค๊ณ ์๊ฐํ๋ค. ๋น์ฆ๋์ค ๋ก์ง์ ์ก์ ํฌ๋ฆฌ์์ดํฐ์ ์ํฉ๋๋ค. ๊ฐ์๊ธฐ๋ ์ด๋ฆฌ์๊ณ ๋จ์ํด์ผ ํฉ๋๋ค. ๋ง์ ๊ฐ๋ณ์ ์ธ ๊ฒฝ์ฐ์๋ ์ค์ํ์ง ์์ง๋ง ์ผ๊ด์ฑ์ด ์ข์ผ๋ฏ๋ก _์ผ๊ด์ ์ผ๋ก_ ํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ข์ต๋๋ค. ๋ค์๊ณผ ๊ฐ์ ๋ช ๊ฐ์ง ์ด์ ๊ฐ ์์ต๋๋ค.
์ํ์ ํญ๋ชฉ ๋ชฉ๋ก๊ณผ ๊ด๋ จ๋ ๋ฉํ๋ฐ์ดํฐ๊ฐ ์๋ค๊ณ ์์ํด ๋ณด์ธ์. ํญ๋ชฉ์ด ์์ , ์ถ๊ฐ ๋๋ ๋ชฉ๋ก์์ ์ ๊ฑฐ๋ ๋๋ง๋ค ๋ฉํ๋ฐ์ดํฐ๋ฅผ ์ ๋ฐ์ดํธํด์ผ ํฉ๋๋ค. ๋ชฉ๋ก๊ณผ ํด๋น ๋ฉํ๋ฐ์ดํฐ๋ฅผ ๋๊ธฐํ ์ํ๋ก ์ ์งํ๊ธฐ ์ํ "๋น์ฆ๋์ค ๋ก์ง"์ ๋ค์๊ณผ ๊ฐ์ ์์น์ ์์ ์ ์์ต๋๋ค.
updateMetadata
์์
๋ ํธ์ถํฉ๋๋ค. ์ด ์ ๊ทผ ๋ฐฉ์์ (๋ฐ๋ผ๊ฑด๋) ๋ช
๋ฐฑํ ์ด์ ๋ก ๋์ฐํฉ๋๋ค.์์ ์ ํ ์ฌํญ์ ๊ฐ์ํ ๋ ์ต์ 3์ด ํ์คํ ๋ ์ข์ต๋๋ค. ์ต์ 1๊ณผ 3 ๋ชจ๋ ๊นจ๋ํ ์ฝ๋ ๊ณต์ ๋ฅผ ์ง์ํ์ง๋ง ์ต์ 3๋ง ๋ชฉ๋ก ๋ฐ/๋๋ ๋ฉํ๋ฐ์ดํฐ ์ ๋ฐ์ดํธ๊ฐ ๋น๋๊ธฐ์์ผ ์ ์๋ ๊ฒฝ์ฐ๋ฅผ ์ง์ํฉ๋๋ค. (์๋ฅผ ๋ค์ด ์น ์์ ์์ ์์กดํ ์ ์์ต๋๋ค.)
์์ , ๊ฐ์๊ธฐ ๋ฐ ์ ํ๊ธฐ๋ฅผ ํ ์คํธํ๋ ๊ฐ์ฅ ํจ์จ์ ์ธ ๋ฐฉ๋ฒ์ ํ ์คํธ๋ฅผ ์์ฑํ ๋ "๋" ์ ๊ทผ ๋ฐฉ์์ ๋ฐ๋ฅด๋ ๊ฒ์ ๋๋ค. ์ด๊ฒ์ ๊ฐ๊ฐ์ ๊ฐ๋ณ์ ์ผ๋ก ์ด์ ์ ๋ง์ถ๋ 3์ธํธ์ ํ ์คํธ๊ฐ ์๋๋ผ ์ฃผ์ด์ง ์ผ๋ จ์ ์์ , ๊ฐ์๊ธฐ ๋ฐ ์ ํ๊ธฐ๋ฅผ ๋ค๋ฃจ๋ ํ๋์ ํ ์คํธ ์ธํธ๋ฅผ ์์ฑํด์ผ ํจ์ ์๋ฏธํฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์ค์ ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ฐ์ํ๋ ์ํฉ์ ๋ณด๋ค ์ ํํ๊ฒ ์๋ฎฌ๋ ์ด์ ํ๊ณ ๋น์ฉ ๋๋น ํจ๊ณผ๋ฅผ ๊ทน๋ํํ ์ ์์ต๋๋ค.
๋ ์ธ๋ถํํ๋ฉด ์ก์ ์์ฑ์์ ์ด์ ์ ๋ง์ถ ํ ์คํธ๋ฅผ ์์ฑํ ๋ค์ ์ ํ์๋ฅผ ์ฌ์ฉํ์ฌ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํ๋ ๊ฒ์ด ์ ์ฉํ๋ค๋ ๊ฒ์ ์์์ต๋๋ค. (๋ฆฌ๋์๋ฅผ ์ง์ ํ ์คํธํ์ง ๋ง์ญ์์ค.) ์ค์ํ ๊ฒ์ ์ฃผ์ด์ง ์์ ์ด ์์ํ ์ํ๋ก ๋ฐ์ํ๋ค๋ ๊ฒ์ ๋๋ค. (๊ณต์ ) ์ ํ๊ธฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ด ๊ฒฐ๊ณผ๋ฅผ ํ์ธํ๋ ๊ฒ์ ๋จ์ผ ํจ์ค์์ ์ธ ๊ฐ์ง ๋ชจ๋๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
Immutable.js ๋๋ ๊ธฐํ๋ฅผ ์ฌ์ฉํ๋์ง ๊ถ๊ธํฉ๋๋ค. REDUX ๊ฒ๋ค์ ์์์์ ๋๋ ๋ด๊ฐ ๋ถ๋ณ์ ์ฌ์ฉํ์ง ์์ํ ์ ์์๋ค ๋ด์ฅํ์ง๋ง, ๋ถ๋ณ๊ฐ ์์ข ์ํ๋ ๋ฐ ๋์์ด ๋๋ ๊ฝค ๋ง์ด ์ค์ฒฉ ๋ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง๊ณ _do_.
์ฐ์. ๊ทธ๊ฒ์ ์ธ๊ธํ๋ ๊ฒ์ _not_ ์ ์๊ฒ ์์ด ์ผ๋ง๋ ๊ฐ๊ณผ๋ ์ผ์ ๋๊น? ์! ์ฐ๋ฆฌ๋ ๋ถ๋ณ์ ์ฌ์ฉํฉ๋๋ค! ๋น์ ์ด ๋งํ๋ฏ์ด, ์๋นํ ๊ฒ์ ์ํด ๊ทธ๊ฒ์ ์ฌ์ฉํ์ง _์๋_ ์์ํ๊ธฐ ์ด๋ ต์ต๋๋ค.
@bvaughn ๋ด๊ฐ ๊ณ ์ฌํ๋ ์์ญ ์ค ํ๋๋ Immutable๊ณผ ๊ตฌ์ฑ ์์ ์ฌ์ด์ ์ ์ ๊ทธ๋ฆด ์์น์ ๋๋ค. ๋ณ๊ฒฝํ ์ ์๋ ๊ฐ์ฒด๋ฅผ ๊ตฌ์ฑ ์์์ ์ ๋ฌํ๋ฉด ์์ ๋ ๋๋ง ๋ฐ์ฝ๋ ์ดํฐ/๋ฏน์ค์ธ์ ๋งค์ฐ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์์ง๋ง ๊ตฌ์ฑ ์์์ IMmutable ์ฝ๋(๋ด๊ฐ ์ข์ํ์ง ์๋)๊ฐ ์๊น๋๋ค. ์ง๊ธ๊น์ง ๋๋ ๊ทธ๋ฅ ๊ตด๋ณตํ๊ณ ๊ทธ๊ฒ์ ํด๋์ง๋ง Immutable.js์ ๋ฉ์๋์ ์ง์ ์ก์ธ์คํ๋ ๋์ render() ๋ฉ์๋์์ ์ ํ๊ธฐ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ ๊ฐ์ต๋๊น?
์์งํ ์ด๊ฒ์ ์ฐ๋ฆฌ๊ฐ ์์ง ์๊ฒฉํ ์ ์ฑ
์ ์ ์ํ์ง ์์ ๊ฒ์
๋๋ค. ์ข
์ข
์ฐ๋ฆฌ๋ "์ค๋งํธ" ์ปจํ
์ด๋์์ ์ ํ๊ธฐ๋ฅผ ์ฌ์ฉํ์ฌ ๋ณ๊ฒฝํ ์ ์๋ ๊ฐ์ฒด์ ๊ธฐ๋ณธ ๊ฐ์ ์ถ๊ฐํ ๋ค์ ๊ธฐ๋ณธ ๊ฐ์ ๋ฌธ์์ด, ๋ถ์ธ ๋ฑ์ผ๋ก ๊ตฌ์ฑ ์์์ ์ ๋ฌํฉ๋๋ค. ๋๋๋ก ์ฐ๋ฆฌ๋ ๋ถ๋ณ ๊ฐ์ฒด๋ฅผ ์ ๋ฌํ์ง๋ง ๊ทธ๋ ๊ฒ ํ ๋ ๊ฑฐ์ ํญ์ Record
์ ํ์ ์ ๋ฌํ์ฌ ๊ตฌ์ฑ ์์๊ฐ ์ด๋ฅผ ๊ธฐ๋ณธ ๊ฐ์ฒด(๊ฒํฐ ํฌํจ)์ฒ๋ผ ์ทจ๊ธํ ์ ์๋๋ก ํฉ๋๋ค.
๋๋ ๋ฐ๋ ๋ฐฉํฅ์ผ๋ก ์์ง์ฌ์ ์ก์ ์ ์์๋ฅผ ๋ ํ์ฐฎ๊ฒ ๋ง๋ญ๋๋ค. ํ์ง๋ง ์ ๋ ์ด์ ๋ง redux๋ฅผ ์ฌ์ฉํ๊ธฐ ์์ํ์ต๋๋ค. ์ ๊ทผ ๋ฐฉ์์ ๋ํ ๋ช ๊ฐ์ง ์ง๋ฌธ:
1) ์ก์
์ ์์๋ฅผ ์ด๋ป๊ฒ ํ
์คํธํฉ๋๊น? ๋๋ ํ
์คํธํ๊ธฐ ์ฝ๊ธฐ ๋๋ฌธ์ ์ธ๋ถ ์๋น์ค์ ์์กดํ์ง ์๋ ์์ ๋๊ธฐ ํจ์๋ก ๊ฐ๋ฅํ ํ ๋ง์ ๋
ผ๋ฆฌ๋ฅผ ์ด๋ํ๋ ๊ฒ์ ์ข์ํฉ๋๋ค.
2) ํซ ๋ฆฌ๋ก๋ฉ๊ณผ ํจ๊ป ์๊ฐ ์ฌํ์ ์ฌ์ฉํฉ๋๊น? react redux devtools์ ๊น๋ํ ์ ์ค ํ๋๋ ํซ ๋ฆฌ๋ก๋ฉ์ด ์ค์ ๋๋ฉด ์คํ ์ด๊ฐ ์ ๋ฆฌ๋์์ ๋ํด ๋ชจ๋ ์์
์ ๋ค์ ์คํํ๋ค๋ ๊ฒ์
๋๋ค. ๋ด ๋
ผ๋ฆฌ๋ฅผ ์ก์
์ ์์๋ก ์ฎ๊ธฐ๋ฉด ์์ด ๋ฒ๋ฆด ๊ฒ์
๋๋ค.
3) ์ก์
์์ฑ์๊ฐ ์ฌ๋ฌ ๋ฒ ๋์คํจ์นํ์ฌ ํจ๊ณผ๋ฅผ ๊ฐ์ ธ์จ๋ค๋ฉด ์ํ๊ฐ ์ ์ ๋์ ์ ํจํ์ง ์์ ์ํ์ ์๋ค๋ ์๋ฏธ์
๋๊น? (๋์ค์ ๋น๋๊ธฐ์์ผ๋ก ๋์คํจ์นํ๋ ๊ฒ์ด ์๋๋ผ ์ฌ๋ฌ ๋๊ธฐ์ ๋์คํจ์น๋ฅผ โโ์๊ฐํ๊ณ ์์ต๋๋ค.)
์, ๊ฐ์๊ธฐ๊ฐ ์ํ์ ๊ตฌํ ์ธ๋ถ ์ฌํญ์ด๋ฉฐ ์ฟผ๋ฆฌ API๋ฅผ ํตํด ๊ตฌ์ฑ ์์์ ์ํ๋ฅผ ๋
ธ์ถํ๋ค๊ณ ๋งํ๋ ๊ฒ์ฒ๋ผ ๋ณด์
๋๋ค.
๋ค๋ฅธ ์ธํฐํ์ด์ค์ ๋ง์ฐฌ๊ฐ์ง๋ก ๋ถ๋ฆฌ๊ฐ ๊ฐ๋ฅํ๊ณ ์ํ๋ฅผ ์ฝ๊ฒ ๋ฆฌํฉํ ๋งํ ์ ์์ต๋๋ค.
์๋ก์ด JS ๊ตฌ๋ฌธ์ ์ฌ์ฉํ๋ IMO์์๋ ์ผ๋ฐ JS๋ก ๋ชฉ๋ก๊ณผ ๊ฐ์ฒด๋ฅผ ์ฝ๊ฒ ์์ ํ ์ ์์ผ๋ฏ๋ก ImmutableJS๋ฅผ ๋ ์ด์ ์ฌ์ฉํ๋ ๊ฒ์ด ๊ทธ๋ค์ง ์ ์ฉํ์ง ์์ต๋๋ค. ์์ฑ์ด ๋ง์ ๋งค์ฐ ํฐ ๋ชฉ๋ก๊ณผ ๊ฐ์ฒด๊ฐ ์๊ณ ์ฑ๋ฅ์์ ์ด์ ๋ก ๊ตฌ์กฐ์ ๊ณต์ ๊ฐ ํ์ํ์ง ์๋ ํ ImmutableJS๋ ์๊ฒฉํ ์๊ตฌ ์ฌํญ์ด ์๋๋๋ค.
@bvaughn ๋น์ ์ ์ ๋ง๋ก ์ด ํ๋ก์ ํธ๋ฅผ ๋ด์ผ ํฉ๋๋ค: https://github.com/yelouafi/redux-saga
๋ด๊ฐ @yelouafi ์๊ฒ
1) ์ก์ ์ ์์๋ฅผ ์ด๋ป๊ฒ ํ ์คํธํฉ๋๊น? ๋๋ ํ ์คํธํ๊ธฐ ์ฝ๊ธฐ ๋๋ฌธ์ ์ธ๋ถ ์๋น์ค์ ์์กดํ์ง ์๋ ์์ ๋๊ธฐ ํจ์๋ก ๊ฐ๋ฅํ ํ ๋ง์ ๋ ผ๋ฆฌ๋ฅผ ์ด๋ํ๋ ๊ฒ์ ์ข์ํฉ๋๋ค.
์์์ ์ด๊ฒ์ ์ค๋ช ํ๋ ค๊ณ ํ์ง๋ง ๊ธฐ๋ณธ์ ์ผ๋ก... "์ค๋ฆฌ"์ ๊ฐ์ ์ ๊ทผ ๋ฐฉ์์ผ๋ก ์ก์ ์ ์์๋ฅผ ํ ์คํธํ๋ ๊ฒ์ด (์ง๊ธ๊น์ง ๋์๊ฒ) ๊ฐ์ฅ ์๋ฏธ๊ฐ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. action-creator์ ๊ฒฐ๊ณผ๋ฅผ ๋์คํจ์นํ์ฌ ํ ์คํธ๋ฅผ ์์ํ ๋ค์ ์ ํ๊ธฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ํ๋ฅผ ํ์ธํฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ๋จ์ผ ํ ์คํธ๋ก ์ก์ ์์ฑ๊ธฐ, ํด๋น ๊ฐ์๊ธฐ ๋ฐ ๋ชจ๋ ๊ด๋ จ ์ ํ๊ธฐ๋ฅผ ๋ค๋ฃฐ ์ ์์ต๋๋ค.
2) ํซ ๋ฆฌ๋ก๋ฉ๊ณผ ํจ๊ป ์๊ฐ ์ฌํ์ ์ฌ์ฉํฉ๋๊น? react redux devtools์ ๊น๋ํ ์ ์ค ํ๋๋ ํซ ๋ฆฌ๋ก๋ฉ์ด ์ค์ ๋๋ฉด ์คํ ์ด๊ฐ ์ ๋ฆฌ๋์์ ๋ํด ๋ชจ๋ ์์ ์ ๋ค์ ์คํํ๋ค๋ ๊ฒ์ ๋๋ค. ๋ด ๋ ผ๋ฆฌ๋ฅผ ์ก์ ์ ์์๋ก ์ฎ๊ธฐ๋ฉด ์์ด ๋ฒ๋ฆด ๊ฒ์ ๋๋ค.
์๋์, ์ฐ๋ฆฌ๋ ์๊ฐ ์ฌํ์ ์ฌ์ฉํ์ง ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ ๋น์ ์ ๋น์ฆ๋์ค ๋ก์ง์ด ์ก์ -ํฌ๋ฆฌ์์ดํฐ์ ์๋ ๊ฒ์ด ์ฌ๊ธฐ์ ์ด๋ค ์ํฅ์ ๋ฏธ์น๊ฒ ์ต๋๊น? ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ๋ฅผ ์ ๋ฐ์ดํธํ๋ ์ ์ผํ ๊ฒ์ ๊ฐ์๊ธฐ์ ๋๋ค. ๋ฐ๋ผ์ ์์ฑ๋ ์์ ์ ๋ค์ ์คํํ๋ฉด ์ด๋ ์ชฝ์ด๋ ๋์ผํ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์์ต๋๋ค.
3) ์ก์ ์์ฑ์๊ฐ ์ฌ๋ฌ ๋ฒ ๋์คํจ์นํ์ฌ ํจ๊ณผ๋ฅผ ๊ฐ์ ธ์จ๋ค๋ฉด ์ํ๊ฐ ์ ์ ๋์ ์ ํจํ์ง ์์ ์ํ์ ์๋ค๋ ์๋ฏธ์ ๋๊น? (๋์ค์ ๋น๋๊ธฐ์์ผ๋ก ๋์คํจ์นํ๋ ๊ฒ์ด ์๋๋ผ ์ฌ๋ฌ ๋๊ธฐ์ ๋์คํจ์น๋ฅผ โโ์๊ฐํ๊ณ ์์ต๋๋ค.)
์ผ์์ ์ธ ๋ฌดํจ ์ํ๋ ์ด๋ค ๊ฒฝ์ฐ์๋ ์ค์ ๋ก ํผํ ์ ์๋ ๊ฒ์ ๋๋ค. ์ต์ข ์ผ๊ด์ฑ์ด ์๋ ํ ์ผ๋ฐ์ ์ผ๋ก ๋ฌธ์ ๊ฐ ๋์ง ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ค์ ๋งํ์ง๋ง, ๋น์ฆ๋์ค ๋ก์ง์ด action-creators ๋๋ reducers์ ์๋์ง์ ๊ด๊ณ์์ด ์ํ๊ฐ ์ผ์์ ์ผ๋ก ์ ํจํ์ง ์์ ์ ์์ต๋๋ค. ๊ทธ๊ฒ์ ๋ถ์์ฉ ๋ฐ ์์ ์ ํน์ฑ๊ณผ ๋ ๊ด๋ จ์ด ์์ต๋๋ค.
์๋ก์ด JS ๊ตฌ๋ฌธ์ ์ฌ์ฉํ๋ IMO์์๋ ์ผ๋ฐ JS๋ก ๋ชฉ๋ก๊ณผ ๊ฐ์ฒด๋ฅผ ์ฝ๊ฒ ์์ ํ ์ ์์ผ๋ฏ๋ก ImmutableJS๋ฅผ ๋ ์ด์ ์ฌ์ฉํ๋ ๊ฒ์ด ๊ทธ๋ค์ง ์ ์ฉํ์ง ์์ต๋๋ค. ์์ฑ์ด ๋ง์ ๋งค์ฐ ํฐ ๋ชฉ๋ก๊ณผ ๊ฐ์ฒด๊ฐ ์๊ณ ์ฑ๋ฅ์์ ์ด์ ๋ก ๊ตฌ์กฐ์ ๊ณต์ ๊ฐ ํ์ํ์ง ์๋ ํ ImmutableJS๋ ์๊ฒฉํ ์๊ตฌ ์ฌํญ์ด ์๋๋๋ค.
Immutable์ ์ฌ์ฉํ๋ ์ฃผ๋ ์ด์ ๋ ์ ๋ฐ์ดํธ๋ฅผ ์ํ ์ฑ๋ฅ์ด๋ ๊ตฌ๋ฌธ์์ ์คํ์ด ์๋๋๋ค. ์ฃผ๋ ์ด์ ๋ ์ฌ์ฉ์(๋๋ ๋ค๋ฅธ ์ฌ๋)๊ฐ ๊ฐ์๊ธฐ ๋ด์์ ๋ค์ด์ค๋ ์ํ๋ฅผ _์ฐ์ฐํ๊ฒ_ ๋ณ๊ฒฝํ๋ ๊ฒ์ ๋ฐฉ์งํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ๊ทธ๊ฒ์ ๋ถ๊ฐ๋ฅํ๋ฉฐ ๋ถํํ๋ ์ผ๋ฐ JS ๊ฐ์ฒด๋ก ์ฝ๊ฒ ์ํํ ์ ์์ต๋๋ค.
@bvaughn ๋น์ ์ ์ ๋ง๋ก ์ด ํ๋ก์ ํธ๋ฅผ ๋ด์ผ ํฉ๋๋ค: https://github.com/yelouafi/redux-saga
๋ด๊ฐ @yelouafi ์๊ฒ
๋๋ ์ค์ ๋ก ๊ทธ ํ๋ก์ ํธ๋ฅผ ์ ์ ์ฒดํฌ ์์ํ์ต๋๋ค :) ๋น๋ก ์์ง ๊ทธ๊ฒ์ ์ฌ์ฉํ์ง ์์์ง๋ง. ๊น๋ํด ๋ณด์ ๋๋ค.
์์์ ์ด๊ฒ์ ์ค๋ช ํ๋ ค๊ณ ํ์ง๋ง ๊ธฐ๋ณธ์ ์ผ๋ก... "์ค๋ฆฌ"์ ๊ฐ์ ์ ๊ทผ ๋ฐฉ์์ผ๋ก ์ก์ ์ ์์๋ฅผ ํ ์คํธํ๋ ๊ฒ์ด (์ง๊ธ๊น์ง ๋์๊ฒ) ๊ฐ์ฅ ์๋ฏธ๊ฐ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. action-creator์ ๊ฒฐ๊ณผ๋ฅผ ๋์คํจ์นํ์ฌ ํ ์คํธ๋ฅผ ์์ํ ๋ค์ ์ ํ๊ธฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ํ๋ฅผ ํ์ธํฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ๋จ์ผ ํ ์คํธ๋ก ์ก์ ์์ฑ๊ธฐ, ํด๋น ๊ฐ์๊ธฐ ๋ฐ ๋ชจ๋ ๊ด๋ จ ์ ํ๊ธฐ๋ฅผ ๋ค๋ฃฐ ์ ์์ต๋๋ค.
์ฃ์กํฉ๋๋ค, ๊ทธ ๋ถ๋ถ์ ์ป์์ต๋๋ค. ๋ด๊ฐ ๊ถ๊ธํ ๊ฒ์ ๋น๋๊ธฐ์ฑ๊ณผ ์ํธ ์์ฉํ๋ ํ ์คํธ ๋ถ๋ถ์ ๋๋ค. ๋ค์๊ณผ ๊ฐ์ ํ ์คํธ๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
var store = createStore();
store.dispatch(actions.startRequest());
store.dispatch(actions.requestResponseReceived({...});
strictEqual(isLoaded(store.getState());
๊ทธ๋ฌ๋ ๋น์ ์ ์ํ์ ์ด๋ป๊ฒ ์๊ฒผ์ต๋๊น? ์ด ๊ฐ์?
var mock = mockFetch();
store.dispatch(actions.request());
mock.expect("/api/foo.bar").andRespond("{status: OK}");
strictEqual(isLoaded(store.getState());
์๋์, ์ฐ๋ฆฌ๋ ์๊ฐ ์ฌํ์ ์ฌ์ฉํ์ง ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ ๋น์ ์ ๋น์ฆ๋์ค ๋ก์ง์ด ์ก์ -ํฌ๋ฆฌ์์ดํฐ์ ์๋ ๊ฒ์ด ์ฌ๊ธฐ์ ์ด๋ค ์ํฅ์ ๋ฏธ์น๊ฒ ์ต๋๊น? ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ๋ฅผ ์ ๋ฐ์ดํธํ๋ ์ ์ผํ ๊ฒ์ ๊ฐ์๊ธฐ์ ๋๋ค. ๋ฐ๋ผ์ ์์ฑ๋ ์์ ์ ๋ค์ ์คํํ๋ฉด ์ด๋ ์ชฝ์ด๋ ๋์ผํ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์์ต๋๋ค.
์ฝ๋๊ฐ ๋ณ๊ฒฝ๋๋ฉด ์ด๋ป๊ฒ ๋๋์? ๊ฐ์๊ธฐ๋ฅผ ๋ณ๊ฒฝํ๋ฉด ๋์ผํ ์์ ์ด ์ฌ์๋์ง๋ง ์ ๊ฐ์๊ธฐ๊ฐ ์ฌ์ฉ๋ฉ๋๋ค. ๋ฐ๋ฉด์ ์ก์ ์์ฑ์๋ฅผ ๋ณ๊ฒฝํ๋ฉด ์ ๋ฒ์ ์ด ์ฌ์๋์ง ์์ต๋๋ค. ๋ฐ๋ผ์ ๋ ๊ฐ์ง ์๋๋ฆฌ์ค๋ฅผ ๊ณ ๋ คํ์ญ์์ค.
๊ฐ์๊ธฐ ์ฌ์ฉ:
1) ๋ด ์ฑ์์ ์์
์ ์๋ํฉ๋๋ค.
2) ๋ด ๋ฆฌ๋์์ ๋ฒ๊ทธ๊ฐ ์์ด์ ์๋ชป๋ ์ํ๊ฐ ๋ฉ๋๋ค.
3) ๊ฐ์๊ธฐ์ ๋ฒ๊ทธ๋ฅผ ์์ ํ๊ณ ์ ์ฅํฉ๋๋ค.
4) ์๊ฐ ์ฌํ์ ์๋ก์ด ๊ฐ์๊ธฐ๋ฅผ ๋ก๋ํ๊ณ ๋ด๊ฐ ์์ด์ผ ํ๋ ์ํ๋ก ๋๋ฅผ ๋ก๋๋ค.
์ก์ ํฌ๋ฆฌ์์ดํฐ์ ํจ๊ป๋ผ๋ฉด
1) ๋ด ์ฑ์์ ์์
์ ์๋ํฉ๋๋ค.
2) ์ก์
์์ฑ์์ ๋ฒ๊ทธ๊ฐ ์์ด ์๋ชป๋ ์ก์
์ด ์์ฑ๋๋ ๊ฒฝ์ฐ
3) ์ก์
์์ฑ๊ธฐ์์ ๋ฒ๊ทธ๋ฅผ ์์ ํ๊ณ ์ ์ฅํฉ๋๋ค.
4) ๋๋ ์ฌ์ ํ ์๋ชป๋ ์ํ์ ์์ต๋๋ค. ์ต์ํ ์์
์ ๋ค์ ์๋ํด์ผ ํ๋ฉฐ, ์์ ํ ๋ง๊ฐ์ง ์ํ๊ฐ ๋๋ฉด ์๋ก๊ณ ์นจํด์ผ ํฉ๋๋ค.
์ผ์์ ์ธ ๋ฌดํจ ์ํ๋ ์ด๋ค ๊ฒฝ์ฐ์๋ ์ค์ ๋ก ํผํ ์ ์๋ ๊ฒ์ ๋๋ค. ์ต์ข ์ผ๊ด์ฑ์ด ์๋ ํ ์ผ๋ฐ์ ์ผ๋ก ๋ฌธ์ ๊ฐ ๋์ง ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ค์ ๋งํ์ง๋ง, ๋น์ฆ๋์ค ๋ก์ง์ด action-creators ๋๋ reducers์ ์๋์ง์ ๊ด๊ณ์์ด ์ํ๊ฐ ์ผ์์ ์ผ๋ก ์ ํจํ์ง ์์ ์ ์์ต๋๋ค. ๊ทธ๊ฒ์ ๋ถ์์ฉ ๋ฐ ์์ ์ ํน์ฑ๊ณผ ๋ ๊ด๋ จ์ด ์์ต๋๋ค.
redux์ ๋ํ ๋ด ์๊ฐ์ ์ ์ฅ์๊ฐ ํญ์ ์ ํจํ ์ํ๋ผ๊ณ ์ฃผ์ฅํ๋ ๊ฒ ๊ฐ์ต๋๋ค. ๊ฐ์๊ธฐ๋ ํญ์ ์ ํจํ ์ํ๋ฅผ ์ทจํ๊ณ ์ ํจํ ์ํ๋ฅผ ์์ฑํฉ๋๋ค. ์ด๋ค ๊ฒฝ์ฐ๊ฐ ์ผ๊ด์ฑ์ด ์๋ ์ํ๋ฅผ ํ์ฉํ๋๋ก ๊ฐ์ ํ๋ค๊ณ ์๊ฐํฉ๋๊น?
๋ฐฉํดํด์ ์ฃ์กํฉ๋๋ค. ์ ํจํ์ง ์์ ์ํ๋ ๋ฌด์์ ์๋ฏธํฉ๋๊น?
์ฌ๊ธฐ? ๋ก๋ ์ค์ธ ๋ฐ์ดํฐ ๋๋ ์คํ ์ค์ธ ์์
์ด์ง๋ง ์์ง ์๋ฃ๋์ง ์์ ๋ชจ์
๋์๊ฒ ์ ํจํ ์ผ์์ ์ธ ์ํ์ฒ๋ผ.
Redux @bvaughn ๋ฐ @sompylasar ์์ ์ผ์์ ์ธ ์ํ๋ ๋ฌด์์ ์๋ฏธํฉ๋๊น? ๋์คํจ์น๊ฐ ์๋ฃ๋๊ฑฐ๋ ๋์ง๋๋ค. ๋์ง๋ฉด ์ํ๊ฐ ๋ณ๊ฒฝ๋์ง ์์ต๋๋ค.
๋ฆฌ๋์์ ์ฝ๋ ๋ฌธ์ ๊ฐ ์๋ ํ Redux์๋ ๋ฆฌ๋์ ๋ ผ๋ฆฌ์ ์ผ์นํ๋ ์ํ๋ง ์์ต๋๋ค. ์ด๋ป๊ฒ๋ ์ ๋ฌ๋ ๋ชจ๋ ์์ ์ ํธ๋์ญ์ ์์ ์ฒ๋ฆฌ๋ฉ๋๋ค. ์ ์ฒด ํธ๋ฆฌ๊ฐ ์ ๋ฐ์ดํธ๋๊ฑฐ๋ ์ํ๊ฐ ์ ํ ๋ณ๊ฒฝ๋์ง ์์ต๋๋ค.
์ ์ฒด ํธ๋ฆฌ๊ฐ ์ ๋ฐ์ดํธ๋์ง๋ง ์ ์ ํ ๋ฐฉ์์ด ์๋ ๊ฒฝ์ฐ(์: React๊ฐ ๋ ๋๋งํ ์ ์๋ ์ํ), ์์ ์ ์ฌ๋ฐ๋ฅด๊ฒ ์ํํ์ง ์์ ๊ฒ์ ๋๋ค. :)
Redux์์ ํ์ฌ ์ํ๋ ๋จ์ผ ๋์คํจ์น๋ฅผ โโํธ๋์ญ์ ๊ฒฝ๊ณ๋ก ๊ฐ์ฃผํ๋ ๊ฒ์ ๋๋ค.
๊ทธ๋ฌ๋ ๋์ผํ ํธ๋์ญ์ ์์ 2๊ฐ์ ์์ ์ ๋๊ธฐ์ ์ผ๋ก ์ ๋ฌํ๋ ค๋ ๊ฒ์ฒ๋ผ ๋ณด์ด๋ @winstonewert ์ ์ฐ๋ ค๋ฅผ ์ดํดํฉ๋๋ค. ๋๋ก๋ actionCreators๊ฐ ์ฌ๋ฌ ์์ ์ ์ ๋ฌํ๊ณ ๋ชจ๋ ์์ ์ด ์ฌ๋ฐ๋ฅด๊ฒ ์คํ๋๊ธฐ๋ฅผ ๊ธฐ๋ํ๊ธฐ ๋๋ฌธ์ ๋๋ค. 2๊ฐ์ ์์ ์ด ์ ๋ฌ๋๊ณ ๋ ๋ฒ์งธ ์์ ์ด ์คํจํ๋ฉด ์ฒซ ๋ฒ์งธ ์์ ๋ง ์ ์ฉ๋์ด "์ผ๊ด๋์ง ์์"์ผ๋ก ๊ฐ์ฃผํ ์ ์๋ ์ํ๊ฐ ๋ฉ๋๋ค. @winstonewert ๋ ๋ ๋ฒ์งธ ์์ ๋์คํจ์น๊ฐ ์คํจํ๋ฉด ๋ ์์ ์ ๋กค๋ฐฑํ๊ธฐ๋ฅผ ์ํ ๊ฒ์ ๋๋ค.
@winstonewert ๋ด๋ถ ํ๋ ์์ํฌ์์ ์ด์ ๊ฐ์ ๊ฒ์ ๊ตฌํํ์ผ๋ฉฐ ์ง๊ธ๊น์ง๋ ์ ์๋ํฉ๋๋ค. https://github.com/stample/atom-react/blob/master/src/atom/atom.js
๋ํ ๋ ๋๋ง ์ค๋ฅ๋ฅผ ์ฒ๋ฆฌํ๊ณ ์ถ์์ต๋๋ค. ์ํ๋ฅผ ์ฑ๊ณต์ ์ผ๋ก ๋ ๋๋งํ ์ ์๋ ๊ฒฝ์ฐ UI ์ฐจ๋จ์ ํผํ๊ธฐ ์ํด ์ํ๊ฐ ๋กค๋ฐฑ๋๊ธฐ๋ฅผ ์ํ์ต๋๋ค. ๋ถํํ๋ ๋ค์ ๋ฆด๋ฆฌ์ค ๊น์ง React๋ ๋ ๋ ๋ฉ์๋๊ฐ ์ค๋ฅ๋ฅผ ๋์ง ๋ ๋งค์ฐ ๋์ ์ผ์ ํ๋ฏ๋ก ๊ทธ๋ค์ง ์ ์ฉํ์ง๋ ์์ง๋ง ๋ฏธ๋์๋ ๋ ์ ์์ต๋๋ค.
๋งค์ฅ์์ ๋ฏธ๋ค์จ์ด๋ฅผ ์ฌ์ฉํ ํธ๋์ญ์ ์์ ์ฌ๋ฌ ๋๊ธฐํ ๋์คํจ์น๋ฅผ โโํ์ฉํ ์ ์๋ค๊ณ ํ์ ํฉ๋๋ค.
๊ทธ๋ฌ๋ ์ผ๋ฐ์ ์ผ๋ก redux ์ ์ฅ์๊ฐ ์ํ๋ฅผ ๋ ๋๋งํ๋ ค๊ณ ํ ๋ ์ด๋ฏธ "์ปค๋ฐ"๋์ด ์๊ธฐ ๋๋ฌธ์ ๋ ๋๋ง ์ค๋ฅ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ ์ํ๋ฅผ ๋กค๋ฐฑํ ์ ์๋์ง ํ์ ํ ์ ์์ต๋๋ค. ๋ด ํ๋ ์์ํฌ์๋ ๋ ๋๋ง์ ํธ๋ฆฌ๊ฑฐํ๊ณ ๊ฒฐ๊ตญ ๋ชจ๋ ๋ ๋๋ง ์ค๋ฅ์์ ๋กค๋ฐฑํ๋ ๋ฐ ์ฌ์ฉํ๋ "beforeTransactionCommit" ํํฌ๊ฐ ์์ต๋๋ค.
@gaearon ์ด๋ฐ ๊ธฐ๋ฅ์ ์ง์ํ ๊ณํ์ด ์๋์ง, ํ์ฌ API๋ก ๊ฐ๋ฅํ์ง ๊ถ๊ธํฉ๋๋ค.
redux-batched-subscribe ๋ ์ค์ ํธ๋์ญ์ ์ ํ์ฉํ์ง ์๊ณ ๋ ๋๋ง ์๋ฅผ ์ค์ด๋ ๊ฒ ๊ฐ์ต๋๋ค. ๋ด๊ฐ ๋ณด๋ ๊ฒ์ ๊ตฌ๋ ์์ ๊ธฐ๊ฐ ๋ง์ง๋ง์ ํ ๋ฒ๋ง ์คํ๋๋ ๊ฒฝ์ฐ์๋ ๊ฐ ๋์คํจ์น ํ์ ์ ์ฅ์ "์ปค๋ฐ"์ด ๋๋ค๋ ๊ฒ์ ๋๋ค.
์์ ํ ๊ฑฐ๋ ์ง์์ด ํ์ํ ์ด์ ๋ ๋ฌด์์ ๋๊น? ์ฌ์ฉ ์ฌ๋ก๋ฅผ ์ดํดํ์ง ๋ชปํ๋ ๊ฒ ๊ฐ์ต๋๋ค.
@gaearon ์์ง ํ์คํ์ง ์์ง๋ง @winstonewert ์ฌ์ฉ ์ฌ๋ก ์ ๋ํด ๋ ์๊ฒ ๋์ด
์์ด๋์ด๋ dispatch([a1,a2])
์ํํ ์ ์๊ณ a2๊ฐ ์คํจํ๋ฉด a1์ด ๋ฐ์ก๋๊ธฐ ์ ์ ์ํ๋ก ๋กค๋ฐฑํ๋ค๋ ๊ฒ์
๋๋ค.
๊ณผ๊ฑฐ์๋ ์ฌ๋ฌ ์์ ์ ๋๊ธฐ์ ์ผ๋ก ์ ๋ฌํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์๊ณ (์: ๋จ์ผ onClick ์์ ๊ธฐ์์ ๋๋ actionCreator์์) ์ฃผ๋ก ์ ๋ฌ๋๋ ๋ชจ๋ ์์ ์ด ๋๋ ๋๋ง ๋ ๋๋ง์ ํธ์ถํ๋ ๋ฐฉ๋ฒ์ผ๋ก ํธ๋์ญ์ ์ ๊ตฌํํ์ต๋๋ค. redux-batched-subscribe ํ๋ก์ ํธ์ ์ํด ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ํด๊ฒฐ๋์์ต๋๋ค.
๋ด ์ฌ์ฉ ์ฌ๋ก์์ ํธ๋์ญ์ ์์ ์คํํ๋ ๋ฐ ์ฌ์ฉํ ์์ ์ ๋๋ถ๋ถ ๋ถํ์ํ ๋ ๋๋ง์ ํผํ๊ธฐ ์ํ ๊ฒ์ด์ง๋ง ์์ ์ ๋ ๋ฆฝ์ ์ผ๋ก ์๋ฏธ๊ฐ ์์ผ๋ฏ๋ก ๋ ๋ฒ์งธ ์์ ์ ๋ํด ๋์คํจ์น๊ฐ ์คํจํ๋๋ผ๋ ์ฒซ ๋ฒ์งธ ์์ ์ ๋กค๋ฐฑํ์ง ์์ผ๋ฉด ์ฌ์ ํ ์ผ๊ด๋ ์ํ๋ฅผ ์ ๊ณตํฉ๋๋ค( ๊ทธ๋ฌ๋ ๊ณํ๋ ๊ฒ์ด ์๋ ์๋ ์์ต๋๋ค...). ๋๊ตฐ๊ฐ๊ฐ ์ ์ฒด ๋กค๋ฐฑ์ด ์ ์ฉํ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ์๊ฐํด ๋ผ ์ ์๋์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค.
๊ทธ๋ฌ๋ ๋ ๋๋ง์ด ์คํจํ๋ฉด ๋ ๋๋งํ ์ ์๋ ์ํ์์ ์งํ์ ์๋ํ๋ ๋์ ๋ ๋๋ง์ด ์คํจํ์ง ์์ ๋ง์ง๋ง ์ํ๋ก ๋กค๋ฐฑ์ ์๋ํ๋ ๊ฒ์ด ํฉ๋ฆฌ์ ์ด์ง ์์ต๋๊น?
๊ฐ๋จํ ๊ฐ์๊ธฐ ์ธํธ์๊ฐ ์๋ํฉ๋๊น? ์
const enhanceReducerWithTheAbilityToConsumeMultipleActions = (reducer =>
(state, actions) => (typeof actions.reduce === 'function'
? actions.reduce(reducer, state)
: reducer(state, actions)
)
)
์ด๋ฅผ ํตํด ์ ์ฅ์์ ๋ฐฐ์ด์ ์ ๋ฌํ ์ ์์ต๋๋ค. ์ธํธ์๋ ๊ฐ๋ณ ์์ ์ ์์ถ์ ํ๊ณ ์ด๋ฅผ ๊ฐ ๋ฆฌ๋์์ ๊ณต๊ธํฉ๋๋ค.
์, ์กด์ฌํฉ๋๋ค: https://github.com/tshelburne/redux-batched-actions
์ค @gaearon ๋ชฐ๋๋ค์ . ๋งค์ฐ ์ ์ฌํ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ํด๊ฒฐํ๋ ค๊ณ ํ๋ 2๊ฐ์ ๊ณ ์ ํ ํ๋ก์ ํธ๊ฐ ์๋ค๋ ๊ฒ์ ์์ง ๋ชปํ์ต๋๋ค.
๋ ๋ค ๋ถํ์ํ ๋ ๋๋ง์ ํผํ ์ ์์ง๋ง ์ฒซ ๋ฒ์งธ๋ ๋ชจ๋ ์ผ๊ด ์ฒ๋ฆฌ๋ ์์ ์ ๋กค๋ฐฑํ๊ณ ๋ ๋ฒ์งธ๋ ์คํจํ ์์ ๋ง ์ ์ฉํ์ง ์์ต๋๋ค.
@gaearon ์ ,
๋๋ ์๋ง๋ ๋๋ถ๋ถ์ ์ฌ๋๋ค๋งํผ Redux์ ๋ํ ์ค์ ๊ฒฝํ์ด ๋ง์ง ์์ ๊ฒ์ ๋๋ค. ๊ทธ๋ฌ๋ ์ฒซ๋์ ๋๋ "์ก์ ํฌ๋ฆฌ์์ดํฐ์์๋ ๋ ๋ง์ด ํ๊ณ ๋ฆฌ๋์์์๋ ๋ ํ๊ธฐ"์ ๋์ํ์ง ์์ ์ ์์ต๋๋ค. ํ์ฌ.
Flux ํจํด์ด ๋์ ๋ Hacker Way: Rethinking Web App Development at Facebook ์์ Flux๋ฅผ ๋ฐ๋ช ํ๊ฒ ๋ ๋ฐ๋ก ๊ทธ ๋ฌธ์ ๋ ๋ช ๋ นํ ์ฝ๋์ ๋๋ค.
์ด ๊ฒฝ์ฐ I/O๋ฅผ ์ํํ๋ Action Creator๋ ๋ช ๋ นํ ์ฝ๋์ ๋๋ค.
์ฐ๋ฆฌ๋ ์ง์ฅ์์ Redux๋ฅผ ์ฌ์ฉํ์ง ์์ง๋ง ๋ด๊ฐ ์ผํ๋ ๊ณณ์์๋ ์ธ๋ถํ๋ ์์
(๋ฌผ๋ก ๋ชจ๋ ์์ฒด์ ์ผ๋ก ์๋ฏธ๊ฐ ์์)์ ์ฌ์ฉํ๊ณ ์ผ๊ด์ ์ผ๋ก ํธ๋ฆฌ๊ฑฐํ์ต๋๋ค. ์๋ฅผ ๋ค์ด ๋ฉ์์ง๋ฅผ ํด๋ฆญํ๋ฉด OPEN_MESSAGE_VIEW
, FETCH_MESSAGE
, MARK_NOTIFICATION_AS_READ
์ธ ๊ฐ์ง ์์
์ด ํธ๋ฆฌ๊ฑฐ๋ฉ๋๋ค.
๊ทธ๋ฐ ๋ค์ ์ด๋ฌํ "๋ฎ์ ์์ค์" ์์ ์ ์์ ๋ด๋ถ์ ์ด๋ค ๊ฐ์ ์ค์ ํ๊ธฐ ์ํ "๋ช ๋ น" ๋๋ "์ค์ ์" ๋๋ "๋ฉ์์ง"์ ๋ถ๊ณผํ๋ค๋ ๊ฒ์ด ๋ฐํ์ก์ต๋๋ค. ๋ค์ ๋์๊ฐ์ MVC๋ฅผ ์ฌ์ฉํ๊ณ ๊ณ์ ์ด๋ ๊ฒ ํ๋ฉด ๋ ๊ฐ๋จํ ์ฝ๋๋ก ๋๋ ์๋ ์์ต๋๋ค.
์ด๋ค ์๋ฏธ์์ Action Creators๋ ์์ ์ฝ๋๋ฅผ ๋ํ๋ด๋ ๋ฐ๋ฉด Reducers(๋ฐ Selector)๋ ์์ ์ฝ๋๋ฅผ ๋ํ๋ ๋๋ค . Haskell ์ฌ๋๋ค์ ๋ ๋ถ์ํ ์ฝ๋์ ๋ ์์ํ ์ฝ๋๋ฅผ ๊ฐ๋ ๊ฒ์ด ๋ ๋ซ๋ค ๋ ๊ฒ์ ์์๋์ต๋๋ค.
์๋ฅผ ๋ค์ด ๋ด ์ฌ์ด๋ โโํ๋ก์ ํธ(Redux ์ฌ์ฉ)์์ ์นํท์ ์์ฑ ์ธ์ API๋ฅผ ์ฌ์ฉํฉ๋๋ค. ๋ง์ ํ๋ฉด onresult
์ด๋ฒคํธ๊ฐ ๋ฐ์ํฉ๋๋ค. ๋ ๊ฐ์ง ์ ํ์ด ์์ต๋๋ค. ์ด๋ฌํ ์ด๋ฒคํธ๋ ์ด๋์์ ์ฒ๋ฆฌ๋ฉ๋๊น?
๋๋ ๋ ๋ฒ์งธ๋ก ๊ฐ๋ค. ๊ทธ๋ฅ ์์ ์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์ ์ฅ์๋ก ๋ณด๋ด๋ผ.
๊ทธ๋ฌ๋ Redux dev-tools๋ ๋น์ผ๋ฐ ๊ฐ์ฒด๊ฐ ์ ์ฅ์๋ก ์ ์ก๋๋ ๊ฒ์ ์ข์ํ์ง ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ๊ทธ๋์ ์ ๋ ์ด๋ฌํ ์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์ผ๋ฐ ๊ฐ์ฒด๋ก ๋ณํํ๊ธฐ ์ํด ์ก์ ์์ฑ์์ ๋ช ๊ฐ์ง ์์ ๋ก์ง์ ์ถ๊ฐํ์ต๋๋ค. (์ก์ ์์ฑ๊ธฐ์ ์ฝ๋๋ ๋๋ฌด ๊ฐ๋จํ์ฌ ์๋ชป๋ ์ ์์ต๋๋ค.)
๊ทธ๋ฐ ๋ค์ ๊ฐ์๊ธฐ๋ ์ด๋ฌํ ๋งค์ฐ ์์์ ์ธ ์ด๋ฒคํธ๋ฅผ ๊ฒฐํฉํ๊ณ ๋งํ ๋ด์ฉ์ ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํ ์ ์์ต๋๋ค. ๊ทธ ๋ก์ง์ ์์ ์ฝ๋ ์์ ์๊ธฐ ๋๋ฌธ์ (๋ฆฌ๋์๋ฅผ ํซ ๋ฆฌ๋ก๋ฉํ์ฌ) ๋ผ์ด๋ธ๋ก ์์ฃผ ์ฝ๊ฒ ์กฐ์ ํ ์ ์์ต๋๋ค.
@dtinth๋ฅผ ์ง์ํ๊ณ ์ถ์ต๋๋ค. ํ๋์ ์ฐ๋ฆฌ๊ฐ ์ด๋ฌํ ์ฌ๊ฑด์ ์ด๋ป๊ฒ ๋ฐ์ํ๊ณ ์ถ์์ง๊ฐ ์๋๋ผ ํ์ค ์ธ๊ณ์์ ์ผ์ด๋ ์ฌ๊ฑด์ ๋ํ๋ด์ผ ํฉ๋๋ค. ํนํ CQRS๋ฅผ ์ฐธ์กฐํ์ญ์์ค. ์ฐ๋ฆฌ๋ ์ค์ ์ฌ๊ฑด์ ๋ํ ๋ง์ ์ธ๋ถ ์ฌํญ์ ๊ธฐ๋กํ๊ณ ์ถ๊ณ , ์์ผ๋ก ๊ฐ์๊ธฐ๊ฐ ๊ฐ์ ๋๊ณ ์๋ก์ด ๋ ผ๋ฆฌ๋ก ์ค๋๋ ์ฌ๊ฑด์ ์ฒ๋ฆฌํ ๊ฐ๋ฅ์ฑ์ด ๋์ต๋๋ค.
@dtinth @denis-sokolov ์ ๋ ๊ทธ ์ ์ ๋์ํฉ๋๋ค. Btw ๋ด๊ฐ redux-saga ํ๋ก์ ํธ๋ฅผ ์ฐธ์กฐํ ๋ ๋๋ actionCreators๋ฅผ ์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ ์ ์ ๋ ๋ณต์กํ๊ฒ ๋ง๋๋ ์์ด๋์ด์ ๋ฐ๋ํ๋ค๋ ๊ฒ์ ๋ถ๋ช ํ ํ์ง ์์์ ์ ์์ต๋๋ค.
Redux-saga ํ๋ก์ ํธ๋ @dtinth์์ ์ค๋ช ํ๋ ๊ฒ์ ์ํํ๋ ค๋ ์๋ ๋ฏธ๋ฌํ ์ฐจ์ด๊ฐ ์์ต๋๋ค. ์ก์ ๋ก๊ทธ์ ๋ฐ์ํ ๋ชจ๋ ์์ ์ด๋ฒคํธ๋ฅผ ์์ฑํ๋ฉด ์ด ์ก์ ๋ก๊ทธ์ ๋ฆฌ๋์์์ ๋ชจ๋ ์ํ๋ฅผ ์ฝ๊ฒ ๊ณ์ฐํ ์ ์๋ค๊ณ ๋งํ๊ณ ์ถ์ ๊ฒ ๊ฐ์ต๋๋ค. ์ด๊ฒ์ ์ ๋์ ์ผ๋ก ์ฌ์ค์ด๋ฉฐ ์์ ๋ก๊ทธ๊ฐ ๋ช ์์ ์ด์ง ์๊ณ ์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ ๊ฐ์๊ธฐ๊ฐ ๋๋ฌด ๋ณต์กํด์ ธ์ ์ฑ์ ์ ์ง ๊ด๋ฆฌํ๊ธฐ๊ฐ ๋งค์ฐ ์ด๋ ค์์ง ๋๊น์ง ํ๋์ ๊ทธ ๊ฒฝ๋ก๋ฅผ ํํ์ต๋๋ค.
Redux ์ฌ๊ฐ ํ ๋ก ์ผ๋ก ์ด์ด์ง๋ ์๋ ํ ๋ก ์ ์ด ์ง์ ์ ๋ณผ ์ ์์ต๋๋ค. https://github.com/paldepind/functional-frontend-architecture/issues/20#issuecomment -162822909
๋ช ๋ฐฑํ TodoCreated ์ด๋ฒคํธ๊ฐ ์๋ Todo ์ฑ์ด ์๋ค๊ณ ์์ํด ๋ณด์ญ์์ค. ๊ทธ๋ฐ ๋ค์ ์ฑ ์จ๋ณด๋ฉ์ ์ฝ๋ฉํ๋๋ก ์์ฒญํฉ๋๋ค. ์ฌ์ฉ์๊ฐ ํ ์ผ์ ์์ฑํ๋ฉด ํ์ ์ผ๋ก ์ถํํด์ผ ํฉ๋๋ค.
์ด๊ฒ์ @bvaughn ์ด ์ ํธํ๋ ๊ฒ์ ๋๋ค.
function createTodo(todo) {
return (dispatch, getState) => {
dispatch({type: "TodoCreated",payload: todo});
if ( getState().isOnboarding ) {
dispatch({type: "ShowOnboardingTodoCreateCongratulation"});
}
}
}
๋๋ ์ด ์ ๊ทผ ๋ฐฉ์์ด ์ฑ ๋ณด๊ธฐ์ ๋ ์ด์์๊ณผ ๋ฐ์ ํ๊ฒ ๊ฒฐํฉ๋ ์ก์ ์์ฑ๊ธฐ๋ฅผ ๋ง๋ค๊ธฐ ๋๋ฌธ์ ๋ง์์ ๋ค์ง ์์ต๋๋ค. actionCreator๊ฐ ๊ฒฐ์ ์ ๋ด๋ฆฌ๊ธฐ ์ํด UI ์ํ ํธ๋ฆฌ์ ๊ตฌ์กฐ๋ฅผ ์์์ผ ํ๋ค๊ณ ๊ฐ์ ํฉ๋๋ค.
์ด๊ฒ์ @denis-sokolov @dtinth ๊ฐ ์ ํธํ๋ ๊ฒ์ ๋๋ค:
function onboardingTodoCreateCongratulationReducer(state = defaultState, action) {
var isOnboarding = isOnboardingReducer(state.isOnboarding,action);
switch (action) {
case "TodoCreated":
return {isOnboarding: isOnboarding, isCongratulationDisplayed: isOnboarding}
default:
return {isOnboarding: isOnboarding, isCongratulationDisplayed: false}
}
}
์, ์ถํ ๋ฉ์์ง๋ฅผ ํ์ํด์ผ ํ๋์ง ์๋ ๊ฐ์๊ธฐ๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ํ์ ์ด ํ์๋์๋ค๋ ์กฐ์น๋ ์์ด ํ์๋๋ ํ์ ์ด ์์ต๋๋ค. ๋ด ์์ ์ ๊ฒฝํ์ ๋ฐ๋ฅด๋ฉด(๊ทธ๋ฆฌ๊ณ ์ฌ์ ํ ๊ทธ๋ ๊ฒ ํ๋ ๋ ๊ฑฐ์ ์ฝ๋๊ฐ ์์) ๋งค์ฐ ๋ช ์์ ์ผ๋ก ๋ง๋๋ ๊ฒ์ด ํญ์ ๋ ์ข์ต๋๋ค. DISPLAY_CONGRATULATION ์์ ์ด ์คํ๋์ง ์์ผ๋ฉด ์ถํ ํ์ ์ ํ์ํ์ง ๋ง์ญ์์ค. ๋ช ์์ ์ ์์์ ๋ณด๋ค ์ ์ง ๊ด๋ฆฌ๊ฐ ํจ์ฌ ์ฝ์ต๋๋ค.
redux-saga๋ ์์ฑ๊ธฐ๋ฅผ ์ฌ์ฉํ๋ฉฐ ์ต์ํ์ง ์์ ๊ฒฝ์ฐ ์ฝ๊ฐ ๋ณต์กํด ๋ณด์ผ ์ ์์ง๋ง ๊ธฐ๋ณธ์ ์ผ๋ก ๋ค์๊ณผ ๊ฐ์ ๊ฐ๋จํ ๊ตฌํ์ ์ฌ์ฉํ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์์ฑํ ์ ์์ต๋๋ค.
function createTodo(todo) {
return (dispatch, getState) => {
dispatch({type: "TodoCreated",payload: todo});
}
}
function onboardingSaga(state, action, actionCreators) {
switch (action) {
case "OnboardingStarted":
return {onboarding: true, ...state};
case "OnboardingStarted":
return {onboarding: false, ...state};
case "TodoCreated":
if ( state.onboarding ) dispatch({type: "ShowOnboardingTodoCreateCongratulation"});
return state;
default:
return state;
}
}
saga๋ ์ด๋ฒคํธ๋ฅผ ์์ ํ๊ณ ํจ๊ณผ๋ฅผ ์์ฑํ ์ ์๋ ์ํ ์ ์ฅ ์กํฐ์ ๋๋ค. ์ฌ๊ธฐ์์ ์ด๊ฒ์ด ๋ฌด์์ธ์ง์ ๋ํ ์์ด๋์ด๋ฅผ ์ ๊ณตํ๊ธฐ ์ํด ๋ถ์ํ ๊ฐ์๊ธฐ๋ก ๊ตฌํ๋์ง๋ง ์ค์ ๋ก๋ redux-saga ํ๋ก์ ํธ์ ์์ต๋๋ค.
์ด๊ธฐ ๊ท์น์ ์ฒ๋ฆฌํ๋ฉด ๋ชจ๋ ๊ฒ์ ๋ํด ๋งค์ฐ ๋ช
์์ ์ด์ง ์์ต๋๋ค.
์์ ๊ตฌํ์ ๋ณด๋ฉด ์จ๋ณด๋ฉ ์ค์ ํ ์ผ์ ๋ง๋ค ๋๋ง๋ค ์ถํ ํ์
์ด ์ด๋ฆฌ๋ ๊ฒ์ ์ ์ ์์ต๋๋ค. ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ์จ๋ณด๋ฉ ์ค์ ๋ฐ์ํ๋ ์ฒซ ๋ฒ์งธ ์์ฑ๋ ํ ์ผ์ ๋ํด์๋ง ์ด๋ฆฌ๊ธธ ์ํ๊ณ ๋ชจ๋ ํ ์ผ์ด ์๋๋ผ ์ด๋ฆฌ๊ธธ ์ํ ๊ฒ์
๋๋ค. ๋ํ ์ฌ์ฉ์๊ฐ ๊ฒฐ๊ตญ ์ฒ์๋ถํฐ ์จ๋ณด๋ฉ์ ๋ค์ ํ ์ ์๋๋ก ํ๊ณ ์ถ์ต๋๋ค.
์จ๋ณด๋ฉ์ด ์ ์ ๋ ๋ณต์กํด์ง์ ๋ฐ๋ผ ์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ 3๊ฐ์ง ๊ตฌํ ๋ชจ๋์์ ์ฝ๋๊ฐ ์ด๋ป๊ฒ ์ง์ ๋ถํด์ก๋์ง ์ ์ ์์ต๋๊น?
redux-saga์ ์์ ์จ๋ณด๋ฉ ๊ท์น์ ์ฌ์ฉํ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์์ฑํ ์ ์์ต๋๋ค.
function* onboarding() {
while ( true ) {
take(ONBOARDING_STARTED)
take(TODO_CREATED)
put(SHOW_TODO_CREATION_CONGRATULATION)
take(ONBOARDING_ENDED)
}
}
์์ ์๋ฃจ์ ๋ณด๋ค ํจ์ฌ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ผ๋ก ์ด ์ฌ์ฉ ์ฌ๋ก๋ฅผ ํด๊ฒฐํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ๋ด๊ฐ ํ๋ ธ๋ค๋ฉด ๋ ๊ฐ๋จํ ๊ตฌํ์ ์๋ ค์ฃผ์ญ์์ค. :)
๋น์ ์ ๋ถ์ํ ์ฝ๋์ ๋ํด ์ด์ผ๊ธฐํ๊ณ ์ด ๊ฒฝ์ฐ์๋ ํ ์ดํฌ/ํ ํจ๊ณผ๊ฐ ์ค์ ๋ก ๋ฐ์ดํฐ์ด๊ธฐ ๋๋ฌธ์ Redux-saga ๊ตฌํ์ ๋ถ์ํจ์ด ์์ต๋๋ค. take() ๊ฐ ํธ์ถ๋๋ฉด ์คํ๋์ง ์๊ณ ์คํํ ํจ๊ณผ์ ์ค๋ช ์๋ฅผ ๋ฐํํ๊ณ ์ด๋ ์์ ์์ ์ธํฐํ๋ฆฌํฐ๊ฐ ์์๋๋ฏ๋ก ๋ฌด์ฉ๋ด์ ํ ์คํธํ๊ธฐ ์ํด ๋ชจ์๊ฐ ํ์ํ์ง ์์ต๋๋ค. ๋น์ ์ด Haskell์ ํ๋ ๊ธฐ๋ฅ์ ์ธ ๊ฐ๋ฐ์๋ผ๋ฉด Free / IO ๋ชจ๋๋๋ฅผ ์๊ฐํ์ญ์์ค.
์ด ๊ฒฝ์ฐ ๋ค์์ ํ์ฉํฉ๋๋ค.
getState
์ ์์กดํ๊ฒ ๋ง๋์ญ์์ค.๋ํ ํด์ ๊ณ์ธต์ ์ ๊ณตํ์ฌ ์์ ์ด๋ฒคํธ๋ฅผ ๋ณด๋ค ์๋ฏธ ์๊ณ ๋์ ์์ค์ ์ด๋ฒคํธ๋ก ๋ณํํ ์ ์์ต๋๋ค(ELM์ด ์ด๋ฒคํธ๋ฅผ ๋ฒ๋ธ๋งํ ๋ ๋ํํ๋ ๊ฒ๊ณผ ์ฝ๊ฐ ์ ์ฌ).
์:
์ค๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ๋ชจ๋์ ์ฑ ๋ ์ด์์์ ๋ฌ์ฑํ๋ ค๋ ๊ฒฝ์ฐ ์ค๋ฆฌ๋ฅผ ํจ๊ป ๊ฒฐํฉํ๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์์ต๋๋ค. ์ฌ๊ฐ๋ ์ฐ๊ฒฐ์ ์ด ๋ฉ๋๋ค. ์ค๋ฆฌ๋ ์์ ์ด๋ฒคํธ๋ฅผ ์์์ผ ํ๊ณ ๋ฌด์ฉ๋ด์ ์ด๋ฌํ ์์ ์ด๋ฒคํธ๋ฅผ ํด์ํฉ๋๋ค. ์ด๊ฒ์ duck1 ํ๋ก์ ํธ๋ฅผ ๋ค๋ฅธ ์ปจํ ์คํธ์์ ๋ ์ฝ๊ฒ ์ฌ์ฌ์ฉํ ์ ์๋๋ก ํ๊ธฐ ๋๋ฌธ์ duck1์ด duck2์ ์ง์ ์์ ์ ๋์คํจ์นํ๋ ๊ฒ๋ณด๋ค ํจ์ฌ ๋ซ์ต๋๋ค. ๊ทธ๋ฌ๋ ๊ฒฐํฉ ์ง์ ์ด actionCreators์์๋ ๊ฐ๋ฅํ๋ค๊ณ ์ฃผ์ฅํ ์ ์์ผ๋ฉฐ ์ด๊ฒ์ด ์ค๋๋ ๋๋ถ๋ถ์ ์ฌ๋๋ค์ด ํ๊ณ ์๋ ์ผ์ ๋๋ค.
@slorber ์ด๊ฒ์ ํ๋ฅญํ ์์ ๋๋ค! ์๊ฐ์ ๋ด์ด ๊ฐ ์ ๊ทผ ๋ฐฉ์์ ์ฅ์ ๊ณผ ๋จ์ ์ ๋ช ํํ๊ฒ ์ค๋ช ํด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค. (๋๋ ๊ทธ๊ฒ์ด ๋ฌธ์์ ์์ด์ผํ๋ค๊ณ ์๊ฐํฉ๋๋ค.)
๋๋ ๋น์ทํ ์์ด๋์ด๋ฅผ ํ๊ตฌํ๊ณค ํ์ต๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ์ด๊ฒ์ ์๋ฌด ๊ฒ๋ ๋ ๋๋งํ์ง ์์ง๋ง( render: () => null
) ์ด๋ฒคํธ๋ฅผ ์์ ํ๊ณ (์: ์์ ์์) ๋ค๋ฅธ ๋ถ์์ฉ์ ์ ๋ฐํ๋ React ๊ตฌ์ฑ ์์์
๋๋ค. ๊ทธ๋ฐ ๋ค์ ํด๋น ์์
์ ๊ตฌ์ฑ ์์๋ ์์ฉ ํ๋ก๊ทธ๋จ ๋ฃจํธ ๊ตฌ์ฑ ์์ ๋ด๋ถ์ ๋ฐฐ์น๋ฉ๋๋ค. ๋ณต์กํ ๋ถ์์ฉ์ ์ฒ๋ฆฌํ๋ ๋ ๋ค๋ฅธ ๋ฏธ์น ๋ฐฉ๋ฒ์
๋๋ค. :stuck_out_tongue:
๋ด๊ฐ ์๋ ๋์ ์ฌ๊ธฐ์์ ๋ง์ ํ ๋ก ์ ํ์ต๋๋ค.
@winstonewert , ๋น์ ์ ์๊ฐ ์ฌํ๊ณผ ๋ฒ๊ทธ๊ฐ ์๋ ์ฝ๋ ์ฌ์์ ๋ํด ์ข์ ์ง์ ์ ํ์ต๋๋ค. ํน์ ์ ํ์ ๋ฒ๊ทธ/๋ณ๊ฒฝ ์ฌํญ์ ์ด๋ ์ชฝ์ด๋ ์๊ฐ ์ฌํ์์ ์๋ํ์ง ์์ ๊ฒ์ด๋ผ๊ณ ์๊ฐํ์ง๋ง ์ ๋ฐ์ ์ผ๋ก ๋น์ ์ด ์ณ๋ค๊ณ ์๊ฐํฉ๋๋ค.
@dtinth , ์ฃ์กํฉ๋๋ค๋ง, ๊ทํ์ ์๊ฒฌ ๋๋ถ๋ถ์ ๋ฐ๋ฅด๊ณ ์์ง ์์ต๋๋ค. action-creator/reducer "ducks" ์ฝ๋์ ์ผ๋ถ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์์ผ ํ๋ค๋ ์ ์์ ๋ถ์ํด์ผ ํฉ๋๋ค. ๊ทธ ์ด์์ผ๋ก ๋น์ ์ ๋๋ฅผ ์์์ต๋๋ค. ๋ด ์ด๊ธฐ ๊ฒ์๋ฌผ์ ์ฃผ์ ๋ชฉ์ ์ค ํ๋๋ ์ค์ฉ์ฃผ์ ์ค ํ๋์์ต๋๋ค.
@winstonewert ๋ "redux์ ๋ํ ๋ด ์๊ฐ์ ์ ์ฅ์๊ฐ ํญ์ ์ ํจํ ์ํ๋ผ๊ณ ์ฃผ์ฅํ๋ ๊ฒ ๊ฐ์ต๋๋ค."๋ผ๊ณ ๋งํ์ต๋๋ค.
@slorber ๋ "Redux @bvaughn ๋ฐ @sompylasar ์์ ์ผ์์ ์ธ ์ํ๋ ๋ฌด์์ ์๋ฏธํฉ๋๊น? ๋์คํจ์น๊ฐ ์๋ฃ๋๊ฑฐ๋ ๋์ง๋๋ค. ๋์ง๋ฉด ์ํ๊ฐ ๋ณ๊ฒฝ๋์ง ์์ต๋๋ค."
๋๋ ์ฐ๋ฆฌ๊ฐ ๋ค๋ฅธ ๊ฒ์ ๋ํด ์๊ฐํ๊ณ ์๋ค๊ณ ํ์ ํฉ๋๋ค. ๋ด๊ฐ "์ผ์์ ์ธ ๋ฌดํจ ์ํ"๋ผ๊ณ ๋งํ ๋ ๋๋ ๋ค์๊ณผ ๊ฐ์ ์ ์ค ์ผ์ด์ค๋ฅผ ์ธ๊ธํ๊ณ ์์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๋์ ๋๋ฃ๋ ์ต๊ทผ redux-search ๋ฅผ ์ถ์ํ์ต๋๋ค. ์ด ๊ฒ์ ๋ฏธ๋ค์จ์ด๋ ๊ฒ์ ๊ฐ๋ฅํ ํญ๋ชฉ ๋ชจ์์ ๋ํ ๋ณ๊ฒฝ ์ฌํญ์ ์์ ํ ๋ค์ ๊ฒ์์ ์ํด (์ฌ)์ธ๋ฑ์ฑํฉ๋๋ค. ์ฌ์ฉ์๊ฐ ํํฐ ํ ์คํธ๋ฅผ ์ ๊ณตํ๋ฉด redux-search๋ ์ฌ์ฉ์์ ํ ์คํธ์ ์ผ์นํ๋ ๋ฆฌ์์ค uid ๋ชฉ๋ก์ ๋ฐํํฉ๋๋ค. ๋ฐ๋ผ์ ๋ค์์ ๊ณ ๋ คํ์ญ์์ค.
์์ฉ ํ๋ก๊ทธ๋จ ์ ์ฅ์์ [{id: 1, name: "Alex"}, {id: 2, name: "Brian"}, {id: 3, name: "Charles"}]
๊ฐ์ ๋ช ๊ฐ์ง ๊ฒ์ ๊ฐ๋ฅํ ๊ฐ์ฒด๊ฐ ํฌํจ๋์ด ์๋ค๊ณ ์์ํด ๋ณด์ญ์์ค. ์ฌ์ฉ์๊ฐ ํํฐ ํ
์คํธ "e"๋ฅผ ์
๋ ฅํ์ผ๋ฏ๋ก ๊ฒ์ ๋ฏธ๋ค์จ์ด์๋ ID 1๊ณผ 3์ ๋ฐฐ์ด์ด ํฌํจ๋ฉ๋๋ค. ์ด์ ์ฌ์ฉ์ 1(Alex)์ด ๋ก์ปฌ์์ ์ฌ์ฉ์ ์์
์ ๋ํ ์๋ต์ผ๋ก ์ญ์ ๋๊ฑฐ๋ ๋ ์ด์ ํด๋น ์ฌ์ฉ์ ๋ ์ฝ๋๋ฅผ ํฌํจํ์ง ์์ต๋๋ค. ๋ฆฌ๋์๊ฐ ์ฌ์ฉ์ ์ปฌ๋ ์
์ ์
๋ฐ์ดํธํ๋ ์์ ์์ redux-search๊ฐ ์ปฌ๋ ์
์ ๋ ์ด์ ์กด์ฌํ์ง ์๋ ID๋ฅผ ์ฐธ์กฐํ๊ธฐ ๋๋ฌธ์ ์คํ ์ด๊ฐ ์ผ์์ ์ผ๋ก ์ ํจํ์ง ์์ต๋๋ค. ๋ฏธ๋ค์จ์ด๊ฐ ๋ค์ ์คํ๋๋ฉด ์๋ชป๋ ์ํ๋ฅผ ์์ ํฉ๋๋ค. ์ด๋ฌํ ์ข
๋ฅ์ ์ผ์ ํธ๋ฆฌ์ ํ ๋
ธ๋๊ฐ ๋ค๋ฅธ ๋
ธ๋์ ๊ด๋ จ๋์ด ์์ ๋๋ง๋ค ๋ฐ์ํ ์ ์์ต๋๋ค.
@slorber ๋ "์ก์ ์์ฑ์๊ฐ ์ฑ ๋ณด๊ธฐ์ ๋ ์ด์์๊ณผ ๋ฐ์ ํ๊ฒ ์ฐ๊ฒฐ๋๊ธฐ ๋๋ฌธ์ ์ด ์ ๊ทผ ๋ฐฉ์์ด ๋ง์์ ๋ค์ง ์์ต๋๋ค. ์ด๋ actionCreator๊ฐ ๊ฒฐ์ ์ ๋ด๋ฆฌ๊ธฐ ์ํด UI ์ํ ํธ๋ฆฌ์ ๊ตฌ์กฐ๋ฅผ ์์์ผ ํ๋ค๊ณ ๊ฐ์ ํฉ๋๋ค."๋ผ๊ณ ๋งํ์ต๋๋ค.
์ก์ ์์ฑ์๋ฅผ "์ฑ ๋ณด๊ธฐ์ ๋ ์ด์์์" ๊ฒฐํฉํ๋ ์ ๊ทผ ๋ฐฉ์์ด ์๋ฏธํ๋ ๋ฐ๋ฅผ ์ดํดํ์ง ๋ชปํฉ๋๋ค. ์ํ ํธ๋ฆฌ๋ UI์ _drives_(๋๋ ์๋ ค์ค๋๋ค). ์ด๊ฒ์ด Flux์ ์ฃผ์ ๋ชฉ์ ์ค ํ๋์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ก์ ์์ฑ์์ ๋ฆฌ๋์๋ ์ ์์ ๋ฐ๋ผ ํด๋น ์ํ์ ์ฐ๊ฒฐ๋์ด ์์ต๋๋ค(UI์๋ ์ฐ๊ฒฐ๋์ง ์์).
๋ด๊ฐ ์ ํธํ๋ ๊ฒ์ผ๋ก ์์ฑํ ์์ ์ฝ๋๋ ๋ด๊ฐ ์ผ๋์ ๋ ๊ฒ์ด ์๋๋๋ค. ์ด์ฉ๋ฉด ๋ด๊ฐ ๋ ์์ ์ ์ ์ค๋ช ํ์ง ๋ชปํ์ ์๋ ์์ต๋๋ค. ์ด์ ๊ฐ์ ๋ ผ์์ ์ด๋ ค์์ ์ผ๋ฐ์ ์ผ๋ก ๋จ์ํ๊ฑฐ๋ ์ผ๋ฐ์ ์ธ ์์์ ๋ํ๋์ง ์๋๋ค๋ ๊ฒ์ ๋๋ค. (์๋ฅผ ๋ค์ด ํ์ค TODO MVC ์ฑ์ ์ด์ ๊ฐ์ ๋ฏธ๋ฌํ ๋ ผ์๋ฅผ ํ๊ธฐ์ ์ถฉ๋ถํ ๋ณต์กํ์ง ์์ต๋๋ค.)
๋ง์ง๋ง ์์ ์ ๋ช ํํ๊ฒ ํ๊ธฐ ์ํด ํธ์ง ํ์ต๋๋ค.
Btw @slorber ๋ ๋ด๊ฐ ์ผ๋์ ๋์๋ ๊ฒ์ ์์ ๋๋ค. ์ฝ๊ฐ ์ธ์์ ์ ๋๋ค.
์ํ์ ๋ง์ ๋ ธ๋๊ฐ ์๋ค๊ณ ๊ฐ์ ํด ๋ณด๊ฒ ์ต๋๋ค. ์ด๋ฌํ ๋ ธ๋ ์ค ํ๋๋ ๊ณต์ ๋ฆฌ์์ค๋ฅผ ์ ์ฅํฉ๋๋ค. ("๊ณต์ "๋ ๋ก์ปฌ๋ก ์บ์๋๊ณ ์ ํ๋ฆฌ์ผ์ด์ ๋ด์ ์ฌ๋ฌ ํ์ด์ง์์ ์ก์ธ์คํ๋ ๋ฆฌ์์ค๋ฅผ ์๋ฏธํฉ๋๋ค.) ์ด๋ฌํ ๊ณต์ ๋ฆฌ์์ค์๋ ๊ณ ์ ํ ์์ ์์ฑ์์ ๊ฐ์๊ธฐ("๋")๊ฐ ์์ต๋๋ค. ๋ค๋ฅธ ๋ ธ๋๋ ํน์ ์ ํ๋ฆฌ์ผ์ด์ ํ์ด์ง์ ๋ํ ์ ๋ณด๋ฅผ ์ ์ฅํฉ๋๋ค. ๊ทํ์ ํ์ด์ง์๋ ์์ฒด ์ค๋ฆฌ๋ ์์ต๋๋ค.
๊ทํ์ ํ์ด์ง๊ฐ ์ต์ ์ ๊ฐ์ฅ ๋ฐ์ด๋ ๊ฒ์ ๋ก๋ํ๊ณ ์ฌ์ฉ์๊ฐ ํธ์งํ ์ ์๋๋ก ํ์ฉํด์ผ ํ๋ค๊ณ ๊ฐ์ ํด ๋ณด๊ฒ ์ต๋๋ค. ๋ค์์ ์ด๋ฌํ ์ํฉ์ ์ฌ์ฉํ ์ ์๋ ์ก์ ์์ฑ์ ์ ๊ทผ ๋ฐฉ์์ ์์ ๋๋ค.
import { fetchThing, thingSelector } from 'resources/thing/duck'
import { showError } from 'messages/duck'
export function fetchAndProcessThing ({ params }): Object {
const { id } = params
return async ({ dispatch, getState }) => {
try {
await dispatch(fetchThing({ id }))
const thing = thingSelector(getState())
dispatch({ type: 'PROCESS_THING', thing })
} catch (err) {
dispatch(showError(`Invalid thing id="${id}".`))
}
}
}
@winstonewert ๋ ๋ ๋ฒ์งธ ์์ ๋์คํจ์น๊ฐ ์คํจํ๋ฉด ๋ ์์ ์ ๋กค๋ฐฑํ๊ธฐ๋ฅผ ์ํ ๊ฒ์ ๋๋ค.
์๋์. ๋ ๊ฐ์ง ์์ ์ ์ ๋ฌํ๋ ์์ ์์ฑ์๋ฅผ ์์ฑํ์ง ์์ ๊ฒ์ ๋๋ค. ๋ ๊ฐ์ง๋ฅผ ์ํํ๋ ๋จ์ผ ์์ ์ ์ ์ํฉ๋๋ค. OP๋ ๋ด๊ฐ ์ซ์ดํ๋ ์ผ์์ ์ธ ์ ํจํ์ง ์์ ์ํ๋ฅผ ํ์ฉํ๋ ๋ ์์ ์์ ์ ์ ๋ฌํ๋ ์์ ์์ฑ์๋ฅผ ์ ํธํ๋ ๊ฒ ๊ฐ์ต๋๋ค.
๋ฆฌ๋์๊ฐ ์ฌ์ฉ์ ์ปฌ๋ ์ ์ ์ ๋ฐ์ดํธํ๋ ์์ ์์ redux-search๊ฐ ์ปฌ๋ ์ ์ ๋ ์ด์ ์กด์ฌํ์ง ์๋ ID๋ฅผ ์ฐธ์กฐํ๊ธฐ ๋๋ฌธ์ ์คํ ์ด๊ฐ ์ผ์์ ์ผ๋ก ์ ํจํ์ง ์์ต๋๋ค. ๋ฏธ๋ค์จ์ด๊ฐ ๋ค์ ์คํ๋๋ฉด ์๋ชป๋ ์ํ๋ฅผ ์์ ํฉ๋๋ค. ์ด๋ฌํ ์ข ๋ฅ์ ์ผ์ ํธ๋ฆฌ์ ํ ๋ ธ๋๊ฐ ๋ค๋ฅธ ๋ ธ๋์ ๊ด๋ จ๋์ด ์์ ๋๋ง๋ค ๋ฐ์ํ ์ ์์ต๋๋ค.
์ด๊ฒ์ ์ค์ ๋ก ๋๋ฅผ ๊ดด๋กญํ๋ ์ข ๋ฅ์ ์ผ์ด์ค์ ๋๋ค. ๋ด ์๊ฐ์ ์ธ๋ฑ์ค๋ ์ด์์ ์ผ๋ก๋ ๊ฐ์๊ธฐ ๋๋ ์ ํ๊ธฐ์ ์ํด ์์ ํ ์ฒ๋ฆฌ๋๋ ๊ฒ์ ๋๋ค. ๊ฒ์์ ์ต์ ์ํ๋ก ์ ์งํ๊ธฐ ์ํด ์ถ๊ฐ ์์ ์ ๋ณด๋ด์ผ ํ๋ ๊ฒ์ ๋ ์์ํ redux ์ฌ์ฉ์ผ๋ก ๋ณด์ ๋๋ค.
OP๋ ๋ด๊ฐ ์ซ์ดํ๋ ์ผ์์ ์ธ ์ ํจํ์ง ์์ ์ํ๋ฅผ ํ์ฉํ๋ ๋ ์์ ์์ ์ ์ ๋ฌํ๋ ์์ ์์ฑ์๋ฅผ ์ ํธํ๋ ๊ฒ ๊ฐ์ต๋๋ค.
์ ํํ. ์ํ ํธ๋ฆฌ์ ์์ ์์ฑ์์ ๋ ธ๋์ ๊ด๋ จํ์ฌ ๋จ์ผ ์์ ์ ์ ํธํฉ๋๋ค. ๊ทธ๋ฌ๋ ๋จ์ผ ๊ฐ๋ ์ ์ฌ์ฉ์ "์์ "์ด ์ํ ํธ๋ฆฌ์ ์ฌ๋ฌ ๋ ธ๋์ ์ํฅ์ ๋ฏธ์น๋ ๊ฒฝ์ฐ ์ฌ๋ฌ ์์ ์ ์ ๋ฌํด์ผ ํฉ๋๋ค. ๊ฐ ์์ ์ ๊ฐ๋ณ์ ์ผ๋ก ํธ์ถํ๊ฑฐ๋(_bad_๋ผ๊ณ ์๊ฐํจ) ๋จ์ผ ์์ ์์ฑ์๊ฐ ์์ ์ ๋ฐ์กํ๋๋ก ํ ์ ์์ต๋๋ค(๋ณด๊ธฐ ๋ ์ด์ด์์ ํด๋น ์ ๋ณด๋ฅผ ์จ๊ธฐ๊ธฐ ๋๋ฌธ์ _better_๋ผ๊ณ ์๊ฐํ๋ redux-thunk ๋ฐฉ์).
์ด๊ฒ์ ์ค์ ๋ก ๋๋ฅผ ๊ดด๋กญํ๋ ์ข ๋ฅ์ ์ผ์ด์ค์ ๋๋ค. ๋ด ์๊ฐ์ ์ธ๋ฑ์ค๋ ์ด์์ ์ผ๋ก๋ ๊ฐ์๊ธฐ ๋๋ ์ ํ๊ธฐ์ ์ํด ์์ ํ ์ฒ๋ฆฌ๋๋ ๊ฒ์ ๋๋ค. ๊ฒ์์ ์ต์ ์ํ๋ก ์ ์งํ๊ธฐ ์ํด ์ถ๊ฐ ์์ ์ ๋ณด๋ด์ผ ํ๋ ๊ฒ์ ๋ ์์ํ redux ์ฌ์ฉ์ผ๋ก ๋ณด์ ๋๋ค.
์ถ๊ฐ ์์ ์ ๋ฐ์กํ์ง ์์ต๋๋ค. ๊ฒ์์ ๋ฏธ๋ค์จ์ด์ ๋๋ค. ์๋์ ๋๋ค. ๊ทธ๋ฌ๋ ํธ๋ฆฌ์ ๋ ๋ ธ๋๊ฐ ์ผ์นํ์ง ์์ ๋ ์ผ์์ ์ธ ์ํ๊ฐ ์กด์ฌํฉ๋๋ค.
@bvaughn ์, ์์์ฃผ์์
์, ์์ ์ฝ๋๋ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ ๋ฐ ๊ธฐํ ๋ถ์์ฉ/IO์ ๊ด๋ จ์ด ์๋ ๋ฐ๋ฉด ์์ ์ฝ๋๋ ๋ถ์์ฉ์ ์ ๋ฐํ ์ ์์ต๋๋ค. ์์ ์ฝ๋์ ์์ ์ฝ๋๋ฅผ ๋น๊ตํ๋ ค๋ฉด ์ด ํ ๋ฅผ ์ฐธ์กฐํ์ธ์.
Flux ๋ชจ๋ฒ ์ฌ๋ก์ ๋ฐ๋ฅด๋ฉด ์์ ์ "์ฌ์ฉ์์ ์์ ์ ์ค๋ช ํด์ผ ํ๋ฉฐ ์ค์ ์๊ฐ ์๋๋๋ค." Flux ๋ฌธ์ ๋ ๋ํ ์ด๋ฌํ ์์ ์ด ์ด๋์์ ์๋์ง ์ถ๊ฐ๋ก ์์ํ์ต๋๋ค.
์์ฉ ํ๋ก๊ทธ๋จ๊ณผ ์ํธ ์์ฉํ๋ ์ฌ๋์ ํตํด ๋๋ ์น API ํธ์ถ์ ํตํด ์ ๋ฐ์ดํฐ๊ฐ ์์คํ ์ ์ ๋ ฅ๋๋ฉด ํด๋น ๋ฐ์ดํฐ๋ ์ ๋ฐ์ดํฐ ํ๋์ ํน์ ์์ ์ ํ์ ํฌํจํ๋ ๊ฐ์ฒด ๋ฆฌํฐ๋ด์ธ ์์ ์ผ๋ก ํจํค์ง๋ฉ๋๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ์กฐ์น๋ "๋ฐ์ํด์ผ ํ ์ผ"์ด ์๋๋ผ "์ผ์ด๋ ์ผ"์ ์ค๋ช ํ๋ ์ฌ์ค/๋ฐ์ดํฐ์ ๋๋ค. ์์ ์ ๋ค๋ฅธ ๋ถ์์ฉ ์์ด ๋๊ธฐ์ ์ด๊ณ ์์ธก ๊ฐ๋ฅํ๊ฒ ์ด๋ฌํ ์กฐ์น์๋ง ๋์ํ ์ ์์ต๋๋ค. ๋ค๋ฅธ ๋ชจ๋ ๋ถ์์ฉ์ ์ก์ ์ ์์(๋๋ sagas :wink:)์์ ์ฒ๋ฆฌํด์ผ ํฉ๋๋ค.
๋๋ ์ด๊ฒ์ด ์ต์ ์ ๋ฐฉ๋ฒ์ด๊ฑฐ๋ ๋ค๋ฅธ ์ด๋ค ๋ฐฉ๋ฒ๋ณด๋ค ๋ ๋ซ๋ค๊ฑฐ๋ ์ฌ์ง์ด ์ข์ ๋ฐฉ๋ฒ์ด๋ผ๊ณ ๋งํ๋ ๊ฒ์ด ์๋๋๋ค. ๊ทธ๋ฌ๋ ์ด๊ฒ์ด ๋ด๊ฐ ํ์ฌ ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ด๋ผ๊ณ ์๊ฐํ๋ ๊ฒ์ ๋๋ค.
์๋ฅผ ๋ค์ด ์ฌ์ฉ์๊ฐ ์๊ฒฉ ์๋ฒ์ ์ฐ๊ฒฐํด์ผ ํ๋ ์ค์ฝ์ด๋ณด๋๋ฅผ ๋ณด๊ณ ์ถ์ดํ๋ค๊ณ ๊ฐ์ ํด ๋ณด๊ฒ ์ต๋๋ค. ๋ค์์ ๋ฐ์ํด์ผ ํ๋ ์ผ์ ๋๋ค.
์ก์ ์ด ์ฌ์ฉ์์ ์ก์ ์ด๋ ์๋ฒ ์๋ต์ ๊ฒฐ๊ณผ๋ก๋ง ์คํ ์ด์ ๋๋ฌํ ์ ์๋ค๊ณ ๊ฐ์ ํ๋ฉด 5๊ฐ์ ์ก์ ์ ์์ฑํ ์ ์์ต๋๋ค.
SCOREBOARD_VIEW
(์ฌ์ฉ์๊ฐ ์ค์ฝ์ด๋ณด๋ ๋ณด๊ธฐ ๋ฒํผ์ ํด๋ฆญํ ๊ฒฐ๊ณผ)SCOREBOARD_FETCH_SUCCESS
(์๋ฒ์ ์ฑ๊ณต์ ์ธ ์๋ต ๊ฒฐ๊ณผ)SCOREBOARD_FETCH_FAILURE
(์๋ฒ์ ์ค๋ฅ ์๋ต ๊ฒฐ๊ณผ)SCOREBOARD_CLOSE
(์ฌ์ฉ์๊ฐ ๋ซ๊ธฐ ๋ฒํผ์ ํด๋ฆญํ ๊ฒฐ๊ณผ)MESSAGE_BOX_CLOSE
(์ฌ์ฉ์๊ฐ ๋ฉ์์ง ์์์ ๋ซ๊ธฐ ๋ฒํผ์ ํด๋ฆญํ ๊ฒฐ๊ณผ)์ด 5๊ฐ์ง ์์
์ ์์ ๋ชจ๋ ์๊ตฌ ์ฌํญ์ ์ฒ๋ฆฌํ๊ธฐ์ ์ถฉ๋ถํฉ๋๋ค. ์ฒ์ 4๊ฐ์ ์์
์ "์ค๋ฆฌ"์ ์๋ฌด ๊ด๋ จ์ด ์์์ ์ ์ ์์ต๋๋ค. ๋ชจ๋ ์์
์ ์ธ๋ถ ์ธ๊ณ์์ ๋ฐ์ํ ์ผ๋ง ์ค๋ช
MESSAGE_BOX_OPEN
์ก์
์ ๊ฐ์ง๊ณ ์์ง ์์ต๋๋ค. ์๋ํ๋ฉด ๊ทธ๊ฒ์ "์ผ์ด๋ ์ผ"์ด ์๋๊ธฐ ๋๋ฌธ์
๋๋ค(๋น๋ก ๊ทธ๊ฒ์ด ์ผ์ด๋์ผ ํ์ง๋ง).
์ํ ํธ๋ฆฌ๋ฅผ ๋ณ๊ฒฝํ๋ ์ ์ผํ ๋ฐฉ๋ฒ์ ๋ฐ์ํ ์ผ์ ์ค๋ช ํ๋ ๊ฐ์ฒด์ธ ์์ ์ ๋ด๋ณด๋ด๋ Redux์ README
๊ทธ๋ค์ ๋ค์ ์ก์ ์ ์์์ ํจ๊ป ๋ถ์ด ์์ต๋๋ค.
function viewScoreboard () {
return async function (dispatch) {
dispatch({ type: 'SCOREBOARD_VIEW' })
try {
const result = fetchScoreboardFromServer()
dispatch({ type: 'SCOREBOARD_FETCH_SUCCESS', result })
} catch (e) {
dispatch({ type: 'SCOREBOARD_FETCH_FAILURE', error: String(e) })
}
}
}
function closeScoreboard () {
return { type: 'SCOREBOARD_CLOSE' }
}
๊ทธ๋ฌ๋ฉด ์ ์ฅ์์ ๊ฐ ๋ถ๋ถ(๋ฆฌ๋์๋ก ๊ด๋ฆฌ)์ด ๋ค์ ์์ ์ ๋ฐ์ํ ์ ์์ต๋๋ค.
| ์ ์ฅ/๊ฐ์๊ธฐ์ ์ผ๋ถ | ํ๋ |
| --- | --- |
| ์ค์ฝ์ด๋ณด๋๋ณด๊ธฐ | SCOREBOARD_VIEW
์ ๋ํ ๊ฐ์์ฑ ์
๋ฐ์ดํธ, SCOREBOARD_CLOSE
๋ฐ SCOREBOARD_FETCH_FAILURE
์ ๋ํ false |
| ์ค์ฝ์ด๋ณด๋ ๋ก๋ฉ ํ์๊ธฐ | SCOREBOARD_VIEW
์ ๋ํ ๊ฐ์์ฑ ์
๋ฐ์ดํธ, SCOREBOARD_FETCH_*
์ ๋ํ false |
| ์ค์ฝ์ด๋ณด๋๋ฐ์ดํฐ | SCOREBOARD_FETCH_SUCCESS
์ ๋งค์ฅ ๋ด ๋ฐ์ดํฐ ์
๋ฐ์ดํธ |
| ๋ฉ์์ง ์์ | ์ฌ์ค ๋ฐ ์ ์ฅ์ ๋ํ ๋ฉ์์ง์ ๋ํ ์
๋ฐ์ดํธ ๊ฐ์์ฑ SCOREBOARD_FETCH_FAILURE
, ๊ทธ๋ฆฌ๊ณ ๊ฑฐ์ง์ผ๋ก ์
๋ฐ์ดํธ ๊ฐ์์ฑ MESSAGE_BOX_CLOSE
|
๋ณด์๋ค์ํผ, ๋จ์ผ ์์ ์ ์์ ์ ๋ง์ ๋ถ๋ถ์ ์ํฅ์ ์ค ์ ์์ต๋๋ค. ์์ ์๋ ๋ช ๋ น(๋ฌด์์ ํด์ผ ํฉ๋๊น?)๋ณด๋ค๋ ์์ (๋ฌด์จ ์ผ์ด ์ผ์ด๋ฌ์ต๋๊น?)์ ๋ํ ๋์ ์์ค์ ์ค๋ช ๋ง ์ ๊ณต๋ฉ๋๋ค. ๊ฒฐ๊ณผ์ ์ผ๋ก:
์๋ฌด ๊ฒ๋ ๋ฉ์์ง ์์์ ์ํ์ ์ํฅ์ ์ค ์ ์์ต๋๋ค. ์ด๋ค ์ด์ ๋ก๋ ์ด๋ผ๊ณ ๋งํ ์ ์๋ ์ฌ๋์ ์๋ฌด๋ ์์ต๋๋ค. ๊ตฌ๋ ํ ํญ๋ชฉ(์ฌ์ฉ์ ์์ ๋ฐ ์๋ฒ ์๋ต)์๋ง ๋ฐ์ํฉ๋๋ค.
์๋ฅผ ๋ค์ด ์๋ฒ๊ฐ ์ ์ํ์ ๊ฐ์ ธ์ค์ง ์๊ณ ๋ฉ์์ง ์์๊ฐ ๋ํ๋์ง ์์ผ๋ฉด SHOW_MESSAGE_BOX
์ก์
์ด ๋์คํจ์น๋์ง ์๋ ์ด์ ๋ฅผ ์ฐพ์ ํ์๊ฐ ์์ต๋๋ค. ๋ฉ์์ง ์์๊ฐ SCOREBOARD_FETCH_FAILURE
์์
์ ์ ๋๋ก ์ฒ๋ฆฌํ์ง ๋ชปํ ๊ฒ์ด ๋ถ๋ช
ํด์ง๋๋ค.
์์ ์ ์ฌ์ํ๊ณ ํซ ๋ฆฌ๋ก๋๋๊ณ ์๊ฐ ์ฌํ์ด ๋ ์ ์์ต๋๋ค.
์์ ์ ๋ฐ์์ ์๊ด์์ด ์ก์ ์ ์์๊ฐ ์ธ๋ถ ์ธ๊ณ์์ ์ผ์ด๋๋ ์ผ์ ์ฌ๋ฐ๋ฅด๊ฒ ์ค๋ช ํ๋์ง ํ ์คํธํ ์ ์์ต๋๋ค.
๊ฐ์ ๋ฐฉ์์ผ๋ก ๋ฆฌ๋์๋ ์ธ๋ถ ์ธ๊ณ์ ๋์์ ์ ์ ํ๊ฒ ๋ฐ์ํ๋์ง ์ฌ๋ถ๋ฅผ ๊ฐ๋จํ ํ ์คํธํ ์ ์์ต๋๋ค.
(ํตํฉ ํ ์คํธ๋ ์ฌ์ ํ ๋งค์ฐ ์ ์ฉํฉ๋๋ค.)
๊ฑฑ์ ๋ง. :) ์ถ๊ฐ ์ค๋ช
์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค. ์ค์ ๋ก ์ฐ๋ฆฌ๊ฐ ์ฌ๊ธฐ์ ๋์ํ๋ ๊ฒ์ฒ๋ผ ๋ค๋ฆฝ๋๋ค. ์์ action-creator viewScoreboard
๋ฅผ ๋ณด๋ฉด ๋ฐ๋ก ์์ ์์ action-creator fetchAndProcessThing
์ ๋งค์ฐ ์ ์ฌํฉ๋๋ค.
์ก์ ์์ฑ์์ ๋ฆฌ๋์๋ ๋ณ๋๋ก ํ ์คํธํ ์ ์์ต๋๋ค.
๋๋ ์ด๊ฒ์ ๋์ํ์ง๋ง ์ข ์ข ํจ๊ป ํ ์คํธํ๋ ๊ฒ์ด ๋ ์ค์ฉ์ ์ธ ์๋ฏธ๊ฐ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ๋น์ ์ ํ๋์ด๋ ๊ฐ์๊ธฐ(๋ ๋ค)๊ฐ ๋งค์ฐ ๊ฐ๋จํ ๊ฐ๋ฅ์ฑ์ด ๋๊ธฐ ๋๋ฌธ์ ๊ฐ๋จํ ๊ฒ์ ๋จ๋ ์ผ๋ก ํ ์คํธํ ๋์ ๋ ธ๋ ฅ ๋๋น ์์ต์ ๋ค์ ๋ฎ์ต๋๋ค. ๊ทธ๋์ ์ก์ ์์ฑ๊ธฐ, ๊ฐ์๊ธฐ ๋ฐ ๊ด๋ จ ์ ํ๊ธฐ๋ฅผ ํจ๊ป ํ ์คํธํ ๊ฒ์ ์ ์ํ์ต๋๋ค("์ค๋ฆฌ"๋ก).
๊ทธ๋ฌ๋ ๋จ์ผ ๊ฐ๋ ์ ์ฌ์ฉ์ "์์ "์ด ์ํ ํธ๋ฆฌ์ ์ฌ๋ฌ ๋ ธ๋์ ์ํฅ์ ๋ฏธ์น๋ ๊ฒฝ์ฐ ์ฌ๋ฌ ์์ ์ ์ ๋ฌํด์ผ ํฉ๋๋ค.
๊ทธ๊ฒ์ด ๋ฐ๋ก ๋น์ ์ดํ๋ ์ผ์ด redux์ ๋ํ ๋ชจ๋ฒ ์ฌ๋ก๋ก ๊ฐ์ฃผ๋๋ ๊ฒ๊ณผ ๋ค๋ฅด๋ค๊ณ ์๊ฐํ๋ ๋ถ๋ถ์ ๋๋ค. ํ์ค ๋ฐฉ๋ฒ์ ์ํ ํธ๋ฆฌ์ ์ฌ๋ฌ ๋ ธ๋๊ฐ ์๋ตํ๋ ํ๋์ ์์ ์ ๊ฐ๋ ๊ฒ์ ๋๋ค.
์, ํฅ๋ฏธ๋ก์ด ๊ด์ฐฐ @winstonewert. ์ฐ๋ฆฌ๋ ๊ฐ "ducks" ๋ฒ๋ค์ ๋ํด ๊ณ ์ ํ ์ ํ ์์๋ฅผ ์ฌ์ฉํ๋ ํจํด์ ๋ฐ๋ฅด๊ณ ์์ผ๋ฏ๋ก ํ์ฅ์๋ ํ์ ์์ ์์ฑ์๊ฐ ์ ๋ฌํ ์์ ์๋ง ์๋ตํฉ๋๋ค. ์ฒ์์๋ ์ก์ ์ ๋ฐ์ํ๋ ์์์ ๋ฆฌ๋์์ ๋ํด ์ด๋ป๊ฒ ๋๋ผ๋์ง ์์งํ ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ์ฝ๊ฐ ๋์ ์บก์ํ ๊ฐ์ ๋๋์ด ๋ญ๋๋ค.
์ฐ๋ฆฌ๋ ๊ฐ "ducks" ๋ฒ๋ค์ ๋ํด ๊ณ ์ ํ ์ ํ ์์๋ฅผ ์ฌ์ฉํ๋ ํจํด์ ๋ฐ๋์ต๋๋ค.
๋ฌธ์์ ์ด๋ ๊ณณ์์๋ ์ด๋ฅผ ๋ณด์ฆํ์ง ์๋๋ค๋ ์ ์ ์ ์ํ์ญ์์ค. ;-) ๊ทธ๊ฒ์ด ๋์๋ค๊ณ ๋งํ์ง๋ ์์ง๋ง ์ฌ๋๋ค์๊ฒ Redux์ ๋ํด ๋๋๋ก ์๋ชป๋ ์์ด๋์ด๋ฅผ ์ ๊ณตํฉ๋๋ค.
๋ฐ๋ผ์ ํ์ฅ์๋ ํ์ ์์ ์์ฑ์๊ฐ ์ ๋ฌํ ์์ ์๋ง ์๋ตํฉ๋๋ค.
Redux์๋ ๊ฐ์๊ธฐ/์ก์ ์์ฑ๊ธฐ ํ์ด๋ง๊ณผ ๊ฐ์ ๊ฒ์ด ์์ต๋๋ค. ๊ทธ๊ฒ์ ์์ ํ ์ค๋ฆฌ์ ์ผ์ ๋๋ค. ์ด๋ค ์ฌ๋๋ค์ ๊ทธ๊ฒ์ ์ข์ํ์ง๋ง Redux/Flux ๋ชจ๋ธ์ ๊ทผ๋ณธ์ ์ธ ๊ฐ์ ์ ํ๋ฆฌ๊ฒ ํฉ๋๋ค. ์ํ ๋์ฐ๋ณ์ด๋ ์๋ก ๋ถ๋ฆฌ๋๊ณ ์ด๋ฅผ ์ผ์ผํค๋ ์ฝ๋์์ ๋ถ๋ฆฌ๋ฉ๋๋ค.
์ฒ์์๋ ์ก์ ์ ๋ฐ์ํ๋ ์์์ ๋ฆฌ๋์์ ๋ํด ์ด๋ป๊ฒ ๋๋ผ๋์ง ์์งํ ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ์ฝ๊ฐ ๋์ ์บก์ํ ๊ฐ์ ๋๋์ด ๋ญ๋๋ค.
์บก์ํ ๊ฒฝ๊ณ๋ฅผ ๊ณ ๋ คํ๋ ํญ๋ชฉ์ ๋ฐ๋ผ ๋ค๋ฆ ๋๋ค. ์ก์ ์ ์ฑ์์ ์ ์ญ์ด๊ณ ๊ด์ฐฎ์ ๊ฒ ๊ฐ์์. ๋ณต์กํ ์ ํ ์๊ตฌ ์ฌํญ ๋๋ฌธ์ ์ฑ์ ํ ๋ถ๋ถ์ด ๋ค๋ฅธ ๋ถ๋ถ์ ์์ ์ ๋ฐ์ํ๊ธฐ๋ฅผ ์ํ ์ ์์ผ๋ฉฐ ์ฐ๋ฆฌ๋ ์ด๊ฒ์ด ๊ด์ฐฎ๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ปคํ๋ง์ ์ต์ํ๋ฉ๋๋ค. ์ฌ์ฉ์๊ฐ ์์กดํ๋ ๊ฒ์ ๋ฌธ์์ด๊ณผ ์์ ๊ฐ์ฒด ๋ชจ์๋ฟ์ ๋๋ค. ์ด์ ์ ์ก์ ์ ์์์ ๋ง์ ์ฐ๊ฒฐ์ ๋ง๋ค์ง ์๊ณ ๋ ์ฑ์ ๋ค๋ฅธ ๋ถ๋ถ์์ ์ก์ ์ ์๋ก์ด ํ์๋ฌผ์ ์ฝ๊ฒ ๋์ ํ ์ ์๋ค๋ ๊ฒ์ ๋๋ค. ์ปดํฌ๋ํธ๋ ์ก์ ์ด โโ๋์คํจ์น๋ ๋ ์ ํํ ๋ฌด์จ ์ผ์ด ์ผ์ด๋๋์ง ์์ง ๋ชปํฉ๋๋ค. ์ด๊ฒ์ ๋ฆฌ๋์ ์ชฝ์์ ๊ฒฐ์ ๋ฉ๋๋ค.
๋ฐ๋ผ์ ๊ณต์ ๊ถ์ฅ ์ฌํญ์ ๋จผ์ ๋์ผํ ์์ ์ ๋ค๋ฅธ ๋ฆฌ๋์๊ฐ ์๋ตํ๋๋ก ํ๋ ๊ฒ์ ๋๋ค. ์ด์ํด์ง๋ฉด ๋ฐ๋์ ๋ณ๋์ ์ก์ ํฌ๋ฆฌ์์ดํฐ๋ฅผ ๋ง๋์ธ์. ๊ทธ๋ฌ๋ ์ด ์ ๊ทผ ๋ฐฉ์์ผ๋ก ์์ํ์ง ๋ง์ญ์์ค.
์ ํ๊ธฐ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ์ฌ์ค ์ํ์์ ์ฝ๋ ์ ์ง ๊ธฐ๋ฅ("์ ํ๊ธฐ")์ ๊ฐ์๊ธฐ์ ํจ๊ป ๋ด๋ณด๋ด๊ณ ๊ตฌ์ฑ ์์์ ์ํ ๊ตฌ์กฐ๋ฅผ ํ๋์ฝ๋ฉํ๋ ๋์ ํญ์ mapStateToProps
์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ๋ด๋ถ ์ํ ๋ชจ์์ ์ฝ๊ฒ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค. ์ฑ๋ฅ์ ์ํด reselect ๋ฅผ ์ฌ์ฉํ ์ ์์ง๋ง(๊ผญ ๊ทธ๋ฐ ๊ฒ์ ์๋์ง๋ง) shopping-cart
์์ ์ ๊ฐ์ด ์์งํ๊ฒ ์ ํ๊ธฐ๋ฅผ ๊ตฌํํ ์๋ ์์ต๋๋ค.
์๋ง๋ ๊ทธ๊ฒ์ ๋น์ ์ด ๋ช ๋ นํ ์คํ์ผ๋ก ํ๋ก๊ทธ๋๋ฐํ๋์ง ์๋๋ฉด ๋ฐ์ํ ์คํ์ผ๋ก ํ๋ก๊ทธ๋๋ฐํ๋์ง์ ๋ฌ๋ ค ์์ต๋๋ค. ์ค๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ฉด ์ก์ ๊ณผ ๋ฆฌ๋์๊ฐ ๊ณ ๋๋ก ๊ฒฐํฉ๋์ด ๋ ๋ช ๋ น์ ์ธ ์ก์ ์ ์ฅ๋ คํ ์ ์์ต๋๋ค.
SHOW_MESSAGE_BOX
๋๋ SHOW_ERROR
์ ๊ฐ์ด "ํ ์ผ"์ด ์ ๊ณต๋ฉ๋๋ค.DATA_FETCHING_FAILED
๋๋ USER_ENTERED_INVALID_THING_ID
. ๊ทธ์ ๋ฐ๋ผ ๋งค์ฅ์ด ๋ฐ์ํฉ๋๋ค.์ด์ ์์์๋ ์ฌ์ค์ด ์๋๊ธฐ ๋๋ฌธ์ SHOW_MESSAGE_BOX
action ๋๋ showError('Invalid thing id="'+id+'"')
action creator๊ฐ ์์ต๋๋ค. ๋ช
๋ น์
๋๋ค.
๊ทธ ์ฌ์ค์ด ์ ์ฅ์์ ๋ค์ด์ค๋ฉด ๊ทธ ์ฌ์ค์ ์์ ๋ฆฌ๋์ ๋ด์์ ๋ช ๋ น์ผ๋ก ๋ณํํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด
// type Command = State โ State
// :: Action โ Command
function interpretAction (action) {
switch (action.type) {
case 'DATA_FETCHING_FAILED':
return showErrorMessage('Data fetching failed')
break
case 'USER_ENTERED_INVALID_THING_ID':
return showErrorMessage('User entered invalid thing ID')
break
case 'CLOSE_ERROR_MESSAGE':
return hideErrorMessage()
break
default:
return doNothing()
}
}
// :: (State, Action) โ State
function errorMessageReducer (state, action) {
return interpretAction(action)(state)
}
const showErrorMessage = message => state => ({ visible: true, message })
const hideErrorMessage = () => state => ({ visible: false })
const doNothing = () => state => state
ํ๋์ด "๋ช ๋ น"์ด ์๋ "์ฌ์ค"๋ก ์์ ์ ๋ค์ด๊ฐ ๋ ์๋ชป๋ ๊ฐ๋ฅ์ฑ์ด ์ ์ต๋๋ค. ๊ธ์์, ์ฌ์ค์ด๊ธฐ ๋๋ฌธ์ ๋๋ค.
์ด์ ๊ฐ์๊ธฐ๊ฐ ๊ทธ ์ฌ์ค์ ์๋ชป ํด์ํ๋ฉด ์ฝ๊ฒ ์์ ํ ์ ์์ผ๋ฉฐ ์์ ์ฌํญ์ ์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ ์ด๋ํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ก์ ์ ์์๊ฐ ๊ทธ ์ฌ์ค์ ์๋ชป ํด์ํ๋ฉด ์ก์ ์ ์์๋ฅผ ๋ค์ ์คํํด์ผ ํฉ๋๋ค.
USER_ENTERED_INVALID_THING_ID
๊ฐ ์คํ๋ ๋ ์ฌ๋ฌผ ID ํ
์คํธ ํ๋๊ฐ ์ฌ์ค์ ๋๋๋ก ๊ฐ์๊ธฐ๋ฅผ ๋ณ๊ฒฝํ ์๋ ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ ๋ณํ๋ ๋ํ ์๊ฐ์ ํตํด ์ด๋ํฉ๋๋ค. ํ์ด์ง๋ฅผ ์๋ก ๊ณ ์น์ง ์๊ณ ๋ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ํ์งํํ ์๋ ์์ต๋๋ค. ์ด๋ ํผ๋๋ฐฑ ๋ฃจํ๋ฅผ ๊ฐํํ๊ณ ๋๋ฒ๊น
๋ฐ ์กฐ์ ์ ํจ์ฌ ์ฝ๊ฒ ๋ง๋ญ๋๋ค.
(์ฌ๊ธฐ์ ๋๋ ๋จ์ง ์ฅ์ ์ ๋ํด ์ด์ผ๊ธฐํ๊ณ ์์ต๋๋ค. ๋ฌผ๋ก ๋จ์ ๋ ์์ต๋๋ค. ๊ทํ์ ์์ ์ด ์ด๋ฌํ ์ฌ์ค์ ๋๊ธฐ์ ์ผ๋ก ๊ทธ๋ฆฌ๊ณ ๋ถ์์ฉ ์์ด ์๋ตํ ์ ์๋ค๋ ์ ์ ๊ฐ์ํ ๋ ๊ทธ ์ฌ์ค์ ํํํ๋ ๋ฐฉ๋ฒ์ ๋ํด ๋ ๋ง์ด ์๊ฐํด์ผ ํฉ๋๋ค. ์ ๋ํ ํ ๋ก ์ ์ฐธ์กฐํ์ญ์์ค. ์ด ์ง๋ฌธ์ StackOverflow์ ๊ฒ์ํ์ต๋๋ค . ์์ง ๊ทธ ๋ถ๋ถ์ ํ์ ํ์ง ๋ชปํ ๊ฒ ๊ฐ์ต๋๋ค.)
์ฒ์์๋ ์ก์ ์ ๋ฐ์ํ๋ ์์์ ๋ฆฌ๋์์ ๋ํด ์ด๋ป๊ฒ ๋๋ผ๋์ง ์์งํ ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ์ฝ๊ฐ ๋์ ์บก์ํ ๊ฐ์ ๋๋์ด ๋ญ๋๋ค.
์ฌ๋ฌ ๊ตฌ์ฑ ์์๊ฐ ๋์ผํ ์ ์ฅ์์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฒ๋ ๋งค์ฐ ์ผ๋ฐ์ ์ ๋๋ค. ๋ํ ๋จ์ผ ๊ตฌ์ฑ ์์๊ฐ ์ ์ฅ์์ ์ฌ๋ฌ ๋ถ๋ถ์์ ๊ฐ์ ธ์จ ๋ฐ์ดํฐ์ ์์กดํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. ๋๋ฌด ๋์ ์บก์ํ์ฒ๋ผ ๋ค๋ฆฌ์ง ์์ต๋๊น? ์ง์ ํ ๋ชจ๋ํ๊ฐ ๋๋ ค๋ฉด React ์ปดํฌ๋ํธ๋ "duck" ๋ฒ๋ค ์์ ์์ด์ผ ํ์ง ์์๊น์? ( Elm ์ํคํ ์ฒ๊ฐ ์ด๋ฅผ ์ํํฉ๋๋ค .)
React๋ ์คํ ์ด์ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ค๋ก ์ฒ๋ฆฌ
๊ฐ์ ๋ฐฉ์์ผ๋ก Redux/Flux๋ ์ก์ ์ ์ฌ์ค๋ก ์ทจ๊ธ
@dtinth, ์๊ฐ์ ๋ด์ด ๊ธ์ ์์ฑํ๊ณ ์๊ฐ์ ๊ณต์ ํด ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค. ๋ํ ์ด ํ ๋ก ์ ์ฐธ์ฌํด ์ฃผ์
์ฌ๋ฌ ๊ตฌ์ฑ ์์๊ฐ ๋์ผํ ์ ์ฅ์์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฒ๋ ๋งค์ฐ ์ผ๋ฐ์ ์ ๋๋ค. ๋ํ ๋จ์ผ ๊ตฌ์ฑ ์์๊ฐ ์ ์ฅ์์ ์ฌ๋ฌ ๋ถ๋ถ์์ ๊ฐ์ ธ์จ ๋ฐ์ดํฐ์ ์์กดํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. ๋๋ฌด ๋์ ์บก์ํ์ฒ๋ผ ๋ค๋ฆฌ์ง ์์ต๋๊น?
์... ์ฃผ๊ด์ ์ธ ๋ถ๋ถ๋ ์์ง๋ง ์๋๋๋ค. ๋ด๋ณด๋ธ action-creators์ selectors๋ฅผ ๋ชจ๋์ API๋ก ์๊ฐํฉ๋๋ค.
์ด์จ๋ ์ข์ ํ ๋ก ์ด์๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ด์ ๋ต๋ณ์์ ์ธ๊ธํ Thai์ ๋ง์ฐฌ๊ฐ์ง๋ก ์ฐ๋ฆฌ๊ฐ ๋ ผ์ํ๊ณ ์๋ ์ด๋ฌํ ์ ๊ทผ ๋ฐฉ์์๋ ์ฅ๋จ์ ์ด ์์ต๋๋ค. ๋ค๋ฅธ ์ ๊ทผ ๋ฐฉ์์ ๋ํ ํต์ฐฐ๋ ฅ์ ์ป๋ ๊ฒ์ด ์ข์ต๋๋ค. :)
๊ทธ๊ฑด ๊ทธ๋ ๊ณ ๋ฉ์์ง ์์๋ ํ์๋ฅผ ์ํด ๋ณ๋์ ์์
์์ฑ์๊ฐ ์๋ ๊ฒ์ ์ ํธํ๋ ์ข์ ์์
๋๋ค. ์ฃผ๋ก ์์ฑ๋ ์๊ฐ์ ์ ๋ฌํ์ฌ ์๋์ผ๋ก ํด์ ํ ์ ์๋๋ก ํ๊ณ ์ถ๊ธฐ ๋๋ฌธ์(๊ทธ๋ฆฌ๊ณ ์ก์
์์ฑ๊ธฐ๋ impure Date.now()
ํธ์ถํ๋ ๊ณณ์
๋๋ค), ์ด๋ฅผ ํด์ ํ๋ ํ์ด๋จธ๋ฅผ ์ค์ ํ๊ณ ์ถ๊ธฐ ๋๋ฌธ์ ํด๋น ํ์ด๋จธ ๋ฑ์ ๋๋ฐ์ด์คํ๊ณ ์ถ์ต๋๋ค. ๋ฐ๋ผ์ ๋ฉ์์ง ์์์ "์์
ํ๋ฆ"์ด ๊ฐ์ธ์ ์ธ ์์
์ ๋ณด์ฆํ ๋งํผ ์ถฉ๋ถํ ์ค์ํ ๊ฒฝ์ฐ๋ฅผ ๊ณ ๋ คํฉ๋๋ค. ๋ด๊ฐ ์ค๋ช
ํ ๋ด์ฉ์ https://github.com/yelouafi/redux-saga์์ ๋ ์ฐ์ํ๊ฒ ํด๊ฒฐํ ์ ์์ต๋๋ค
์ฒ์์ Discord Reactiflux ์ฑํ ์ ์ด๊ฒ์ ์ผ์ง๋ง ์ฌ๊ธฐ์ ๋ถ์ฌ๋ฃ์ผ๋ผ๋ ์์ฒญ์ ๋ฐ์์ต๋๋ค.
๋๋ ์ต๊ทผ์ ๊ฐ์ ๊ฒ์ ๋ํด ๋ง์ด ์๊ฐํ๊ณ ์๋ค. ์ํ ์ ๋ฐ์ดํธ๊ฐ ์ธ ๋ถ๋ถ์ผ๋ก ๋๋์ด์ ธ ์๋ ๊ฒ ๊ฐ์ต๋๋ค.
- ์์ ์์ฑ์์๊ฒ ์ ๋ฐ์ดํธ๋ฅผ ์คํํ๋ ๋ฐ ํ์ํ ์ต์ํ์ ์ ๋ณด๊ฐ ์ ๋ฌ๋ฉ๋๋ค. ์ฆ, ํ์ฌ ์ํ์์ ๊ณ์ฐํ ์ ์๋ ๊ฒ์ ๊ทธ ์์ ์์ผ๋ฉด ์ ๋ฉ๋๋ค.
- ์ํ๋ ์ ๋ฐ์ดํธ๋ฅผ ์ํํ๋ ๋ฐ ํ์ํ ์ ๋ณด์ ๋ํด ์ฟผ๋ฆฌ๋ฉ๋๋ค(์: id X๋ก Todo๋ฅผ ๋ณต์ฌํ๋ ค๋ ๊ฒฝ์ฐ ๋ณต์ฌํ ์ ์๋๋ก id X๋ก Todo์ ์์ฑ์ ๊ฐ์ ธ์ด). ์ด๊ฒ์ ์์ ์์ฑ์์์ ์ํํ ์ ์์ผ๋ฉฐ ํด๋น ์ ๋ณด๋ ์์ ๊ฐ์ฒด์ ํฌํจ๋ฉ๋๋ค. ๊ฒฐ๊ณผ์ ์ผ๋ก ๋ฑ๋ฑํ ์์ ๊ฐ์ฒด๊ฐ ์์ฑ๋ฉ๋๋ค. ๋๋ ๊ฐ์๊ธฐ - ์์ ์์ ๊ฐ์ฒด์์ ๊ณ์ฐํ ์ ์์ต๋๋ค.
- ํด๋น ์ ๋ณด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์์ ๋ฆฌ๋์ ๋ก์ง์ด ์ ์ฉ๋์ด ๋ค์ ์ํ๋ฅผ ์ป์ต๋๋ค.
์ด์ ๋ฌธ์ ๋ ์ก์ ์์ฑ์์ ๋ฌด์์ ๋ฃ๊ณ ๋ฆฌ๋์์ ๋ฌด์์ ๋ฃ์์ง, ๋ฑ๋ฑํ ์ก์ ๊ฐ์ฒด์ ์์ ์ก์ ๊ฐ์ฒด ์ค ์ ํ์ ๋๋ค. ๋ชจ๋ ๋ก์ง์ ์ก์ ์์ฑ์์ ๋ฃ์ผ๋ฉด ๊ธฐ๋ณธ์ ์ผ๋ก ์ํ ์ ๋ฐ์ดํธ๋ฅผ ์ ์ธํ๋ ๋ฑ๋ฑํ ์ก์ ๊ฐ์ฒด๊ฐ ์๊น๋๋ค. ๋ฆฌ๋์๋ ์์ํ๊ณ , ๋ฉ์ฒญํ๊ณ , ์ถ๊ฐํ๊ณ , ์ ๊ฑฐํ๊ณ , ์ด๋ฌํ ๊ธฐ๋ฅ์ ์ ๋ฐ์ดํธํฉ๋๋ค. ๊ทธ๋ค์ ์๊ณกํ๊ธฐ ์ฌ์ธ ๊ฒ์ ๋๋ค. ๊ทธ๋ฌ๋ ๋น์ฆ๋์ค ๋ก์ง์ ๋๋ถ๋ถ์ ๊ฑฐ๊ธฐ์ ์์ ๊ฒ์ ๋๋ค.
๋ฆฌ๋์์ ๋ ๋ง์ ๋ก์ง์ ๋ฃ์ผ๋ฉด ๋ฉ์ง๊ณ ์์ ์ก์ ๊ฐ์ฒด๊ฐ ์๊ธฐ๊ณ ๋๋ถ๋ถ์ ๋ฐ์ดํฐ ๋ก์ง์ด ํ ๊ณณ์ ์์ง๋ง ๋ค๋ฅธ ๋ธ๋์น์ ์ ๋ณด๊ฐ ํ์ํ ์ ์๊ธฐ ๋๋ฌธ์ ๋ฆฌ๋์๋ ๊ตฌ์ฑํ๊ธฐ๊ฐ ๋ ์ด๋ ต์ต๋๋ค. ์ํ์ ์์์์ ์ถ๊ฐ ์ธ์๋ฅผ ์ทจํ๋ ๋ํ ๊ฐ์๊ธฐ ๋๋ ๊ฐ์๊ธฐ๋ก ๋๋ฉ๋๋ค.
์ด ๋ฌธ์ ์ ๋ํ ๋ต์ด ๋ฌด์์ธ์ง ๋ชจ๋ฅด๋ฉฐ ์์ง ์๋์ง ํ์คํ์ง ์์ต๋๋ค.
์ด๋ฌํ ์๊ฐ์ ๊ณต์ ํด ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค @tommikaikkonen. ๋๋ ์ฌ๊ธฐ์ "๋๋ต"์ด ๋ฌด์์ธ์ง ์์ง ๊ฒฐ์ ํ์ง ๋ชปํ์ต๋๋ค. ๋๋ ๋น์ ์ ์์ฝ์ ๋์ํฉ๋๋ค. "๋ชจ๋ ๋ ผ๋ฆฌ๋ฅผ ์์ ์์ฑ์์ ๋ฃ๊ธฐ..." ์น์ ์ ์์ ๋ฉ๋ชจ ํ๋๋ฅผ ์ถ๊ฐํ๊ฒ ์ต๋๋ค. ์ด ์น์ ์์๋ ์ผ๋ถ ๊ฒฝ์ฐ์ ์ ์ฉํ ์ ์๋ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ธฐ ์ํด (๊ณต์ ) ์ ํ๊ธฐ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ด๊ฒ์ ํฅ๋ฏธ๋ก์ด ์ค๋ ๋์
๋๋ค! redux ์ฑ์์ ์ฝ๋๋ฅผ ๋ฐฐ์นํ ์์น๋ฅผ ํ์
ํ๋ ๊ฒ์ ์ฐ๋ฆฌ ๋ชจ๋๊ฐ ์ง๋ฉดํ ๋ฌธ์ ์ธ ๊ฒ ๊ฐ์ต๋๋ค. ๋๋ ์ผ์ด๋ ์ผ์ ๊ธฐ๋กํ๋ CQRS ์์ด๋์ด๋ฅผ ์ข์ํฉ๋๋ค.
๊ทธ๋ฌ๋ CQRS์์ ์์ด๋์ด์ ๋ถ์ผ์น๋ฅผ ๋ณผ ์ ์์ต๋๋ค. AFAIK ๋ชจ๋ฒ ์ฌ๋ก๋ ๋ณด๊ธฐ์์ ์ง์ ์๋นํ ์ ์๋ ์์
/์ด๋ฒคํธ์์ ๋น์ ๊ทํ๋ ์ํ๋ฅผ ๊ตฌ์ถํ๋ ๊ฒ์
๋๋ค. ๊ทธ๋ฌ๋ redux์์ ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ ์์ ํ ์ ๊ทํ๋ ์ํ๋ฅผ ๊ตฌ์ถํ๊ณ ์ ํ๊ธฐ๋ฅผ ํตํด ๋ทฐ์ ๋ฐ์ดํฐ๋ฅผ ํ์์ํค๋ ๊ฒ์
๋๋ค.
๋ทฐ์์ ์ง์ ์๋นํ ์ ์๋ ๋น์ ๊ทํ ์ํ๋ฅผ ๋น๋ํ๋ฉด ๋ฆฌ๋์๊ฐ ๋ค๋ฅธ ๋ฆฌ๋์์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ค๋ ๋ฌธ์ ๊ฐ ์ฌ๋ผ์ง๋๋ค(๊ฐ ๋ฆฌ๋์๊ฐ ์ ๊ทํ์ ์ ๊ฒฝ ์ฐ์ง ์์๋ ๋๋ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ ์ ์๊ธฐ ๋๋ฌธ). ๊ทธ๋ฌ๋ ๋ฐ์ดํฐ๋ฅผ ์
๋ฐ์ดํธํ ๋ ๋ค๋ฅธ ๋ฌธ์ ๊ฐ ๋ฐ์ํฉ๋๋ค. ์ด๊ฒ์ด ํ ๋ก ์ ํต์ฌ์ด ์๋๊น์?
์๋ ๊ฐ์ ๊ฐ์ฒด ์งํฅ ๊ฐ๋ฐ์์ ๋น๋กฏ๋ ๊ฒ์ ๋๋ค. Redux๋ ํฌ๊ฒ ํํดํ ๊ฒ์ฒ๋ผ ๋๊ปด์ง๋๋ค. ๋๋ ์ด๋ฒคํธ(์ก์ ์์ฑ์)์ ๋น์ฆ๋์ค ๋ก์ง์ ์บก์ํํ๋ ํด๋์ค๋ฅผ ๋ง๋ค์ด๋ฌ๋ผ๊ณ ์ ์ํฉ๋๋ค. ๋๋ ์ฌ์ ํ ์๋ฏธ ์๋ ํํ์ ์ฐพ์ผ๋ ค๊ณ ๋ ธ๋ ฅํ๊ณ ์์ง๋ง ์์ง ๊ทธ๋ ๊ฒ ํ ์ ์์ต๋๋ค. ๋ค๋ฅธ ์ฌ๋๋ ๊ฐ์ ๊ธฐ๋ถ์ด ๋ค๊น์?
๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ์ฝ๊ธฐ์ ์ฐ๊ธฐ๋ฅผ ํจ๊ป ์ฌ์ฉํ๋๋ก ๊ถ์ฅํฉ๋๋ค. ์ด๋ก ์ธํด ์ค๋ ์ท ๋ฐ ๋กค๋ฐฑ, ์ค์ ์ง์ค์ ๋ก๊น , ์๋ชป๋ ์ํ ๋ณํ ๋๋ฒ๊น , ์ธ๋ถํ๋ ํจ์จ์ ์ธ ์ ๋ฐ์ดํธ ๋ฑ ๋ง์ ๋ฌธ์ ๊ฐ ๋ฐ์ํฉ๋๋ค. ๊ทธ๊ฒ์ด ๋น์ ์๊ฒ ๋ฌธ์ ๋ผ๊ณ ์๊ฐํ์ง ์๋๋ค๋ฉด, ์ ํต์ ์ธ ๊ฐ์ฒด ์งํฅ MVC ์ฝ๋๋ฅผ ์์ฑํ๋ฉด์ ๊ทธ๊ฒ๋ค์ ํผํ๋ ๋ฐฉ๋ฒ์ ์๊ณ ์๊ณ , Redux๊ฐ ๋น์ ์ ์ฑ์์ ํด๊ฒฐํ๋ ๊ฒ๋ณด๋ค ๋ ๋ง์ ๋ฌธ์ ๋ฅผ ๋์ ํ๋ค๋ฉด, Redux๋ฅผ ์ฌ์ฉํ์ง ๋ง์ญ์์ค :wink: .
@jayesbe ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ ๋ฐฐ๊ฒฝ์์ https://www.leaseweb.com/labs/2015/08/object-oriented-programming-is-exceptionally-bad/.
๋ฐ์ดํฐ ๋ณํ์์ ์์ ์ ๋ถ๋ฆฌํ๋ฉด ๋น์ฆ๋์ค ๊ท์น์ ์ ์ฉ ํ ์คํธ๊ฐ ๋ ๊ฐ๋จํด์ง๋๋ค. ๋ณํ์ ์ ํ๋ฆฌ์ผ์ด์ ์ปจํ ์คํธ์ ๋ ์์กดํฉ๋๋ค.
๊ทธ๋ ๋ค๊ณ ์๋ฐ์คํฌ๋ฆฝํธ์์ ๊ฐ์ฒด๋ ํด๋์ค๋ฅผ ํฌ๊ธฐํ๋ ๊ฒ์ ์๋๋๋ค. ์๋ฅผ ๋ค์ด React ๊ตฌ์ฑ ์์๋ ๊ฐ์ฒด๋ก ๊ตฌํ๋๊ณ ์ด์ ๋ ํด๋์ค๋ก ๊ตฌํ๋ฉ๋๋ค. ๊ทธ๋ฌ๋ React ๊ตฌ์ฑ ์์๋ ๋จ์ํ ์ ๊ณต๋ ๋ฐ์ดํฐ์ ํฌ์์ ์์ฑํ๋๋ก ์ค๊ณ๋์์ต๋๋ค. ์ํ๋ฅผ ์ ์ฅํ์ง ์๋ ์์ ๊ตฌ์ฑ ์์๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
์ด๊ฒ์ด Redux๊ฐ ๋ฑ์ฅํ๋ ๊ณณ์ ๋๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์ํ๋ฅผ ๊ตฌ์ฑํ๊ณ ์์ ๊ณผ ์ ํ๋ฆฌ์ผ์ด์ ์ํ์ ํด๋น ๋ณํ์ ํจ๊ป ๊ฐ์ ธ์ต๋๋ค.
@johnsoftek ๋งํฌ ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค. ๊ทธ๋ฌ๋ ์ง๋ 10๋ ๋์์ ๋ด ๊ฒฝํ์ ๋ฐ๋ฅด๋ฉด. ๋๋ ๊ทธ๊ฒ์ ๋์ํ์ง ์์ง๋ง ์ฐ๋ฆฌ๋ ์ฌ๊ธฐ์ OO์ non-OO ์ฌ์ด์ ๋ ผ์์ ๋ค์ด๊ฐ ํ์๊ฐ ์์ต๋๋ค. ๋ด๊ฐ ๊ฐ์ง ๋ฌธ์ ๋ ์ฝ๋์ ์ถ์ํ๋ฅผ ๊ตฌ์ฑํ๋ ๊ฒ์ ๋๋ค.
๋ด ๋ชฉํ๋ ๊ตฌ์ฑ ๊ฐ๋ง ์ฌ์ฉํ์ฌ 100๊ฐ์ ์ฑ์ ๋ง๋๋ ๋ฐ ์ฌ์ฉํ ์ ์๋ ๋จ์ผ ์ฑ/๋จ์ผ ์ํคํ ์ฒ๋ฅผ ๋ง๋๋ ๊ฒ์ ๋๋ค. ๋ด๊ฐ ์ฒ๋ฆฌํด์ผ ํ๋ ์ฌ์ฉ ์ฌ๋ก๋ ๋ง์ ํด๋ผ์ด์ธํธ๊ฐ ์ฌ์ฉํ๋ ํ์ดํธ ๋ ์ด๋ธ ์ํํธ์จ์ด ์๋ฃจ์ ์ ์ฒ๋ฆฌํ๋ ๊ฒ์ ๋๋ค. ๊ฐ๊ฐ์ ์์ฉ ํ๋ก๊ทธ๋จ์ ์์ฒด์ ์ผ๋ก ํธ์ถํฉ๋๋ค.
๋๋ ํฅ๋ฏธ๋ก์ด ์ ์ถฉ์์ด๋ผ๊ณ ์๊ฐํ๋ ๊ฒ์ ์๊ฐํด ๋์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ถฉ๋ถํ ์ ์ฒ๋ฆฌํ๋ค๊ณ ์๊ฐํ์ง๋ง ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ๊ตฐ์ค ํ์ค์ ์ถฉ์กฑํ์ง ๋ชปํ ์๋ ์์ต๋๋ค. ๋๋ ์ฌ์ ํ ๊ทธ๊ฒ์ ๊ฑฐ๊ธฐ์ ๋ฃ๊ณ ์ถ์ต๋๋ค.
๋ด ์๋ฒ ์ธก ์์ฉ ํ๋ก๊ทธ๋จ๊ณผ ์ธํฐํ์ด์คํ๋ ๋ฐ ํ์ํ ๋ชจ๋ ๋น์ฆ๋์ค ๋ ผ๋ฆฌ, API ๋ํผ ๋ฑ์ด ํฌํจ๋ ๋จ์ผ ์์ฉ ํ๋ก๊ทธ๋จ ํด๋์ค๊ฐ ์์ต๋๋ค.
์์..
export default Application {
constructor(config) {
this.config = config;
}
config() {
return this.config;
}
login(data, cb) {
const url = [
this.config.url,
'?client=' + this.config.client,
'&username=' + data.username,
....
].join('');
fetch(url).then((responseText) => {
cb(responseText);
})
}
... more business logic
}
์ด ๊ฐ์ฒด์ ๋จ์ผ ์ธ์คํด์ค๋ฅผ ๋ง๋ค๊ณ ์ปจํ ์คํธ์ ๋ฐฐ์นํ์ต๋๋ค. Redux ๊ณต๊ธ์๋ฅผ ํ์ฅํ์ฌ
import { Provider } from 'react-redux';
export default class MyProvider extends Provider {
getChildContext() {
return Object.assign({}, Provider.prototype.getChildContext.call(this), {
app: this.props.app
});
}
render() {
return this.props.children;
}
}
MyProvider.childContextTypes = {
store: React.PropTypes.object,
app: React.PropTypes.object
}
๊ทธ๋ฐ ๋ค์์ด ๊ณต๊ธ์๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ์ต๋๋ค.
import Application from './application';
import config from './config';
class MyApp extends Component {
render() {
return (
<MyProvider store={store} app={new Application(config)}>
<Router />
</MyProvider>
);
}
}
AppRegistry.registerComponent('MyApp', () => MyApp);
๋ง์นจ๋ด ๋ด ๊ตฌ์ฑ ์์์์ ๋ด ์ฑ์ ์ฌ์ฉํ์ต๋๋ค.
class Login extends React.Component {
render() {
const { app } = this.context;
const { state, actions } = this.props;
return (
<View style={style.transparentContainer}>
<Form ref="form" type={User} options={options} />
<Button
onPress={() => {
value = this.refs.form.getValue();
if (value) {
app.login(value, actions.login);
}
}}
>
Login
</Button>
</View>
);
}
};
Login.contextTypes = {
app: React.PropTypes.object,
};
function mapStateToProps(state) {
return {
state: state.default.auth
};
};
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(authActions, dispatch),
dispatch
};
}
export default connect(mapStateToProps, mapDispatchToProps)(Login);
๋ฐ๋ผ์ Action Creator๋ ๋ด ๋น์ฆ๋์ค ๋ก์ง์ ๋ํ ์ฝ๋ฐฑ ํจ์์ผ ๋ฟ์ ๋๋ค.
app.login(value, actions.login);
์ด ์๋ฃจ์ ์ ์ธ์ฆ์ผ๋ก๋ง ์์ํ์ง๋ง ํ์ฌ ์ ์๋ํ๋ ๊ฒ ๊ฐ์ต๋๋ค.
์คํ ์ด๋ฅผ ๋ด Application ์ธ์คํด์ค์ ์ ๋ฌํ ์๋ ์๋ค๊ณ ์๊ฐํ์ง๋ง ์คํ ์ด๊ฐ ์ฐ์ฐํ ๋์ฐ๋ณ์ด๋ฅผ ๊ฒช๋ ๊ฒ์ ์ํ์ง ์๊ธฐ ๋๋ฌธ์ ๊ทธ๋ ๊ฒ ํ๊ณ ์ถ์ง ์์ต๋๋ค. ์์ ์ ์ก์ธ์คํ๋ ๊ฒ์ด ํธ๋ฆฌํ ์ ์์ต๋๋ค. ํ์ํ๋ฉด ๋ ์๊ฐํ๊ฒ ์ต๋๋ค.
๋๋ ํฅ๋ฏธ๋ก์ด ์ ์ถฉ์์ด๋ผ๊ณ ์๊ฐํ๋ ๊ฒ์ ์๊ฐํด ๋์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ถฉ๋ถํ ์ ์ฒ๋ฆฌํ๋ค๊ณ ์๊ฐํ์ง๋ง ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ๊ตฐ์ค ํ์ค์ ์ถฉ์กฑํ์ง ๋ชปํ ์๋ ์์ต๋๋ค.
์ฌ๊ธฐ์์ "๊ธฐ๋ฅ์ ์ธ ๊ตฐ์ค"์ ์ฐพ์ ์ ์์ต๋๋ค :wink: . Redux์์ ๊ธฐ๋ฅ์ ์๋ฃจ์
์ ์ ํํ๋ ์ด์ ๋ ์ฐ๋ฆฌ๊ฐ ๋
๋จ์ ์ด๊ธฐ ๋๋ฌธ์ด ์๋๋ผ ์ฌ๋๋ค์ด ์์
๋๋ฌธ์ ์ข
์ข
๋ง๋๋ ๋ช ๊ฐ์ง ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ๋๋ฌธ์
๋๋ค. ์๋ฅผ ๋ค์ด ๋ฆฌ๋์๋ฅผ ์ก์
์์ฑ์์ ๋ถ๋ฆฌํ๋ฉด ๋ฒ๊ทธ๋ฅผ ๊ธฐ๋กํ๊ณ ์ฌ์ํ๋ ๋ฐ ์ค์ํ ์ฝ๊ธฐ์ ์ฐ๊ธฐ๋ฅผ ๋ถ๋ฆฌํ ์ ์์ต๋๋ค. ์ผ๋ฐ ๊ฐ์ฒด์ธ ์์
์ ์ง๋ ฌํ ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ ๊ธฐ๋ก ๋ฐ ์ฌ์์ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค. ๋ง์ฐฌ๊ฐ์ง๋ก ์ํ๊ฐ MyAppState
์ ์ธ์คํด์ค๊ฐ ์๋ ์ผ๋ฐ ๊ฐ์ฒด์ด๋ฏ๋ก ์๋ฒ์์ ์ง๋ ฌํํ๊ณ ์๋ฒ ๋ ๋๋ง์ ์ํด ํด๋ผ์ด์ธํธ์์ ์ญ์ง๋ ฌํํ๊ฑฐ๋ localStorage
์ ์ผ๋ถ๋ฅผ ์ ์งํ๋ ๊ฒ์ด ๋งค์ฐ ์ฝ์ต๋๋ค. ๋ฆฌ๋์๋ฅผ ํจ์๋ก ํํํ๋ฉด ์๊ฐ ์ฌํ๊ณผ ํซ ๋ฆฌ๋ก๋ฉ์ ๊ตฌํํ ์ ์๊ณ , ์
๋ ํฐ๋ฅผ ํจ์๋ก ํํํ๋ฉด ๋ฉ๋ชจ์ด์ ์ด์
์ ์ฝ๊ฒ ์ถ๊ฐํ ์ ์์ต๋๋ค. ์ด๋ฌํ ๋ชจ๋ ์ด์ ์ ์ฐ๋ฆฌ๊ฐ "๊ธฐ๋ฅ์ ๊ตฐ์ค"์ด ๋๋ ๊ฒ๊ณผ ์๋ฌด ๊ด๋ จ์ด ์์ผ๋ฉฐ ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ํด๊ฒฐํ๊ธฐ ์ํด ์์ฑ๋ ํน์ ์์
์ ํด๊ฒฐํ๋ ๊ฒ๊ณผ ๊ด๋ จ์ด ์์ต๋๋ค.
์ด ๊ฐ์ฒด์ ๋จ์ผ ์ธ์คํด์ค๋ฅผ ๋ง๋ค๊ณ ์ปจํ ์คํธ์ ๋ฐฐ์นํ์ต๋๋ค. Redux ๊ณต๊ธ์๋ฅผ ํ์ฅํ์ฌ
์ด๊ฒ์ ๋์๊ฒ ์์ ํ ํฉ๋ฆฌ์ ์ผ๋ก ๋ณด์ ๋๋ค. ์ฐ๋ฆฌ๋ ์์ ์ ๋นํฉ๋ฆฌ์ ์ผ๋ก ์ซ์ดํ์ง ์์ต๋๋ค. ์์ ์ ๊ทธ๊ฒ๋ค์ด ์ฌ๊ฐํ๊ฒ ์ ํ๋๋ ๊ฒฝ์ฐ(์: ๊ฐ์๊ธฐ ๋๋ ์์ ๊ฐ์ฒด์ ๊ฒฝ์ฐ)์๋ ์ฌ์ฉํ์ง ์๋ ๊ฒ์ด ์ข์ง๋ง ์๋ฅผ ๋ค์ด ์์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๋ฐ ์ฌ์ฉํ๋ ๊ฒ์ ๊ด์ฐฎ์ต๋๋ค.
๊ทธ๋ฌ๋ Provider
๋ฅผ ํ์ฅํ๋ ๊ฒ์ ๊นจ์ง๊ธฐ ์ฌ์ฐ๋ฏ๋ก ํผํฉ๋๋ค. ๊ทธ๋ด ํ์๊ฐ ์์ต๋๋ค. React๋ ๊ตฌ์ฑ ์์์ ์ปจํ
์คํธ๋ฅผ ๋ณํฉํ๋ฏ๋ก ๋์ ๊ฐ์ธ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค.
import { Component } from 'react';
import { Provider } from 'react-redux';
export default class MyProvider extends Component {
getChildContext() {
return {
app: this.props.app
};
}
render() {
return (
<Provider store={this.props.store}>
{this.props.children}
</Provider>
);
}
}
MyProvider.childContextTypes = {
app: React.PropTypes.object
}
MyProvider.propTypes = {
app: React.PropTypes.object,
store: React.PropTypes.object
}
์ค์ ๋ก ๋ด ๋ณด๊ธฐ์๋ ๋ ์ฝ๊ธฐ ์ฝ๊ณ ๋ ๊นจ์ง๊ธฐ ์ฝ์ต๋๋ค.
๋ฐ๋ผ์ ์ ๋ฐ์ ์ผ๋ก ๊ทํ์ ์ ๊ทผ ๋ฐฉ์์ ์์ ํ ์๋ฏธ๊ฐ ์์ต๋๋ค. ์ด ๊ฒฝ์ฐ ํด๋์ค๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ createActions(config)
์ ๊ฐ์ ๊ฒ๊ณผ ํฌ๊ฒ ๋ค๋ฅด์ง ์์ต๋๋ค. ์ด๋ ์ก์
์์ฑ์๋ฅผ ๋งค๊ฐ๋ณ์ํํด์ผ ํ๋ ๊ฒฝ์ฐ์๋ ๊ถ์ฅํ๋ ํจํด์
๋๋ค. ์ ํ ๋ฌธ์ ๊ฐ ์์ต๋๋ค.
ํด๋์ค ์ธ์คํด์ค๋ ์ง๋ ฌํ๋ฅผ ๋งค์ฐ ๊น๋ค๋กญ๊ฒ ๋ง๋ค๊ธฐ ๋๋ฌธ์ ์ํ ๋ฐ ์์ ๊ฐ์ฒด์ ๋ํด ํด๋์ค ์ธ์คํด์ค๋ฅผ ์ฌ์ฉํ์ง ์๋ ๊ฒ์ด ์ข์ต๋๋ค. ๊ฐ์๊ธฐ์ ๊ฒฝ์ฐ ๋ค๋ฅธ ๊ฐ์๊ธฐ๋ฅผ ํธ์ถํ๋ ๊ฐ์๊ธฐ ๊ตฌ์ฑ, ์ฆ ๊ฐ์๊ธฐ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ ์ด๋ ต๊ธฐ ๋๋ฌธ์ ํด๋์ค ์ฌ์ฉ๋ ๊ถ์ฅํ์ง ์์ต๋๋ค. ๋ค๋ฅธ ๋ชจ๋ ๊ฒ์๋ ํด๋์ค๋ฅผ ํฌํจํ ๋ชจ๋ ์ฝ๋ ๊ตฌ์ฑ ์๋จ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ ํ๋ฆฌ์ผ์ด์ ๊ณผ ๊ตฌ์ฑ์ด ๋ณ๊ฒฝ ๋ถ๊ฐ๋ฅํ ๊ฒฝ์ฐ(๊ทธ๋ฆฌ๊ณ ๊ทธ๋์ผ ํ๋ค๊ณ ์๊ฐํ์ง๋ง ์๋ง๋ ๊ธฐ๋ฅ์ ์ธ ์ฟจ ์์ด๋๋ฅผ ๋๋ฌด ๋ง์ด ๋ง์ ๊ฒ ๊ฐ์ต๋๋ค) ๋ค์ ์ ๊ทผ ๋ฐฉ์์ ๊ณ ๋ คํ ์ ์์ต๋๋ค.
const appSelector = createSelector(
(state) => state.config,
(config) => new Application(config)
)
๊ทธ๋ฐ ๋ค์ mapStateToProps์์:
function mapStateToProps(state) {
return {
app: appSelector(state)
};
};
๊ทธ๋ฐ ๋ค์ ์ฑํํ ๊ณต๊ธ์ ๊ธฐ์ ์ด ํ์ํ์ง ์์ผ๋ฉฐ ์ํ์์ ์์ฉ ํ๋ก๊ทธ๋จ ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์ค๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค. reselect ๋๋ถ์ Application ๊ฐ์ฒด๋ ๊ตฌ์ฑ์ด ๋ณ๊ฒฝ๋ ๋๋ง ๊ตฌ์ฑ๋๋ฉฐ, ์ด๋ ์๋ง๋ ํ ๋ฒ์ผ ๊ฒ์ ๋๋ค.
์ด ์ ๊ทผ ๋ฐฉ์์ด ์ฅ์ ์ด ์์ ์ ์๋ค๊ณ ์๊ฐํ๋ ๊ฒฝ์ฐ ์ด๋ฌํ ๊ฐ์ฒด๊ฐ ์ฌ๋ฌ ๊ฐ ์๊ณ ํด๋น ๊ฐ์ฒด๊ฐ ์ํ์ ๋ค๋ฅธ ๋ถ๋ถ์ ์ข ์๋๋๋ก ํ๋ ์์ด๋์ด๋ฅผ ์ฝ๊ฒ ํ์ฅํ ์ ์๋ค๋ ์ ์ ๋๋ค. ์๋ฅผ ๋ค์ด ๊ตฌ์ฑ๊ณผ ์ํ์ ์ผ๋ถ์ ๋ชจ๋ ์ก์ธ์คํ ์ ์๋ ๋ก๊ทธ์ธ/๋ก๊ทธ์์/etc ๋ฉ์๋๊ฐ ์๋ UserControl ํด๋์ค๊ฐ ์์ ์ ์์ต๋๋ค.
๋ฐ๋ผ์ ์ ๋ฐ์ ์ผ๋ก ๊ทํ์ ์ ๊ทผ ๋ฐฉ์์ ์์ ํ ์๋ฏธ๊ฐ ์์ต๋๋ค.
:+1: ๋์์ด ๋์์ต๋๋ค. ๊ฐ์ฌํฉ๋๋ค. MyProvider์ ๊ฐ์ ์ฌํญ์ ๋์ํฉ๋๋ค. ๋ฐ๋ฅด๋๋ก ์ฝ๋๋ฅผ ์ ๋ฐ์ดํธํ๊ฒ ์ต๋๋ค. Redux๋ฅผ ์ฒ์ ๋ฐฐ์ธ ๋ ๊ฒช์๋ ๊ฐ์ฅ ํฐ ๋ฌธ์ ์ค ํ๋๋ "Action Creators"์ ์๋ฏธ๋ก ์ ๊ฐ๋ ์ด์์ต๋๋ค. ์ด๋ฒคํธ์ ๋์ผ์ํ ๋๊น์ง๋ ์๋ฏธ๊ฐ ์์์ต๋๋ค. ๋์๊ฒ ๊ทธ๊ฒ์ .. ์ด๊ฒ๋ค์ด ํ๊ฒฌ๋๋ ์ด๋ฒคํธ์ ๊ฐ์ ์ผ์ข ์ ๊นจ๋ฌ์์ด์์ต๋๋ค.
@winstonewert ๋ react-native์์ createSelector๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๊น? ๋๋ ๊ทธ๊ฒ์ ๋ฏฟ์ง ์๋๋ค. ๋์์ ์ผ๋ถ ๊ตฌ์ฑ ์์์ mapStateToProps์ ์ฐ๊ฒฐํ ๋๋ง๋ค ์ ์์ฉ ํ๋ก๊ทธ๋จ์ ๋ง๋๋ ๊ฒ์ฒ๋ผ ๋ณด์ ๋๋ค. ๋ด ๋ชฉํ๋ ์์ฉ ํ๋ก๊ทธ๋จ์ ๋ํ ๋ชจ๋ ๋น์ฆ๋์ค ๋ ผ๋ฆฌ๋ฅผ ์ ๊ณตํ๊ณ ํด๋น ๊ฐ์ฒด๊ฐ ์ ์ญ์ ์ผ๋ก ์ก์ธ์คํ ์ ์๋๋ก ํ๋ ๋จ์ผ ๊ฐ์ฒด๋ฅผ ์ธ์คํด์คํํ๋ ๊ฒ์ ๋๋ค. ์ ์์ด ํจ๊ณผ๊ฐ ์๋์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ํ์ํ ๊ฒฝ์ฐ ์ถ๊ฐ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ ์ ์๋ค๋ ์์ด๋์ด๊ฐ ์ข์ง๋ง.. ๊ธฐ์ ์ ์ผ๋ก Application ์ธ์คํด์ค๋ฅผ ํตํด ํ์์ ๋ฐ๋ผ ์ธ์คํด์คํํ ์๋ ์์ต๋๋ค.
Redux๋ฅผ ์ฒ์ ๋ฐฐ์ธ ๋ ๊ฒช์๋ ๊ฐ์ฅ ํฐ ๋ฌธ์ ์ค ํ๋๋ "Action Creators"์ ์๋ฏธ๋ก ์ ๊ฐ๋ ์ด์์ต๋๋ค. ์ด๋ฒคํธ์ ๋์ผ์ํ ๋๊น์ง๋ ์๋ฏธ๊ฐ ์์์ต๋๋ค. ๋์๊ฒ ๊ทธ๊ฒ์ .. ์ด๊ฒ๋ค์ด ํ๊ฒฌ๋๋ ์ด๋ฒคํธ์ ๊ฐ์ ์ผ์ข ์ ๊นจ๋ฌ์์ด์์ต๋๋ค.
Redux์๋ Action Creators์ ์๋ฏธ๋ก ์ ๊ฐ๋ ์ด ์ ํ ์๋ค๊ณ ๋งํ๊ณ ์ถ์ต๋๋ค. Actions์ ์๋ฏธ๋ก ์ ๊ฐ๋ ์ด ์์ต๋๋ค(์ผ์ด๋ ์ผ์ ์ค๋ช ํ๊ณ ์ด๋ฒคํธ์ ๋๋ต ๋์ผํ์ง๋ง ์์ ํ ๊ฐ์ง๋ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด #351์ ํ ๋ก ์ฐธ์กฐ). ์ก์ ์์ฑ์๋ ์ฝ๋๋ฅผ ๊ตฌ์ฑํ๊ธฐ ์ํ ํจํด์ผ ๋ฟ์ ๋๋ค. ๊ฐ์ ์ ํ์ ์์ ์ด ์ผ๊ด๋ ๊ตฌ์กฐ๋ฅผ ๊ฐ๊ณ ์ ๋ฌ๋๊ธฐ ์ ์ ๋์ผํ ๋ถ์์ฉ์ด ์๋์ง ๋ฑ์ ํ์ธํ๊ณ ์ถ๊ธฐ ๋๋ฌธ์ ์์ ์ ์ํ ํฉํ ๋ฆฌ๋ฅผ ๊ฐ๋ ๊ฒ์ด ํธ๋ฆฌํฉ๋๋ค. ๊ทธ๋ฌ๋ Redux์ ๊ด์ ์์ ๋ณผ ๋ ์์ ์์ฑ์๋ ์กด์ฌํ์ง ์์ต๋๋ค. Redux ํ๋๋ง ๋ณด์ ๋๋ค.
react-native์์ createSelector๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๊น?
์ข ์์ฑ์ด ์๋ ์ผ๋ฐ JavaScript์ด๋ฉฐ ์น, ๊ธฐ๋ณธ, ์๋ฒ ๋ฑ์์ ์๋ํ ์ ์๋ Reselect ์์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์. ์์์ด. ์ํฉ์ด ํจ์ฌ ๋ ๋ช ํํด์ก์ต๋๋ค. ๊ฑด๋ฐฐ.
์ต๊ทผ Redux๊ฐ mapStateToProps์ mapDispatchToProps๋ฅผ ๋ณํฉํ ๋ ์ค์ฒฉ๋ ๊ฐ์ฒด๊ฐ ์์ค๋๋ ๋ฌธ์ ์ ๋ถ๋ช์ณค์ต๋๋ค(reactjs/react-redux#324 ์ฐธ์กฐ). @gaearon ์ ์ค์ฒฉ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ ์ ์๋ ์๋ฃจ์ ์ ์ ๊ณตํ์ง๋ง
์ด์ ๊ฐ์ด ๊ฐ์ฒด๋ฅผ ๊ทธ๋ฃนํํ๋ฉด ๋ถํ์ํ ํ ๋น์ด ๋ฐ์ํ๊ณ ์ฑ๋ฅ ์ต์ ํ๊ฐ ๋ ์ด๋ ค์์ง๋๋ค. ๊ฒฐ๊ณผ props๊ฐ ๋ณ๊ฒฝ๋์๋์ง ์ฌ๋ถ๋ฅผ ์๋ ค์ฃผ๋ ๋ฐฉ๋ฒ์ผ๋ก ๋ ์ด์ ๊ฒฐ๊ณผ props์ ์์ ๋๋ฑ์ฑ์ ์์กดํ ์ ์๊ธฐ ๋๋ฌธ์ ๋๋ค. ๋ฐ๋ผ์ ๋ฌธ์์์ ๊ถ์ฅํ๋ ๋ค์์คํ์ด์ค๊ฐ ์๋ ๋จ์ํ ์ ๊ทผ ๋ฐฉ์๋ณด๋ค ๋ ๋ง์ ๋ ๋๋ง์ ๋ณผ ์ ์์ต๋๋ค.
@bvaughn์ด ๋งํ๋ค
๊ฐ์๊ธฐ๋ ์ด๋ฆฌ ์๊ณ ๋จ์ํด์ผํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ ์ฐ๋ฆฌ๋ ๋๋ถ๋ถ์ ๋น์ฆ๋์ค ๋ก์ง์ ์ก์ ์์ฑ์์๊ฒ ๋ฃ์ด์ผ ํฉ๋๋ค. ์ ๋ ๊ทธ๊ฒ์ ์ ์ ์ผ๋ก ๋์ํฉ๋๋ค. ๊ทธ๋ฌ๋ ๋ชจ๋ ๊ฒ์ด ์คํ์ผ๋ก ์ฎ๊ฒจ์ก๋ค๋ฉด ์ ์ฌ์ ํ ์๋์ผ๋ก ๊ฐ์๊ธฐ ํ์ผ๊ณผ ๊ธฐ๋ฅ์ ๋ง๋ค์ด์ผ ํฉ๋๊น? ์ก์ ์์ ์กฐ์๋ ๋ฐ์ดํฐ๋ฅผ ์ง์ ์ ์ฅํ์ง ์๊ฒ ์ต๋๊น?
ํ๋์ ์ ๋ฅผ ํผ๋์ค๋ฝ๊ฒ ๋ง๋ค์์ต๋๋ค...
์ ์ฌ์ ํ ๊ฐ์๊ธฐ ํ์ผ๊ณผ ๊ธฐ๋ฅ์ ์๋์ผ๋ก ๋ง๋ค์ด์ผ ํฉ๋๊น?
๋ฆฌ๋์๋ ์์ ํจ์์ด๊ธฐ ๋๋ฌธ์ ์ํ ์ ๋ฐ์ดํธ ๋ก์ง์ ์ค๋ฅ๊ฐ ์๋ ๊ฒฝ์ฐ ๋ฆฌ๋์๋ฅผ ํซ ๋ฆฌ๋ก๋ํ ์ ์์ต๋๋ค. ๊ทธ๋ฐ ๋ค์ ๊ฐ๋ฐ ๋๊ตฌ๋ ์ฑ์ ์ด๊ธฐ ์ํ๋ก ๋๊ฐ๊ณ ์ ๊ฐ์๊ธฐ๋ฅผ ์ฌ์ฉํ์ฌ ๋ชจ๋ ์์ ์ ์ฌ์ํ ์ ์์ต๋๋ค. ์ฆ, ์๋์ผ๋ก ๋กค๋ฐฑํ๊ณ ์์ ์ ๋ค์ ์ํํ์ง ์๊ณ ๋ ์ํ ์ ๋ฐ์ดํธ ๋ฒ๊ทธ๋ฅผ ์์ ํ ์ ์์ต๋๋ค. ์ด๊ฒ์ ๋ฆฌ๋์์ ์ํ ์ ๋ฐ์ดํธ ๋ก์ง์ ๋๋ถ๋ถ์ ์ ์งํ๋ ์ด์ ์ ๋๋ค.
์ด๊ฒ์ ๋ฆฌ๋์์ ์ํ ์ ๋ฐ์ดํธ ๋ก์ง์ ๋๋ถ๋ถ์ ์ ์งํ๋ ์ด์ ์ ๋๋ค.
@dtinth "์ํ ์ ๋ฐ์ดํธ ๋ ผ๋ฆฌ"๋ผ๊ณ ๋งํ๋ฉด "๋น์ฆ๋์ค ๋ ผ๋ฆฌ"๋ฅผ ์๋ฏธํฉ๋๊น?
๋๋ ๋๋ถ๋ถ์ ๋
ผ๋ฆฌ๋ฅผ ์ก์
์์ฑ์์๊ฒ ์ ์ฉํ๋ ๊ฒ์ด ์ข์ ์๊ฐ์ธ์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ๋ชจ๋ ๋ฆฌ๋์๊ฐ ADD_X
์ ๊ฐ์ ์์
์ ํ์ฉํ๋ ์ฌ์ํ ๊ธฐ๋ฅ์ด๋ผ๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํ ๊ฐ๋ฅ์ฑ์ด ์์ต๋๋ค. ์ข์ต๋๋ค! ๊ทธ๋ฌ๋ ๋ชจ๋ ์ค๋ฅ๊ฐ ์์
์์ฑ์์๊ฒ ํธ์๋๊ณ @dtinth๊ฐ ์์ํ๋ ํ๋ฅญํ ๋๋ฒ๊น
๊ฒฝํ์
๊ทธ๋ฌ๋ @tommikaikkonen์ด ์ธ๊ธํ๋ฏ์ด ๋ณต์กํ ๋ฆฌ๋์๋ฅผ ์์ฑํ๋ ๊ฒ์ ๊ทธ๋ฆฌ ๊ฐ๋จํ์ง ์์ต๋๋ค. ๋ด ์ง๊ฐ์ ๋ฐ๋ฅด๋ฉด Redux์ ์ด์ ์ ์ป๊ณ ์ถ๋ค๋ฉด ํธ์ํ๊ณ ์ถ์ ๊ฒ์ ๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ๋ถ์์ฉ์ ๊ฐ์ฅ์๋ฆฌ๋ก ๋ฐ์ด ๋ฃ๋ ๋์ ๊ฐ์ฅ ์ฌ์ํ ์์ ๋ง ์ฒ๋ฆฌํ๋๋ก ์์ํ ๊ธฐ๋ฅ์ ๋ฐ์ด๋ถ์ด๊ณ ๋๋ถ๋ถ์ ๊ตญ๊ฐ๊ฐ ๋ชฐ๊ณ ์๋ ์ง์ฅ์์ ์ฑ์ :)
@sompylasar "๋น์ฆ๋์ค ๋ก์ง"๊ณผ "์ํ ์ ๋ฐ์ดํธ ๋ก์ง"์ ๊ฐ์ ๊ฒ์ ๋๋ค.
๊ทธ๋ฌ๋ ๋ด ์์ ์ ๊ตฌํ ์ธ๋ถ ์ฌํญ์ผ๋ก ์ฐจ์ํ๊ธฐ ์ํด .. ๋ด ์์ ์ ์ฃผ๋ก ์์ ์ ๋ํ ์ ๋ ฅ์ ๋ํ ์กฐํ์ ๋๋ค. ์ค์ ๋ก ๋ชจ๋ "๋น์ฆ๋์ค ๋ ผ๋ฆฌ"๋ฅผ ์์ฉ ํ๋ก๊ทธ๋จ ์ปจํ ์คํธ๋ก ์ด๋ํ๊ธฐ ๋๋ฌธ์ ๋ชจ๋ ์์ ์ ์์ํฉ๋๋ค.
์๋ฅผ ๋ค์ด .. ์ด๊ฒ์ ๋ด ์ผ๋ฐ์ ์ธ ๊ฐ์๊ธฐ
export default function reducer(state = initialState, action = {}) {
switch (action.type) {
case 'FOO_REQUEST':
case 'FOO_RESPONSE':
case 'FOO_ERROR':
case 'FOO_RESET':
return {
...state,
...action.data
};
default:
return state;
}
}
๋์ ์ ํ์ ์ธ ํ๋:
export function fooRequest( res ) {
return {
type: 'FOO_REQUEST',
data: {
isFooing: true,
toFoo: res.saidToFoo
}
};
}
export function fooResponse( res ) {
return {
type: 'FOO_RESPONSE',
data: {
isFooing: false,
isFooed: true,
fooData: res.data
}
};
}
export function fooError( res ) {
return {
type: 'FOO_ERROR',
data: {
isFooing: false,
fooData: null,
isFooed: false,
fooError: res.error
}
};
}
export function fooReset( res ) {
return {
type: 'FOO_RESET',
data: {
isFooing: false,
fooData: null,
isFooed: false,
fooError: null,
toFoo: true
}
};
}
๋ด ๋น์ฆ๋์ค ๋ก์ง์ ์ปจํ ์คํธ์ ์ ์ฅ๋ ๊ฐ์ฒด์ ์ ์๋์ด ์์ต๋๋ค.
export default class FooBar
{
constructor(store)
{
this.actions = bindActionCreators({
...fooActions
}, store.dispatch);
}
async getFooData()
{
this.actions.fooRequest({
saidToFoo: true
});
fetch(url)
.then((response) => {
this.actions.fooResponse(response);
})
}
}
์์ ๋ด ์๊ฒฌ์ ๋ณด๋ฉด ๋๋ ์ต์ ์ ์ ๊ทผ ๋ฐฉ์์ผ๋ก ๊ณ ์ฌํ๊ณ ์์์ต๋๋ค. ๊ฒฐ๊ตญ ๋ฆฌํฉํ ๋งํ๊ณ ์ ์ฅ์๋ฅผ ๋ด ์์ฉ ํ๋ก๊ทธ๋จ ๊ฐ์ฒด์ ์์ฑ์์ ์ ๋ฌํ๊ณ ์ด ์ค์ฌ์ ์์ ๋ชจ๋ ์์ ์ ๋์คํจ์ฒ์ ์ฐ๊ฒฐํ๋ ๊ฒ์ผ๋ก ํด๊ฒฐํ์ต๋๋ค. ๋ด ์ ํ๋ฆฌ์ผ์ด์ ์ด ์๊ณ ์๋ ๋ชจ๋ ์์ ์ด ์ฌ๊ธฐ์ ํ ๋น๋ฉ๋๋ค.
๋๋ ๋ ์ด์ ์ด๋์์๋ mapDispatchToProps()๋ฅผ ์ฌ์ฉํ์ง ์์ต๋๋ค. Redux์ ๊ฒฝ์ฐ ์ด์ ์ฐ๊ฒฐ๋ ๊ตฌ์ฑ ์์๋ฅผ ์์ฑํ ๋ mapStateToProps๋ง ์ฌ์ฉํฉ๋๋ค. ์์ ์ ํธ๋ฆฌ๊ฑฐํด์ผ ํ๋ ๊ฒฝ์ฐ .. ์ปจํ ์คํธ๋ฅผ ํตํด ๋ด ์์ฉ ํ๋ก๊ทธ๋จ ๊ฐ์ฒด๋ฅผ ํตํด ์์ ์ ํธ๋ฆฌ๊ฑฐํ ์ ์์ต๋๋ค.
class SomeComponent extends React.Component {
componentWillReceiveProps(nextProps) {
if (nextProps.someFoo != this.props.someFoo) {
const { app } = this.context;
app.actions.getFooData();
}
}
}
SomeComponent.contextTypes = {
app: React.PropTypes.object
};
์์ ๊ตฌ์ฑ ์์๋ redux ์ฐ๊ฒฐ์ด ํ์ํ์ง ์์ต๋๋ค. ์ฌ์ ํ ์์ ์ ์ ๋ฌํ ์ ์์ต๋๋ค. ๋ฌผ๋ก ๊ตฌ์ฑ ์์ ๋ด์์ ์ํ๋ฅผ ์ ๋ฐ์ดํธํด์ผ ํ๋ ๊ฒฝ์ฐ ์ํ ๋ณ๊ฒฝ์ด ์ ํ๋๋๋ก ์ฐ๊ฒฐ ๊ตฌ์ฑ ์์๋ก ์ ํํฉ๋๋ค.
์ด๊ฒ์ด ๋ด๊ฐ ํต์ฌ "๋น์ฆ๋์ค ๋ก์ง"์ ๊ตฌ์ฑํ ๋ฐฉ๋ฒ์ ๋๋ค. ๋ด ์ํ๊ฐ ๋ฐฑ์๋ ์๋ฒ์์ ์ค์ ๋ก ์ ์ง๋๊ธฐ ๋๋ฌธ์ .. ์ด๊ฒ์ ๋ด ์ฌ์ฉ ์ฌ๋ก์ ์ ๋ง ์ ์๋ํฉ๋๋ค.
"๋น์ฆ๋์ค ๋ ผ๋ฆฌ"๋ฅผ ์ ์ฅํ๋ ์์น๋ ์ค์ ๋ก ๊ทํ์ ์ฌ์ฉ ์ฌ๋ก์ ๋ง๋ ๋ฐฉ๋ฒ์ ๋ฌ๋ ค ์์ต๋๋ค.
@jayesbe ๋ค์ ๋ถ๋ถ์ ๋ฆฌ๋์์ "๋น์ฆ๋์ค ๋ก์ง"์ด ์๊ณ , ๊ฒ๋ค๊ฐ ์ํ ๊ตฌ์กฐ๊ฐ ๋ฆฌ๋์๋ฅผ ํตํด ์คํ ์ด๋ก ์ ์ก๋๋ ํ์ด๋ก๋๋ฅผ ์์ฑํ๋ ์ก์
case 'FOO_REQUEST':
case 'FOO_RESPONSE':
case 'FOO_ERROR':
case 'FOO_RESET':
return {
...state,
...action.data
};
export function fooRequest( res ) {
return {
type: 'FOO_REQUEST',
data: {
isFooing: true,
toFoo: res.saidToFoo
}
};
}
@jayesbe ๋ด ์์ ๊ณผ ๊ฐ์๊ธฐ๋ ๊ทํ์ ๋งค์ฐ ์ ์ฌํ๋ฉฐ ์ผ๋ถ ์์ ์ ์ผ๋ฐ ๋คํธ์ํฌ ์๋ต ๊ฐ์ฒด๋ฅผ ์ธ์๋ก ์์ ํ๋ฉฐ ์๋ต ๋ฐ์ดํฐ๋ฅผ ์์ ์ผ๋ก ์ฒ๋ฆฌํ๊ณ ๋ง์ง๋ง์ผ๋ก ๋งค์ฐ ๊ฐ๋จํ ๊ฐ์ฒด๋ฅผ ๋ฐํ๋ ๊ฐ์ผ๋ก ๋ฐํํ ๋ค์ ์ ๋ฌํ๋ ๋ฐฉ๋ฒ์ ๋ํ ๋ ผ๋ฆฌ๋ฅผ ์บก์ํํ์ต๋๋ค. ํธ์ถ dispatch()๋ฅผ ํตํ ๊ฐ์๊ธฐ. ๋น์ ์ด ํ ์ผ์ฒ๋ผ. ๋ฌธ์ ๋ ์ด๋ฌํ ๋ฐฉ์์ผ๋ก ์์ฑ๋ ์ก์ ์ด ๊ฑฐ์ ๋ชจ๋ ์์ ์ ์ํํ์ผ๋ฉฐ ๋ฆฌ๋์์ ์ฑ ์์ด ๋งค์ฐ ๊ฐ๋ณ๋ค๋ฉด ๋ฆฌ๋์๊ฐ ๋จ์ํ ์ก์ ๊ฐ์ฒด๋ฅผ ํ์ฐํ๋ ๊ฒฝ์ฐ ์๋์ผ๋ก ์ ์ฅํ ๋ฐ์ดํฐ๋ฅผ ์ ์กํด์ผ ํ๋ ์ด์ ๊ฐ ๋ฌด์์ ๋๊น? Redux๊ฐ ์ฐ๋ฆฌ๋ฅผ ์ํด ์๋์ผ๋ก ํฌ์ฌํ๋ ๊ฒ์ ์ ํ ์ด๋ ค์ด ์ผ์ด ์๋๋๋ค.
๋ฐ๋์๋ ์๋๋๋ค. ๊ทธ๋ฌ๋ ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ๋น์ฆ๋์ค ํ๋ก์ธ์ค์ ์ผ๋ถ์ธ
๋น์ฆ๋์ค ๊ท์น์ ๋ฐ๋ผ ์ ํ๋ฆฌ์ผ์ด์
์ ์ํ๋ฅผ ์
๋ฐ์ดํธํ๋ ๊ฒ์ ํฌํจํฉ๋๋ค.
๊ทธ๋์ ๊ฑฐ๊ธฐ์ ์ฝ๊ฐ์ ๋น์ฆ๋์ค ๋ก์ง์ ๋ฃ์ด์ผ ํ ์๋ ์์ต๋๋ค.
๊ทน๋จ์ ์ธ ๊ฒฝ์ฐ ๋ค์์ ํ์ธํ์ธ์.
"๋๊ธฐ์ RTS ์์ง๊ณผ ๋น๋๊ธฐ์ ์ด์ผ๊ธฐ" @ForrestTheWoods
https://blog.forrestthewoods.com/synchronous-rts-engines-and-a-tale-of-desyncs-9d8c3e48b2be
2016๋ 4์ 5์ผ ์คํ 5์ 54๋ถ์ "John Babak" [email protected]์ด ์์ฑํ์ต๋๋ค.
์ด๊ฒ์ ๋๋ถ๋ถ์ ์ํ ์ ๋ฐ์ดํธ ๋ ผ๋ฆฌ๋ฅผ ์ ์งํ๋ ์ด์ ์ ๋๋ค.
๊ฐ์๊ธฐ.@dtinth https://github.com/dtinth ๋ช ํํ ํ์๋ฉด
"์ํ ์ ๋ฐ์ดํธ ๋ ผ๋ฆฌ"๋ "๋น์ฆ๋์ค ๋ ผ๋ฆฌ"๋ฅผ ์๋ฏธํฉ๋๊น?โ
๋น์ ์ด ์ธ๊ธ๋์๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ ๋ฐ๋ ๊ฒ์ ๋๋ค.
์ด ์ด๋ฉ์ผ์ ์ง์ ๋ต์ฅํ๊ฑฐ๋ GitHub์์ ํ์ธํ์ธ์.
https://github.com/reactjs/redux/issues/1171#issuecomment -205754910
@LumiaSaki ์์ฑ์์๊ฒ ๋ณต์กํ ๋ก์ง์ ์ ์งํ๋ฉด์ ๋ฆฌ๋์๋ฅผ ๋จ์ํ๊ฒ ์ ์ง
๊ทธ ๋๋ฌธ์ Redux๋ ์์ ์์ ์ ์ฅ์๋ก ๋ฐ์ดํฐ๋ฅผ ์๋์ผ๋ก ์ ์กํ์ง ์์ต๋๋ค. Redux๋ฅผ ์ฌ์ฉํด์ผ ํ๋ ๋ฐฉ์์ด ์๋๊ธฐ ๋๋ฌธ์ ๋๋ค. Redux๋ ์๋ํ ๊ฒ๊ณผ ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ์ฌ์ฉํ๊ธฐ ์ฝ๊ฒ ๋ณ๊ฒฝ๋์ง ์์ ๊ฒ์ ๋๋ค. ๋ฌผ๋ก , ๋น์ ์ ๋น์ ์๊ฒ ๋ง๋ ์ผ์ ํ๋ ๊ฒ์ด ์ ๋์ ์ผ๋ก ์์ ๋กญ์ง๋ง Redux๊ฐ ๊ทธ๊ฒ์ ์ํด ๋ฐ๋ ๊ฒ์ด๋ผ๊ณ ๊ธฐ๋ํ์ง ๋ง์ญ์์ค.
๊ทธ ๊ฐ์น๋ฅผ ์ํด ๋ค์๊ณผ ๊ฐ์ ๊ฒ์ ์ฌ์ฉํ์ฌ ๊ฐ์๊ธฐ๋ฅผ ์์ฐํฉ๋๋ค.
let {reducer, actions} = defineActions({
fooRequest: (state, res) => ({...state, isFooing: true, toFoo: res.saidToFoo}),
fooResponse: (state, res) => ({...state, isFooing: false, isFooed: true, fooData: res.data}),
fooError: (state, res) => ({...state, isFooing: false, fooData: null, isFooed: false, fooError: res.error})
fooReset: (state, res) => ({...state, isFooing: false, fooData: null, isFooed: false, fooError: null, toFoo: false})
})
defineActions๋ ๋ฆฌ๋์์ ์ก์ ์์ฑ์๋ฅผ ๋ชจ๋ ๋ฐํํฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์ฌ์ํ ์์ ์์ฑ๊ธฐ๋ฅผ ์์ฑํ๋ ๋ฐ ๋ง์ ์๊ฐ์ ํ ์ ํ์ง ์๊ณ ๋ ์ ๋ฐ์ดํธ ๋ ผ๋ฆฌ๋ฅผ ๊ฐ์๊ธฐ ๋ด๋ถ์ ์ ์งํ๋ ๊ฒ์ด ๋งค์ฐ ์ฝ๋ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
์ก์ ์์ฑ์์๊ฒ ๋ ผ๋ฆฌ๋ฅผ ์ ์งํด์ผ ํ๋ค๊ณ ์ฃผ์ฅํ๋ค๋ฉด ๋ฐ์ดํฐ๋ฅผ ์ง์ ์๋ํํ๋ ๋ฐ ๋ฌธ์ ๊ฐ ์์ด์ผ ํฉ๋๋ค. ๊ฐ์๊ธฐ๋ ๊ธฐ๋ฅ์ด๋ฉฐ ์ํ๋ ๋ชจ๋ ์์ ์ ์ํํ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ๊ฐ์๊ธฐ๋ ๋ค์๊ณผ ๊ฐ์ด ๊ฐ๋จํ ์ ์์ต๋๋ค.
function reducer(state, action) {
if (action.data) {
return {...state, ...action.data}
} else {
return state;
}
}
๋น์ฆ๋์ค ๋ก์ง์ ๊ดํ ์ด์ ์์ ์ ํ์ฅํ์ฌ ๋น์ฆ๋์ค ๋ก์ง์ ๋ ๋ถ๋ถ์ผ๋ก ๋๋ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
์ฌ์ฉ์๊ฐ ์คํ ๋ฒํผ์ ํด๋ฆญํ ์ ์๊ณ ์ฑ์ ์ปดํ์ผํ๊ณ ์คํํ ์ ์๋ IDE์ ์ ์ฌํ ์ํํธ์จ์ด๋ฅผ ๊ณ ๋ คํ์ญ์์ค. (์ฌ๊ธฐ์๋ ์ ์ฅ์๋ฅผ ์ฌ์ฉํ๋ ๋น๋๊ธฐ ํจ์๋ฅผ ์ฌ์ฉํ์ง๋ง ๋์ redux-thunk
๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.)
js
export async function runApp (store) {
try {
store.dispatch({ type: 'startCompiling' })
const compiledApp = await compile(store)
store.dispatch({ type: 'startRunning', app: compiledApp })
} catch (e) {
store.dispatch({ type: 'errorCompiling', error: e })
}
}
``` js
'updeep'์์ ๊ฐ์ ธ์ค๊ธฐ
๋ด๋ณด๋ด๊ธฐ const ๊ฐ์๊ธฐ = createReducer({
// [์ก์
์ด๋ฆ]: ์ก์
=> currentState => nextState
์์ ์ปดํ์ผ: () => u({ ์ปดํ์ผ: ์ฐธ }),
errorCompiling: ({ ์ค๋ฅ }) => u({ ์ปดํ์ผ: false, compileError: ์ค๋ฅ }),
์์ ์คํ: ({ ์ฑ }) => u({
์คํ ์ค: () => ์ฑ,
์ปดํ์ผ: ๊ฑฐ์ง
}),
stopRunning: () => u({ ์คํ ์ค: false }),
ํ๊ธฐCompileError: () => u({ compileError: null }),
// ...
})
```
๋๋ ๊ฐ๋ฅํ ํ ๋ง์ ์ฝ๋๋ฅผ ์ด ๊ฒฐ์ ์ ์ธ ์์ญ์ ๋ฃ์ผ๋ ค๊ณ ๋ ธ๋ ฅํ์ง๋ง, ๋ฆฌ๋์์ ์ ์ผํ ์ฑ ์์ ๋ค์ด์ค๋ ์์ ์ด ์ฃผ์ด์ง๋ฉด ์ ํ๋ฆฌ์ผ์ด์ ์ํ๋ฅผ ์ผ๊ด๋๊ฒ ์ ์งํ๋ ๊ฒ์ด๋ผ๋ ์ ์ ์ผ๋์ ๋ก๋๋ค. ๋ ์ด์ ์๋ฌด๊ฒ๋ ์์ต๋๋ค. ๊ทธ ์ธ์๋ Redux๊ฐ ์ํ ์ปจํ ์ด๋์ผ ๋ฟ์ด๋ฏ๋ก Redux ์ธ๋ถ์์ ์ํํฉ๋๋ค.
@dtinth ์ฐ์ํจ,์์ ์์ ์ ๋๋ฌธ์ https://github.com/reactjs/redux/issues/1171#issuecomment -205782740์ ๋น์ ์ด ์ด ๊ฒ๊ณผ ์์ ํ ๋ค๋ฅธ ๋ชจ์ต https://github.com/reactjs/redux/ Issues/1171#issuecomment -205888533 -- ์ก์ ์์ฑ์์์ ์ํ๋ฅผ ๊ตฌ์ฑํ๊ณ ๋ฆฌ๋์์ ์ ๋ฌํ์ฌ ์ ๋ฐ์ดํธ๋ฅผ ํผ๋จ๋ฆด ์ ์๋๋ก ์ ์ํฉ๋๋ค. https://github.com/reactjs/redux/issues/1171#issuecomment-205865840 ).
@winstonewert
Redux์์ ๊ถ์ฅํ๋ ํจํด์ ๋ฐ๋์ ๋๋ค. ๋ฆฌ๋์์์ ๋ณต์กํ ๋ ผ๋ฆฌ๋ฅผ ์ ์งํ๋ฉด์ ์์ ์์ฑ์๋ฅผ ๋จ์ํ๊ฒ ์ ์งํ์ธ์.
์ด๋ป๊ฒ ruducers์ ๋ณต์กํ ๋ ผ๋ฆฌ๋ฅผ ๋ฃ๊ณ ์ฌ์ ํ ์์ํ๊ฒ ์ ์งํ ์ ์์ต๋๊น?
์๋ฅผ ๋ค์ด fetch()๋ฅผ ํธ์ถํ๊ณ ์๋ฒ์์ ๋ฐ์ดํฐ๋ฅผ ๋ก๋ํ๋ ๊ฒฝ์ฐ.. ์ด๋ค ์์ผ๋ก๋ ์ฒ๋ฆฌํฉ๋๋ค. ๋๋ ์์ง "๋ณต์กํ ๋ ผ๋ฆฌ"๋ฅผ ๊ฐ์ง ๊ฐ์๊ธฐ์ ์๋ฅผ ๋ณด์ง ๋ชปํ์ต๋๋ค.
@jayesbe : ์ด... "๋ณต์กํ"๊ณผ "์์ํ"์ ์ง๊ตํฉ๋๋ค. ๊ฐ์๊ธฐ ๋ด๋ถ์ _์ ๋ง__ ๋ณต์กํ ์กฐ๊ฑด๋ถ ๋ ผ๋ฆฌ๋ ์กฐ์์ด ์์ ์ ์์ผ๋ฉฐ, ์ ๋ ฅ์ ๊ธฐ๋ฅ์ผ ๋ฟ์ด๊ณ ๋ถ์์ฉ์ด ์๋ ํ ์ฌ์ ํ ์์ํฉ๋๋ค.
๋ณต์กํ ๋ก์ปฌ ์ํ(ํฌ์คํธ ํธ์ง๊ธฐ, ํธ๋ฆฌ ๋ณด๊ธฐ ๋ฑ)๊ฐ ์๊ฑฐ๋ ๋๊ด์ ์ ๋ฐ์ดํธ์ ๊ฐ์ ์์ ์ ์ฒ๋ฆฌํ๋ ๊ฒฝ์ฐ ๋ฆฌ๋์์ ๋ณต์กํ ๋ ผ๋ฆฌ๊ฐ ํฌํจ๋ฉ๋๋ค. ๊ทธ๊ฒ์ ์ ๋ง๋ก ์ฑ์ ๋ฌ๋ ค ์์ต๋๋ค. ์ผ๋ถ์๋ ๋ณต์กํ ์์ฒญ์ด ์๊ณ ๋ค๋ฅธ ์ผ๋ถ์๋ ๋ณต์กํ ์ํ ์ ๋ฐ์ดํธ๊ฐ ์์ต๋๋ค. ์ผ๋ถ๋ ๋ ๋ค ๊ฐ์ง๊ณ ์์ต๋๋ค :-)
@markerikson ok ๋ ผ๋ฆฌ ๋ฌธ์ ํ ๊ฐ์ง์ ๋๋ค. ๊ทธ๋ฌ๋ ํน์ ์์ ์ ์คํํฉ๋๊น? ์๋ฅผ ๋ค์ด ํ ๊ฒฝ์ฐ์๋ ์ธ ๊ฐ์ง ๋ค๋ฅธ ์์ ์ ํธ๋ฆฌ๊ฑฐํ๊ฑฐ๋ ๋ค๋ฅธ ๊ฒฝ์ฐ์๋ ๋ ๊ฐ์ ๋ณ๊ฐ์ ๋ณ๋ ์์ ์ ํธ๋ฆฌ๊ฑฐํ๋ ํ๋์ ์์ ์ด ์์ต๋๋ค. ๊ทธ ๋ ผ๋ฆฌ + ์์ ์คํ์ ๊ฐ์๊ธฐ์ ๋ค์ด๊ฐ์ผ ํ ๊ฒ์ฒ๋ผ ๋ค๋ฆฌ์ง ์์ต๋๋ค.
๋ด ์ํ ๋ฐ์ดํฐ/๋ชจ๋ธ ์ํ๋ ์๋ฒ์ ์๊ณ ๋ณด๊ธฐ ์ํ๋ ๋ฐ์ดํฐ ๋ชจ๋ธ๊ณผ ๋ค๋ฅด์ง๋ง ํด๋น ์ํ์ ๊ด๋ฆฌ๋ ํด๋ผ์ด์ธํธ์ ์์ต๋๋ค. ๋ด ๋ฐ์ดํฐ ๋ชจ๋ธ ์ํ๋ ๋จ์ํ ๋ณด๊ธฐ๋ก ์ ๋ฌ๋ฉ๋๋ค. ์ด๋ ๋ด ๊ฐ์๊ธฐ์ ์์ ์ ๋งค์ฐ ๊ฐ๊ฒฐํ๊ฒ ๋ง๋ญ๋๋ค.
@jayesbe : ๋ค๋ฅธ ํ๋์ ํธ๋ฆฌ๊ฑฐ๋ง์ด ๊ฐ์๊ธฐ์ ๋ค์ด๊ฐ์ผ ํ๋ค๊ณ ๋งํ ์ฌ๋์ ์๋ฌด๋ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ฌ์ค, ๊ทธ๋ฌ๋ฉด ์๋ฉ๋๋ค. ๊ฐ์๊ธฐ์ ์์
์ ๋จ์ํ (currentState + action) -> newState
์
๋๋ค.
์ฌ๋ฌ ์์ ์ ํจ๊ป ๋ฌถ์ด์ผ ํ๋ ๊ฒฝ์ฐ ์ฝํฌ ๋๋ ์ฌ๊ฐ์ ๊ฐ์ ๋ฐฉ์์ผ๋ก ์ํํ๊ณ ์์๋๋ก ์คํํ๊ฑฐ๋ ์ํ ๋ณ๊ฒฝ์ ์์ ํ๋ ์์ ์ ์ํํ๊ฑฐ๋ ๋ฏธ๋ค์จ์ด๋ฅผ ์ฌ์ฉํ์ฌ ์์ ์ ๊ฐ๋ก์ฑ๊ณ ์ถ๊ฐ ์์ ์ ์ํํฉ๋๋ค.
์์งํ ๋งํด์ ์ด ์์ ์์ ๋ ผ์๊ฐ ๋ฌด์์ธ์ง ํผ๋์ค๋ฝ์ต๋๋ค.
@markerikson ์ฃผ์ ๋ "๋น์ฆ๋์ค ๋ก์ง"๊ณผ ๊ทธ๊ฒ์ด ์ด๋๋ก
๋น์ ์ด ๋งํ๋ฏ์ด ์ ๋ง๋ก ์ค์ํ ๊ฒ์ ๋น์ ์๊ฒ ํจ๊ณผ๊ฐ ์๋ ๊ฒ์ ๋๋ค. ๊ทธ๋ฌ๋ ์ฌ๊ธฐ์ ๊ทํ๊ฐ ์ง๋ฌธํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
์๋ฅผ ๋ค์ด fetch()๋ฅผ ํธ์ถํ๊ณ ์๋ฒ์์ ๋ฐ์ดํฐ๋ฅผ ๋ก๋ํ๋ ๊ฒฝ์ฐ.. ์ด๋ค ์์ผ๋ก๋ ์ฒ๋ฆฌํฉ๋๋ค. ๋๋ ์์ง "๋ณต์กํ ๋ ผ๋ฆฌ"๋ฅผ ๊ฐ์ง ๊ฐ์๊ธฐ์ ์๋ฅผ ๋ณด์ง ๋ชปํ์ต๋๋ค.
๋ด ๊ฐ์๊ธฐ๋ ๋ด ์๋ฒ์์ ์์ ์๋ต์ ๋ฐ์ ๋ด ์ํ๋ฅผ ์ ๋ฐ์ดํธํฉ๋๋ค. ๊ทธ๋ ๊ฒํ๋ฉด ๊ทํ๊ฐ ๋งํ๋ ์ฒ๋ฆฌ ์๋ต์ด ๋ด ๊ฐ์๊ธฐ์์ ์ํ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด ์์ฒญ์ ๋ฆฌ๋์๊ฐ ๋ก์ปฌ ๋ ์ฝ๋ ์บ์์ ์ ์ฅํ๋ ๋ด ์๋ฒ์ ๋ํ JSON ๋ ์ฝ๋ ๊ฐ์ ธ์ค๊ธฐ์ผ ์ ์์ต๋๋ค.
k ๋ ผ๋ฆฌ ๋ฌธ์ ํ ๊ฐ์ง์ ๋๋ค. ๊ทธ๋ฌ๋ ํน์ ์์ ์ ์คํํฉ๋๊น? ์๋ฅผ ๋ค์ด ํ ๊ฒฝ์ฐ์๋ ์ธ ๊ฐ์ง ๋ค๋ฅธ ์์ ์ ํธ๋ฆฌ๊ฑฐํ๊ฑฐ๋ ๋ค๋ฅธ ๊ฒฝ์ฐ์๋ ๋ ๊ฐ์ ๋ณ๊ฐ์ ๋ณ๋ ์์ ์ ํธ๋ฆฌ๊ฑฐํ๋ ํ๋์ ์์ ์ด ์์ต๋๋ค. ๊ทธ ๋ ผ๋ฆฌ + ์์ ์คํ์ ๊ฐ์๊ธฐ์ ๋ค์ด๊ฐ์ผ ํ ๊ฒ์ฒ๋ผ ๋ค๋ฆฌ์ง ์์ต๋๋ค.
๊ทธ๊ฒ์ ๋น์ ์ดํ๋ ์ผ์ ๋ฌ๋ ค ์์ต๋๋ค. ๋ถ๋ช ํ ์๋ฒ ๊ฐ์ ธ์ค๊ธฐ์ ๊ฒฝ์ฐ ํ ์์ ์ด ๋ค๋ฅธ ์์ ์ ํธ๋ฆฌ๊ฑฐํฉ๋๋ค. ์ด๋ ๊ถ์ฅ๋๋ Redux ์ ์ฐจ ๋ด์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋ค์๊ณผ ๊ฐ์ ์์ ์ ์ํํ ์๋ ์์ต๋๋ค.
function createFoobar(dispatch, state, updateRegistry) {
dispatch(createFoobarRecord());
if (updateRegistry) {
dispatch(updateFoobarRegistry());
} else {
dispatch(makeFoobarUnregistered());
}
if (hasFoobarTemps(state)) {
dispatch(dismissFoobarTemps());
}
}
์ด๊ฒ์ Redux๋ฅผ ์ฌ์ฉํ๋ ๋ฐ ๊ถ์ฅ๋๋ ๋ฐฉ๋ฒ์ด ์๋๋๋ค. Redux์์ ๊ถ์ฅํ๋ ๋ฐฉ๋ฒ์ ์ด๋ฌํ ๋ชจ๋ ์ํ๋ ๋ณ๊ฒฝ์ ์ผ์ผํค๋ ๋จ์ผ CREATE_FOOBAR ์์ ์ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค.
@winstonewert :
์ด๊ฒ์ Redux๋ฅผ ์ฌ์ฉํ๋ ๋ฐ ๊ถ์ฅ๋๋ ๋ฐฉ๋ฒ์ด ์๋๋๋ค. Redux์์ ๊ถ์ฅํ๋ ๋ฐฉ๋ฒ์ ์ด๋ฌํ ๋ชจ๋ ์ํ๋ ๋ณ๊ฒฝ์ ์ผ์ผํค๋ ๋จ์ผ CREATE_FOOBAR ์์ ์ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค.
์ง์ ๋ ์ด๋๊ฐ์ ๋ํ ํฌ์ธํฐ๊ฐ ์์ต๋๊น? ๋ด๊ฐ FAQ ํ์ด์ง์ ๋ํ ์กฐ์ฌ๋ฅผ ํ ๋ ๋ด๊ฐ ์๊ฐํด๋ธ ๊ฒ์ Dan์ด ์ง์ ์ ์ํ "๊ทธ๊ฒ์ ์์กด์ "์ด๊ธฐ ๋๋ฌธ์ ๋๋ค. http://redux.js.org/docs/FAQ.html#actions -multiple-actions ๋ฐ Dan์ SO on this ๋ต๋ณ์ ์ฐธ์กฐํ์ญ์์ค.
"๋น์ฆ๋์ค ๋ ผ๋ฆฌ"๋ ์ค์ ๋ก ๊ฝค ๊ด๋ฒ์ํ ์ฉ์ด์ ๋๋ค. "์ผ์ด๋ ์ผ์ด ์์๋์?", "์ด๋ฐ ์ผ์ด ๋ฐ์ํ์ผ๋ ์ด์ ์ด๋ป๊ฒ ํฉ๋๊น?", "์ด๊ฒ์ด ์ ํจํ๊ฐ์?" ๋ฑ๊ณผ ๊ฐ์ ๋ด์ฉ์ ๋ค๋ฃฐ ์ ์์ต๋๋ค. Redux์ ์ค๊ณ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ์ฌ ์ด๋ฌํ ์ง๋ฌธ์ ์ํฉ์ ๋ฐ๋ผ ๋ค์ํ ์์น์์ ๋ต๋ณํ ์ _์_ ์์ต๋๋ค. ๋น๋ก "์ด๋ฐ ์ผ์ด ๋ฐ์ํ์ต๋๊น?"๋ ์ก์ ์์ฑ์์ ๋ ๋ง์ ์ฑ ์์ผ๋ก ๋ณด๊ณ "์ง๊ธ์"์ ๊ฑฐ์ ํ์คํ ๊ฐ์๊ธฐ ์ฑ ์์ผ๋ก ๋ณผ ์ ์์ต๋๋ค.
์ ๋ฐ์ ์ผ๋ก, "๋น์ฆ๋์ค ๋ ผ๋ฆฌ"์ ๋ํ ์ด _ ์ ์ฒด ์ง๋ฌธ _"๊ทธ๊ฒ์ _์
๋ด๊ฐ ๋์ํ๋ ๋จํธํ๊ณ ํ์คํ ๊ท์น์ "์ก์ ์์ฑ์์ ๋น๊ฒฐ์ ๋ก , ๋ฆฌ๋์์ ์์ํ ๊ฒฐ์ ๋ก "์ ๋๋ค. ๊ทธ๊ฒ์ ์ฃผ์ด์ง ๊ฒ์ ๋๋ค.
๊ทธ ์ด์ธ์? ๋น์ ์๊ฒ ๋ง๋ ๊ฒ์ ์ฐพ์ผ์ญ์์ค. ์ผ๊ด์ฑ์ ์ ์งํ์ญ์์ค. ํน์ ๋ฐฉ์์ผ๋ก ํ๋ ์ด์ ๋ฅผ ์ ์ ์์ต๋๋ค. ํจ๊ป ๊ฐ์ธ์.
"๋ฐ์ํ์ต๋๊น?"๊ฐ ๋ ๋ง์ ์์ ์์ฑ์ ์ฑ ์์ผ๋ก ๊ฐ์ฃผ๋์ง๋ง "์ง๊ธ์ ๋ฌด์์ ๋๊น"๋ ๊ฑฐ์ ํ์คํ ๊ฐ์๊ธฐ ์ฑ ์์ ๋๋ค.
์ด๊ฒ์ด ๋ฐ๋ก ๋ถ์์ฉ, ์ฆ "what now"์ ์์ํ์ง ์์ ๋ถ๋ถ์ reducer: #1528์ ๋ฃ๋ ๋ฐฉ๋ฒ์ ๋ํด ๋ณ๋ ฌ ํ ๋ก ์ด ์๋ ์ด์ ์ ๋๋ค.
๋ด๊ฐ ์ฌ์ฉํ ํจํด์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
์ด ์ค๋ ๋์ ์๋ถ๋ถ์์ Dan์ ์ง์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
๋ฐ๋ผ์ ๊ณต์ ๊ถ์ฅ ์ฌํญ์ ๋จผ์ ๋์ผํ ์์ ์ ๋ค๋ฅธ ๋ฆฌ๋์๊ฐ ์๋ตํ๋๋ก ํ๋ ๊ฒ์ ๋๋ค. ์ด์ํด์ง๋ฉด ๋ฐ๋์ ๋ณ๋์ ์ก์ ํฌ๋ฆฌ์์ดํฐ๋ฅผ ๋ง๋์ธ์. ๊ทธ๋ฌ๋ ์ด ์ ๊ทผ ๋ฐฉ์์ผ๋ก ์์ํ์ง ๋ง์ญ์์ค.
๊ทธ๋ฐ ์ ์์ ๊ถ์ฅ๋๋ ์ ๊ทผ ๋ฐฉ์์ ์ด๋ฒคํธ๋น ํ๋์ ์์ ์ ์ ๋ฌํ๋ ๊ฒ์ ๋๋ค. ๊ทธ๋ฌ๋ ์ค์ฉ์ ์ผ๋ก ์๋ํ๋ ์ผ์ ํ์ญ์์ค.
@winstonewert : Dan์ "๋ฆฌ๋์ ๊ตฌ์ฑ" ํจํด์ ์ฐธ์กฐํฉ๋๋ค. ์ฆ, "ํ๋์ ๋ฆฌ๋์๋ง ๋ฃ๋ ์์ " ๋ "๋ง์ ๋ฆฌ๋์๊ฐ ๋์ผํ ์์ ์ ์๋ตํ ์ ์์"์ ๋๋ค. Dan์ ๋จ์ผ ์์ ์ ์๋ตํ๋ ์์์ ๋ฆฌ๋์์ ๋ํด ๋งค์ฐ ๊ด์ฌ์ด ๋ง์ต๋๋ค. ๋ค๋ฅธ ์ฌ๋๋ค์ ๋ฆฌ๋์์ ์ก์ ์ด ๋งค์ฐ ๋ฐ์ ํ๊ฒ ๋ฌถ์ด๊ณ ์ค์ง ํ๋์ ๋ฆฌ๋์๋ง์ด ์ฃผ์ด์ง ์ก์ ์ ์ฒ๋ฆฌํ๋ "์ค๋ฆฌ" ์ ๊ทผ ๋ฐฉ์๊ณผ ๊ฐ์ ๊ฒ์ ์ ํธํฉ๋๋ค. ๋ฐ๋ผ์ ์ด ์๋ "์ฌ๋ฌ ์์ ์ ์์๋๋ก ์ ๋ฌ"ํ๋ ๊ฒ์ด ์๋๋ผ "๋ด ๊ฐ์๊ธฐ ๊ตฌ์กฐ์ ์ผ๋ง๋ ๋ง์ ๋ถ๋ถ์ด ์ด์ ์๋ตํ ๊ฒ์ผ๋ก ์์๋๋์ง"์ ๊ดํ ๊ฒ์ ๋๋ค.
๊ทธ๋ฌ๋ ์ค์ฉ์ ์ผ๋ก ์๋ํ๋ ์ผ์ ํ์ญ์์ค.
:+1:
@sompylasar ๋ด ์์ ์ ์ํ ๊ตฌ์กฐ๊ฐ ์์ผ๋ฉด ๋ด ๋ฐฉ์์ ์ค๋ฅ๊ฐ ํ์๋ฉ๋๋ค. ์ํ ๊ตฌ์กฐ๋ฅผ ๋ด ๋ฆฌ๋์๋ก ์ฝ๊ฒ ์ ํํ๊ณ ๋ด ์์ ์ ๋จ์ํํ ์ ์์ต๋๋ค. ๊ฑด๋ฐฐ.
์ ๊ฐ ๋ณด๊ธฐ์๋ ๊ฐ์ ๊ฒ ๊ฐ์ต๋๋ค.
์ฌ๋ฌ ์ํ ๋ณ๊ฒฝ์ ์ผ์ผํค๋ ์ฌ๋ฌ ๊ฐ์๊ธฐ๋ฅผ ํธ๋ฆฌ๊ฑฐํ๋ ๋จ์ผ ์์ ์ด ์๊ฑฐ๋ ๋จ์ผ ์ํ ๋ณ๊ฒฝ์ ์ ๋ฐํ๋ ๋จ์ผ ๊ฐ์๊ธฐ๋ฅผ ๊ฐ๊ฐ ํธ๋ฆฌ๊ฑฐํ๋ ์ฌ๋ฌ ์์ ์ด ์์ต๋๋ค. ์ฌ๋ฌ ๋ฆฌ๋์๊ฐ ์์ ์ ์๋ตํ๊ณ ์ด๋ฒคํธ๊ฐ ์ฌ๋ฌ ์์ ์ ์ ๋ฌํ๋๋ก ํ๋ ๊ฒ์ ๋์ผํ ๋ฌธ์ ์ ๋ํ ๋์ ์๋ฃจ์ ์ ๋๋ค.
์ธ๊ธํ StackOverflow ์ง๋ฌธ์์ ๊ทธ๋ ๋ค์๊ณผ ๊ฐ์ด ๋งํฉ๋๋ค.
๊ฐ๋ฅํ ํ ์ฌ์ฉ์ ์ํธ ์์ฉ์ ๊ธฐ๋ก์ ๊ฐ๊น์ด ์์ ๋ก๊ทธ๋ฅผ ์ ์งํฉ๋๋ค. ๊ทธ๋ฌ๋ ๊ฐ์๊ธฐ๋ฅผ ๊ตฌํํ๊ธฐ ์ด๋ ต๊ฒ ๋ง๋๋ ๊ฒฝ์ฐ ์ผ๋ถ ์์ ์ ์ฌ๋ฌ ๊ฐ๋ก ๋ถํ ํ๋ ๊ฒ์ ๊ณ ๋ คํ๊ณ UI ์ ๋ฐ์ดํธ๊ฐ ์ฐ์ฐํ ํจ๊ป ๋ฐ์ํ๋ ๋ ๊ฐ์ ๊ฐ๋ณ ์์ ์ผ๋ก ์๊ฐํ ์ ์๋ค๋ฉด.
๋ด๊ฐ ๋ณด๊ธฐ์ Dan์ ์ด์์ ์ธ ๋ฐฉ๋ฒ์ผ๋ก ์ฌ์ฉ์ ์ํธ ์์ฉ๋น ํ๋์ ์์ ์ ์ ์งํ๋ ๊ฒ์ ์ง์งํฉ๋๋ค. ๊ทธ๋ฌ๋ ๊ทธ๋ ์ค์ฉ์ ์ ๋๋ค. ๊ฐ์๊ธฐ๋ฅผ ๊ตฌํํ๊ธฐ ์ด๋ ต๊ฒ ๋ง๋ค ๋ ๊ทธ๋ ์์ ๋ถํ ์ ์ง์งํฉ๋๋ค.
์ฌ๊ธฐ์์ ์ ์ฌํ์ง๋ง ๋ค์ ๋ค๋ฅธ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ์๊ฐํํ๊ณ ์์ต๋๋ค.
1) ์์
์ ์ํํ๋ ค๋ฉด ์ฃผ์ ์ฌ๋ฌ ์์ญ์ ๋ํ ์
๋ฐ์ดํธ๊ฐ ํ์ํฉ๋๋ค. ํนํ combineReducers
๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ ํ์ ๋๋ฉ์ธ์ ์ฒ๋ฆฌํ๋ ๋ณ๋์ ๊ฐ์๊ธฐ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ์ ๊ทธ๋ ์ต๋๋ค. ๋น์ ์:
2) ํน์ ์์๋ก ๋ฐ์ํ๋ ์ผ๋ จ์ ๋จ๊ณ๊ฐ ์์ผ๋ฉฐ ๊ฐ ๋จ๊ณ์๋ ์ผ๋ถ ์ํ ์ ๋ฐ์ดํธ ๋๋ ๋ฏธ๋ค์จ์ด ์์ ์ด ํ์ํฉ๋๋ค. ๋น์ ์:
๋ค, ํ์คํ ๊ฒน์น๋ ๋ถ๋ถ์ด ์์ง๋ง ์ฌ๊ธฐ์ ์ ์ ์ ์ธ ๊ทธ๋ฆผ์ ์ฐจ์ด์ ์ค ์ผ๋ถ๋ ๋ค์ํ ์ฌ์ฉ ์ฌ๋ก๋ผ๊ณ ์๊ฐํฉ๋๋ค.
@markerikson ๊ทธ๋์ ๋น์ ์ ์กฐ์ธ์ '์ด๋ค ์ํฉ์ ๋ง๋ฌ๋๋์ ๋ฌ๋ ค์๋ค'๊ณ , ์ก์ ์ด๋ ๋ฆฌ๋์์์ '๋น์ฆ๋์ค ๋ก์ง'์ ๊ท ํ์ ๋ง์ถ๋ ๋ฐฉ๋ฒ์ ๋น์ ์ ๊ณ ๋ ค์ ๋ฌ๋ ค ์์ต๋๋ค. ์ฐ๋ฆฌ๋ ๊ฐ๋ฅํ ํ ์์ ๊ธฐ๋ฅ์ ์ด์ ์ ์ทจํด์ผํฉ๋๊น?
์. ๊ฐ์๊ธฐ๋ Redux ์๊ตฌ ์ฌํญ์ผ๋ก ์์ํด์ผ _๊ฐ์ง๊ณ _ ์์ต๋๋ค(ํน๋ณํ ๊ฒฝ์ฐ์ 0.00001% ์ ์ธ). ์ก์ ์ ์์๋ ์ ๋์ ์ผ๋ก _ ํ์ง ์์๋ _ ์์ํด์ผ ํ๋ฉฐ ์ค์ ๋ก ๋๋ถ๋ถ์ "๋ถ์๋ฌผ"์ด ์ด ๊ณณ์ ๋๋ค. ๊ทธ๋ฌ๋ ์์ ํจ์๋ ์์ ํจ์๋ณด๋ค ์ดํดํ๊ณ ํ ์คํธํ๊ธฐ๊ฐ ๋ถ๋ช ํ ๋ ์ฝ๊ธฐ ๋๋ฌธ์ _if_ ์ผ๋ถ ์์ ์์ฑ ๋ ผ๋ฆฌ๋ฅผ ์์ํ๊ณ ํ๋ฅญํ๊ฒ ๋ง๋ค ์ ์์ต๋๋ค! ๊ทธ๋ ์ง ์๋ค๋ฉด ๊ด์ฐฎ์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋ค, ์ ๊ด์ ์์ ๋ณผ ๋ ์ฑ์ ๋ ผ๋ฆฌ์ ์์น์ ์ ์ ํ ๊ท ํ์ด ๋ฌด์์ธ์ง ๊ฒฐ์ ํ๋ ๊ฒ์ ๊ฐ๋ฐ์์ ๋ชซ์ ๋๋ค. ์ก์ ์์ฑ์/๋ฆฌ๋์ ๋ถํ ์ ์ด๋ ์ชฝ์ด ์ ์ง๋์ด์ผ ํ๋์ง์ ๋ํ ๋จ์ผํ๊ณ ํ์คํ ๊ท์น์ ์์ต๋๋ค. (์, ์์์ ์ธ๊ธํ "๊ฒฐ์ ๋ก /๋น๊ฒฐ์ ๋ก "์ ์ ์ธํ๊ณ . ์ด ์ฃผ์์์ ๋ถ๋ช ํ ์ธ๊ธํ๋ ค๊ณ ํ๋ ๊ฒ์ ๋๋ค. ๋ถ๋ช ํ.)
@cpsubrian
๊ฒฐ๊ณผ๋ก ์ํํ ์์ : ๊ฐ์๊ธฐ
์ค์ ๋ก ์ด๊ฒ์ด saga๊ฐ "์ด๋ฐ ์ผ์ด ๋ฐ์ํ๋ค๋ฉด, ๊ทธ๊ฒ๋ ๋ฐ์ํด์ผ ํฉ๋๋ค"์ ๊ฐ์ ํจ๊ณผ๋ฅผ ์ฒ๋ฆฌํ๋ ์ด์ ์ ๋๋ค.
@markerikson @LumiaSaki
์ก์ ์ ์์๋ ์ ๋์ ์ผ๋ก ์์ํ ํ์๊ฐ ์์ผ๋ฉฐ ์ค์ ๋ก ๋๋ถ๋ถ์ "๋ถ์๋ฌผ"์ด ์ด ๊ณณ์ ๋๋ค.
์ค์ ๋ก ์ก์
ํฌ๋ฆฌ์์ดํฐ๋ ๋ถ์ํ๊ฑฐ๋ ์กด์ฌํ ํ์์กฐ์ฐจ ์์ต๋๋ค.
http://stackoverflow.com/a/34623840/82609 ์ฐธ์กฐ
๊ทธ๋ฆฌ๊ณ ๋ค, ์ ๊ด์ ์์ ๋ณผ ๋ ์ฑ์ ๋ ผ๋ฆฌ์ ์์น์ ์ ์ ํ ๊ท ํ์ด ๋ฌด์์ธ์ง ๊ฒฐ์ ํ๋ ๊ฒ์ ๊ฐ๋ฐ์์ ๋ชซ์ ๋๋ค. ์ก์ ์์ฑ์/๋ฆฌ๋์ ๋ถํ ์ ์ด๋ ์ชฝ์ด ์ ์ง๋์ด์ผ ํ๋์ง์ ๋ํ ๋จ์ผํ๊ณ ํ์คํ ๊ท์น์ ์์ต๋๋ค.
์, ํ์ง๋ง ๊ฒฝํ ์์ด ๊ฐ ์ ๊ทผ ๋ฐฉ์์ ๋จ์ ์ ์์์ฐจ๋ฆฌ๋ ๊ฒ์ ๊ทธ๋ฆฌ ๋ถ๋ช ํ์ง ์์ต๋๋ค. ์ฌ๊ธฐ์์ ๋ด ์๊ฒฌ๋ ์ฐธ์กฐํ์ญ์์ค. https://github.com/reactjs/redux/issues/1171#issuecomment -167585575
์๊ฒฉํ ๊ท์น์ ๋๋ถ๋ถ์ ๊ฐ๋จํ ์ฑ์ ์ ํฉํ์ง ์์ง๋ง ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ๊ตฌ์ฑ ์์๋ฅผ ๋น๋ํ๋ ค๋ ๊ฒฝ์ฐ ์ด๋ฌํ ๊ตฌ์ฑ ์์๋ ์์ฒด ๋ฒ์ ๋ฐ์ ๊ฒ์ ์ธ์ํด์๋ ์ ๋ฉ๋๋ค.
๋ฐ๋ผ์ ์ ์ฒด ์ฑ์ ๋ํ ์ ์ญ ์์ ๋ชฉ๋ก์ ์ ์ํ๋ ๋์ ์ฑ์ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ๊ตฌ์ฑ ์์๋ก ๋ถํ ํ ์ ์์ผ๋ฉฐ ๊ฐ ๊ตฌ์ฑ ์์์๋ ์์ฒด ์์ ๋ชฉ๋ก์ด ์์ผ๋ฉฐ ์ด๋ฌํ ์์ ๋ง ์ ๋ฌ/์ถ์ํ ์ ์์ต๋๋ค. ๋ฌธ์ ๋ "๋ ์ง ์ ํ๊ธฐ์์ ๋ ์ง๊ฐ ์ ํ๋๋ฉด ํด๋น ํ ์ผ ํญ๋ชฉ์ ๋ฏธ๋ฆฌ ์๋ฆผ์ ์ ์ฅํ๊ณ ํผ๋๋ฐฑ ์๋ฆผ์ ํ์ํ ๋ค์ ๋ฏธ๋ฆฌ ์๋ฆผ์ด ์๋ ํ ์ผ ๋ชฉ๋ก์ผ๋ก ์ฑ์ ํ์ํด์ผ ํฉ๋๋ค"๋ฅผ ์ด๋ป๊ฒ ํํํฉ๋๊น? saga๊ฐ ์คํ๋ฉ๋๋ค: ๊ตฌ์ฑ ์์๋ฅผ ์ค์ผ์คํธ๋ ์ด์
https://github.com/slorber/scalable-frontend-with-elm-or-redux ๋
๊ทธ๋ฆฌ๊ณ ๋ค, ์ ๊ด์ ์์ ๋ณผ ๋ ์ฑ์ ๋ ผ๋ฆฌ์ ์์น์ ์ ์ ํ ๊ท ํ์ด ๋ฌด์์ธ์ง ๊ฒฐ์ ํ๋ ๊ฒ์ ๊ฐ๋ฐ์์ ๋ชซ์ ๋๋ค. ์ก์ ์์ฑ์/๋ฆฌ๋์ ๋ถํ ์ ์ด๋ ์ชฝ์ด ์ ์ง๋์ด์ผ ํ๋์ง์ ๋ํ ๋จ์ผํ๊ณ ํ์คํ ๊ท์น์ ์์ต๋๋ค.
์, ๋ฆฌ๋์์ ๋ก์ง์ ๋ฃ๋ ์ก์ ์์ฑ์์ ๋ก์ง์ ๋ฃ๋ Redux์ ์๊ตฌ ์ฌํญ์ ์์ต๋๋ค. Redux๋ ์ด๋ ์ชฝ์ด๋ ์ค๋จ๋์ง ์์ต๋๋ค. ์ด๋ค ์์ผ๋ก๋ ํด์ผ ํ๋ค๋ ์๊ฒฉํ๊ณ ๋น ๋ฅธ ๊ท์น์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ Dan์ ๊ถ์ฅ ์ฌํญ์ "๊ฐ๋ฅํ ํ ์ฌ์ฉ์ ์ํธ ์์ฉ์ ๊ธฐ๋ก์ ๊ฐ๊น์ด ์์ ๋ก๊ทธ๋ฅผ ์ ์ง"ํ๋ ๊ฒ์ด์์ต๋๋ค. ์ฌ์ฉ์ ์ด๋ฒคํธ๋น ๋จ์ผ ์์ ์ ์ ๋ฌํ ํ์๋ ์์ง๋ง ๊ถ์ฅ๋ฉ๋๋ค.
์ ๊ฒฝ์ฐ์๋ 1๊ฐ์ ์์ ์ ๊ด์ฌ์ด ์๋ 2๊ฐ์ ๊ฐ์๊ธฐ๊ฐ ์์ต๋๋ค. ์์ action.data๋ก๋ ์ถฉ๋ถํ์ง ์์ต๋๋ค. ๋ณํ๋ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํด์ผ ํฉ๋๋ค. 2๊ฐ์ ๊ฐ์๊ธฐ์์ ๋ณํ์ ์ํํ๊ณ ์ถ์ง ์์์ต๋๋ค. ๊ทธ๋์ ์ฝํฌ๋ก ๋ณํ์ ์ํํ๋ ํจ์๋ฅผ ์ฎ๊ฒผ์ต๋๋ค. ์ด๋ฐ ์์ผ๋ก ๋ด ๋ฆฌ๋์๋ ์ฌ์ฉํ ์ค๋น๊ฐ ๋ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ต๋๋ค. ์ด๊ฒ์ ๋ด ์งง์ 1๊ฐ์ redux ๊ฒฝํ์์ ์๊ฐํ ์ ์๋ ์ต๊ณ ์ ๋๋ค.
์์ ๊ตฌ์กฐ์์ ๊ตฌ์ฑ ์์/๋ณด๊ธฐ๋ฅผ ๋ถ๋ฆฌํ๋ ๊ฒ์ ์ด๋ป์ต๋๊น? ๋ด ๋ชฉํ๋ ์ ์ฅ์ ๊ตฌ์กฐ์ ์ํฅ์ ๋ฐ๋ ๋ชจ๋ ๊ฒ์ด ๋ฆฌ๋์์์ ๊ด๋ฆฌ๋์ด์ผ ํ๋ ๊ฒ์ ๋๋ค. ๊ทธ๋์ ์ ํ๊ธฐ๋ฅผ ๋ฆฌ๋์์ ํจ๊ป ๋ฐฐ์นํ๋ ๊ฒ์ ์ข์ํ๋ฏ๋ก ๊ตฌ์ฑ ์์๊ฐ ์ ์ฅ์์ ํน์ ๋ ธ๋๋ฅผ ์ป๋ ๋ฐฉ๋ฒ์ ์ ํ์๊ฐ ์์ต๋๋ค.
์ด๋ ๊ตฌ์ฑ ์์์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ๋ฐ ์ ์ฉํฉ๋๋ค. ๊ตฌ์ฑ ์์๊ฐ ์์ ์ ์ ๋ฌํ ๋ ๋ฐ๋์ ๊ฒฝ์ฐ๋ ์ด๋ป์ต๋๊น?
์๋ฅผ ๋ค์ด Todo ์ฑ์์ Todo ํญ๋ชฉ์ ์ด๋ฆ์ ์ ๋ฐ์ดํธํ๊ณ ์์ผ๋ฏ๋ก ์ ๋ฐ์ดํธํ๋ ค๋ ํญ๋ชฉ์ ์ผ๋ถ๋ฅผ ์ ๋ฌํ๋ ์์ ์ ์ ๋ฌํ๋ค๊ณ ๊ฐ์ ํด ๋ณด๊ฒ ์ต๋๋ค.
dispatch(updateItem({name: <text variable>}));
, ์์ ์ ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
const updateItem = (updatedData) => {type: "UPDATE_ITEM", updatedData}
์ด๊ฒ์ ๊ฐ๋จํ ๋ค์์ ์ํํ ์ ์๋ ๊ฐ์๊ธฐ์ ์ํด ์ฒ๋ฆฌ๋ฉ๋๋ค.
Object.assign({}, item, action.updatedData)
ํญ๋ชฉ์ ์ ๋ฐ์ดํธํฉ๋๋ค.
์ด๊ฒ์ ๋์ผํ ์์ ๊ณผ ๊ฐ์๊ธฐ๋ฅผ ์ฌ์ฌ์ฉํ์ฌ Todo ํญ๋ชฉ์ ๋ชจ๋ ์ํ์ ์ ๋ฐ์ดํธํ ์ ์์ผ๋ฏ๋ก ํ๋ฅญํ๊ฒ ์๋ํฉ๋๋ค. ์:
updateItem({description: <text variable>})
๋์ ์ค๋ช ์ด ๋ณ๊ฒฝ๋ ๊ฒฝ์ฐ.
๊ทธ๋ฌ๋ ์ฌ๊ธฐ์ ๊ตฌ์ฑ ์์๋ ์์ ์์ Todo ํญ๋ชฉ์ด ์ด๋ป๊ฒ ์ ์๋๋์ง ์์์ผ ํ๊ณ ํด๋น ์ ์๊ฐ ๋ณ๊ฒฝ๋๋ฉด ๊ทธ๊ฒ์ ์์กดํ๋ ๋ชจ๋ ๊ตฌ์ฑ ์์์์ ๋ณ๊ฒฝํ๋ ๊ฒ์ ๊ธฐ์ตํด์ผ ํฉ๋๋ค. ์ด๋ ๋ถ๋ช ํ ๋์ ์๊ฐ์ ๋๋ค. ์ด ์๋๋ฆฌ์ค์ ๋ํ ์ ์ ์ฌํญ์ด ์์ต๋๊น?
@dcoellarb
์ด๋ฐ ์ข ๋ฅ์ ์ํฉ์์ ๋ด ์๋ฃจ์ ์ ์์ฉ๊ตฌ๋ฅผ ์์ฑํ๊ธฐ ์ํด Javascript์ ์ ์ฐ์ฑ์ ํ์ฉํ๋ ๊ฒ์ ๋๋ค.
๊ทธ๋์ ๋๋ ๊ฐ์ง ์ ์์ต๋๋ค :
const {reducer, actions, selector} = makeRecord({
name: TextField,
description: TextField,
completed: BooleanField
})
์ฌ๊ธฐ์ makeRecord๋ ๋ด ์ค๋ช ์์ ์๋์ผ๋ก ๊ฐ์๊ธฐ, ์ก์ ์์ฑ๊ธฐ ๋ฐ ์ ํ๊ธฐ๋ฅผ ๋น๋ํ๋ ๊ธฐ๋ฅ์ ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์์ฉ๊ตฌ๊ฐ ์ ๊ฑฐ๋์ง๋ง ๋์ค์ ์ด ๊น๋ํ ํจํด์ ๋ง์ง ์๋ ์์ ์ ์ํํด์ผ ํ๋ ๊ฒฝ์ฐ makeRecord์ ๊ฒฐ๊ณผ์ ์ฌ์ฉ์ ์ง์ ๊ฐ์๊ธฐ/๋์/์ ํ๊ธฐ๋ฅผ ์ถ๊ฐํ ์ ์์ต๋๋ค.
tks @winstonewert ๋๋ ์์ฉ๊ตฌ๋ฅผ ํผํ๊ธฐ ์ํ ์ ๊ทผ ๋ฐฉ์์ ์ข์ํฉ๋๋ค. ๋ง์ ๋ชจ๋ธ์ด ์๋ ์ฑ์์ ๋ง์ ์๊ฐ์ ์ ์ฝํ ์ ์๋ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด๊ฒ์ด ์ด๋ป๊ฒ ๊ตฌ์ฑ ์์๋ฅผ ์ ์ฅ์ ๊ตฌ์กฐ์์ ๋ถ๋ฆฌํ๋์ง ์ ์ ์์ต๋๋ค. ์ฆ, ์์ ์ด ์์ฑ๋๋๋ผ๋ ๊ตฌ์ฑ ์์๋ ์ ๋ฐ์ดํธ๋ ํ๋๋ฅผ ์ฌ์ ํ ์ ๋ฌํด์ผ ํฉ๋๋ค. ์ฆ, ๊ตฌ์ฑ ์์๋ ์ฌ์ ํ ๋ค์ ๊ตฌ์กฐ๋ฅผ ์์์ผ ํฉ๋๋ค. ๊ฐ๊ฒ ๋ง์ง?
@winstonewert @dcoellarb ์ ์๊ฐ์๋ ์ก์ ํ์ด๋ก๋ ๊ตฌ์กฐ๋ ๋ฆฌ๋์๊ฐ ์๋ ์ก์ ์ ์ํด์ผ ํ๋ฉฐ ๋ฆฌ๋์์์ ๋ช ์์ ์ผ๋ก ์ํ ๊ตฌ์กฐ๋ก ๋ณํ๋์ด์ผ ํฉ๋๋ค. ์ด๋ฌํ ๊ตฌ์กฐ๊ฐ ์ด๊ธฐ ๋จ์์ฑ์ ์ํด ์๋ก ๋ฏธ๋ฌ๋ง๋๋ค๋ ๊ฒ์ ์ด์ด ์ข์ ์ฐ์ฐ์ ์ผ์น์ผ ๊ฒ์ ๋๋ค. ์ด ๋ ๊ตฌ์กฐ๋ ๋์ผํ ๊ฐ์ฒด๊ฐ ์๋๊ธฐ ๋๋ฌธ์ ํญ์ ์๋ก๋ฅผ ๋ฏธ๋ฌ๋งํ ํ์๊ฐ ์์ต๋๋ค.
@sompylasar ๋ง์์, ๊ทธ๋ ๊ฒ ํด์. api/rest ๋ฐ์ดํฐ๋ฅผ ๋ด ์ ์ฅ์ ๊ตฌ์กฐ๋ก ๋ณํํ์ง๋ง ์ฌ์ ํ ์ ์ฅ์ ๊ตฌ์กฐ๋ฅผ ์์์ผ ํ๋ ์ ์ผํ ๊ฒ์ ๊ฐ์๊ธฐ์ ์ ํ๊ธฐ๋ฟ์ธ๊ฐ์? ๋ด๊ฐ ๊ทธ๋ค์ ๊ฐ์ ์์น์ ๋ฐฐ์นํ๋ ์ด์ , ๋ด ๋ฌธ์ ๋ ๊ตฌ์ฑ ์์/๋ณด๊ธฐ์ ์์ต๋๋ค. ๋์ค์ ๋ณ๊ฒฝํ๊ธฐ๋ก ๊ฒฐ์ ํ ๊ฒฝ์ฐ์ ๋๋นํ์ฌ ์์ ๊ตฌ์กฐ๋ฅผ ์ ํ์๊ฐ ์๋ ๊ฒ์ ์ ํธํ์ง๋ง ๋ด ์์์ ์ค๋ช ํ๋ฏ์ด ๊ตฌ์กฐ๋ฅผ ์์์ผ ํ ์ ์์ต๋๋ค. ์ ๋ฐ์ดํธํ ์ฌ๋ฐ๋ฅธ ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ด์ญ์์ค. ๋ ์ข์ ๋ฐฉ๋ฒ์ ์ฐพ์ง ๋ชปํ์ต๋๋ค.
@dcoellarb ๋ณด๊ธฐ๋ฅผ ํน์ ์ ํ์ ๋ฐ์ดํฐ ์ ๋ ฅ์ผ๋ก ์๊ฐํ ์ ์์ต๋๋ค(๋ฌธ์์ด ๋๋ ์ซ์์ ๊ฐ์ง๋ง ํ๋๊ฐ ์๋ ๊ตฌ์กฐํ๋ ๊ฐ์ฒด). ์ด ๋ฐ์ดํฐ ๊ฐ์ฒด๋ ๋ฐ๋์ ์ ์ฅ์ ๊ตฌ์กฐ๋ฅผ ๋ฏธ๋ฌ๋งํ์ง๋ ์์ต๋๋ค. ์ด ๋ฐ์ดํฐ ๊ฐ์ฒด๋ฅผ ์์ ์ ๋ฃ์ต๋๋ค. ์ด๊ฒ์ ์์ ๊ตฌ์กฐ์ ๊ฒฐํฉ๋์ง ์์ต๋๋ค. ์คํ ์ด์ ๋ทฐ๋ ๋ชจ๋ ์ก์ ํ์ด๋ก๋ ๊ตฌ์กฐ์ ๊ฒฐํฉ๋์ด์ผ ํฉ๋๋ค.
@sompylasar ๋ ์๋ฏธ๊ฐ ์์ต๋๋ค. ์๋ํด ๋ณด๊ฒ ์ต๋๋ค. ๊ฐ์ฌํฉ๋๋ค!!!
redux-saga
๋ฅผ ์ฌ์ฉํ์ฌ ์ก์
์ ๋ ์์ํ๊ฒ ๋ง๋ค ์ ์๋ค๊ณ ๋ง๋ถ์ด์
์ผ ํฉ๋๋ค. ๊ทธ๋ฌ๋ redux-saga๋ ๋น๋๊ธฐ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐ ์ด๋ ค์์ ๊ฒช์ผ๋ฏ๋ก redux-saga ๋์ RxJS(๋๋ ๋ชจ๋ FRP ๋ผ์ด๋ธ๋ฌ๋ฆฌ)๋ฅผ ์ฌ์ฉํ์ฌ ์ด ์์ด๋์ด๋ฅผ ํ ๋จ๊ณ ๋ ๋ฐ์ ์ํฌ ์ ์์ต๋๋ค. ๋ค์์ KefirJS๋ฅผ ์ฌ์ฉํ ์์
๋๋ค. https://github.com/awesome-editor/awesome-editor/blob/saga-demo/src/stores/app/AppSagaHandlers.js
์๋ ํ์ธ์ @frankandrobot ์ ๋๋ค .
redux-saga๋ ๋น๋๊ธฐ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํด ๊ณ ๊ตฐ๋ถํฌํฉ๋๋ค.
์ด๊ฒ ๋ฌด์จ ๋ง์ด์์? redux-saga
๋ ๋น๋๊ธฐ ์ด๋ฒคํธ์ ๋ถ์์ฉ์ ์ฐ์ํ ๋ฐฉ์์ผ๋ก ์ฒ๋ฆฌํ๋๋ก ๋ง๋ค์ด์ง์ง ์์์ต๋๊น? https://github.com/reactjs/redux/issues/1171#issuecomment -167715393์ ์ดํด๋ณด์ธ์.
์๋ @IceOnFire . ์ง๋๋ฒ์ redux-saga
๋ฌธ์๋ฅผ ์ฝ์์ ๋ ๋ณต์กํ ๋น๋๊ธฐ ์ํฌํ๋ก๋ฅผ ์ฒ๋ฆฌํ๋ ๊ฒ์ ์ด๋ ต์ต๋๋ค. ์๋ฅผ ๋ค์ด ์ฐธ์กฐ: http://yelouafi.github.io/redux-saga/docs/advanced/NonBlockingCalls.html
๊ทธ๊ฒ์ (์ฌ์ ํ ๋งํฉ๋๊น?) ํจ๊ณผ์ ๋ํด ๋ฌด์ธ๊ฐ๋ฅผ ๋งํ์ต๋๋ค.
๋ณต์กํด์ง๊ธฐ ์์ํ๊ธฐ ๋๋ฌธ์ ๋๋จธ์ง ์ธ๋ถ ์ฌํญ์ ๋ ์์๊ฒ ๋งก๊ธฐ๊ฒ ์ต๋๋ค.
FRP ๋ฐฉ์๊ณผ ๋น๊ต: https://github.com/frankandrobot/rflux/blob/master/doc/06-sideeffects.md#a -more-complex-workflow
์ ์ฒด ์ํฌํ๋ก๊ฐ ์์ ํ ์ฒ๋ฆฌ๋ฉ๋๋ค. (๋ช ์ค๋ง ์ถ๊ฐํ๋ฉด ๋ฉ๋๋ค.) ๊ฒ๋ค๊ฐ redux-saga
์ ์ฅ์ ๋ ๋๋ถ๋ถ ์ป์ ์ ์์ต๋๋ค(๋ชจ๋ ๊ฒ์ด ์์ ํจ์์ด๋ฉฐ ๋๋ถ๋ถ ์ฌ์ด ๋จ์ ํ
์คํธ์).
๋ง์ง๋ง์ผ๋ก ์ด๊ฒ์ ๋ํด ์๊ฐํ์ ๋ ๋ฌธ์ ๋ redux-saga๊ฐ ๋ชจ๋ ๊ฒ์ ๋๊ธฐ์์ผ๋ก ๋ณด์ด๊ฒ ํ๋ค๋ ๊ฒฐ๋ก ์ ๋๋ฌํ์ต๋๋ค. ๊ฐ๋จํ ์ํฌํ๋ก์๋ ํ๋ฅญํ์ง๋ง ๋ณต์กํ ๋น๋๊ธฐ ์ํฌํ๋ก์ ๊ฒฝ์ฐ ๋น๋๊ธฐ๋ฅผ ๋ช ์์ ์ผ๋ก ์ฒ๋ฆฌํ๋ฉด ๋ ์ฝ์ต๋๋ค. ์ด๊ฒ์ด FRP๊ฐ ํ์ํ ๊ฒ์ ๋๋ค.
์๋ ํ์ธ์ @frankandrobot ์ ๋๋ค .
์ค๋ช
ํด์ฃผ์
์ ๊ฐ์ฌํฉ๋๋ค. ๋๋ ๋น์ ์ด ์ธ๊ธํ ์ธ์ฉ๋ฌธ์ ๋ณผ ์ ์์ต๋๋ค. ์๋ง๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์งํํ์ ๊ฒ์
๋๋ค(์๋ฅผ ๋ค์ด, ์ง๊ธ์ ์ ์ ๋ณธ ์ ์ด ์๋ cancel
ํจ๊ณผ๋ฅผ ๋ด
๋๋ค).
๋ ์์ (saga ๋ฐ FRP)๊ฐ ์ ํํ ๋์ผํ๊ฒ ๋์ํ๋ ๊ฒฝ์ฐ ํฐ ์ฐจ์ด๊ฐ ์์ต๋๋ค. ํ๋๋ try/catch ๋ธ๋ก ๋ด๋ถ์ ๋ช
๋ น ์ํ์ค์ด๊ณ ๋ค๋ฅธ ํ๋๋ ์คํธ๋ฆผ์ ๋ฉ์๋ ์ฒด์ธ์
๋๋ค. ์คํธ๋ฆผ์ ๋ํ ๊ฒฝํ์ด ๋ถ์กฑํ๊ธฐ ๋๋ฌธ์ yield
ํ๋ํ๋๋ฅผ ํ๋์ฉ ํ
์คํธํ ์ ์์ผ๋ฏ๋ก ์ฌ๊ฐ ์์ ๋ฅผ ๋ ์ฝ๊ธฐ ์ฝ๊ณ ํ
์คํธํ๊ธฐ๊ฐ ๋ ์ฝ์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด๊ฒ์ ๊ธฐ์ ๋ณด๋ค ๋ด ๋ง์๊ฐ์ง ๋๋ฌธ์ด๋ผ๊ณ ํ์ ํฉ๋๋ค.
์ด์จ๋ ์ด์ ๋ํ @yelouafi ์ ์๊ฒฌ์ ์๊ณ
@bvaughn ์ฌ๊ธฐ์ ์ค๋ช ํ๋ ๊ฒ๊ณผ ๋์ผํ ํ ์คํธ์์ ์์ , ๊ฐ์๊ธฐ, ์ ํ๊ธฐ๋ฅผ ํ ์คํธํ๋ ์ ์ ํ ์๋ฅผ
์์ , ๊ฐ์๊ธฐ ๋ฐ ์ ํ๊ธฐ๋ฅผ ํ ์คํธํ๋ ๊ฐ์ฅ ํจ์จ์ ์ธ ๋ฐฉ๋ฒ์ ํ ์คํธ๋ฅผ ์์ฑํ ๋ "๋" ์ ๊ทผ ๋ฐฉ์์ ๋ฐ๋ฅด๋ ๊ฒ์ ๋๋ค. ์ด๊ฒ์ ๊ฐ๊ฐ์ ๊ฐ๋ณ์ ์ผ๋ก ์ด์ ์ ๋ง์ถ๋ 3์ธํธ์ ํ ์คํธ๊ฐ ์๋๋ผ ์ฃผ์ด์ง ์ผ๋ จ์ ์์ , ๊ฐ์๊ธฐ ๋ฐ ์ ํ๊ธฐ๋ฅผ ๋ค๋ฃจ๋ ํ๋์ ํ ์คํธ ์ธํธ๋ฅผ ์์ฑํด์ผ ํจ์ ์๋ฏธํฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์ค์ ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ฐ์ํ๋ ์ํฉ์ ๋ณด๋ค ์ ํํ๊ฒ ์๋ฎฌ๋ ์ด์ ํ๊ณ ๋น์ฉ ๋๋น ํจ๊ณผ๋ฅผ ๊ทน๋ํํ ์ ์์ต๋๋ค.
์๋ ํ์ธ์ @morgs32 ๐
์ด ๋ฌธ์ ๋ ์กฐ๊ธ ์ค๋๋์๊ณ Redux๋ฅผ ํ๋์ ์ฌ์ฉํ์ง ์์์ต๋๋ค. Redux ์ฌ์ดํธ์ ํ ์คํธ ์์ฑ ์ ๋ํ ์น์ ์ด ์์ผ๋ ํ์ธํด๋ณด์ธ์.
๊ธฐ๋ณธ์ ์ผ๋ก ์ ๋ ์ก์ ๊ณผ ๋ฆฌ๋์์ ๋ํ ํ ์คํธ๋ฅผ ๋ฐ๋ก ์์ฑํ๋ ๊ฒ๋ณด๋ค ๋ค์๊ณผ ๊ฐ์ด ํจ๊ป ์์ฑํ๋ ๊ฒ์ด ๋ ํจ์จ์ ์ผ ์ ์๋ค๋ ์ ์ ์ง์ ํ์ต๋๋ค.
import configureMockStore from 'redux-mock-store'
import { actions, selectors, reducer } from 'your-redux-module';
it('should support adding new todo items', () => {
const mockStore = configureMockStore()
const store = mockStore({
todos: []
})
// Start with a known state
expect(selectors.todos(store.getState())).toEqual([])
// Dispatch an action to modify the state
store.dispatch(actions.addTodo('foo'))
// Verify the action & reducer worked successfully using your selector
// This has the added benefit of testing the selector also
expect(selectors.todos(store.getState())).toEqual(['foo'])
})
์ด๊ฒ์ ํ๋ก์ ํธ์์ ๋ช ๋ฌ ๋์ Redux๋ฅผ ์ฌ์ฉํ ํ ๊ด์ฐฐํ ๊ฒ์ ๋๋ค. ๊ณต์์ ์ธ ๊ถ์ฅ ์ฌํญ์ด ์๋๋๋ค. YMMV. ๐
"์ก์ ํฌ๋ฆฌ์์ดํฐ์์ ๋ ๋ง์ ์ผ์ ํ๊ณ ๋ฆฌ๋์์์ ๋ ์ ๊ฒ ์ํ"
์ ํ๋ฆฌ์ผ์ด์
์ด ์๋ฒ&ํด๋ผ์ด์ธํธ์ด๊ณ ์๋ฒ์ ๋น์ฆ๋์ค ๋ก์ง๊ณผ ์ ํจ์ฑ ๊ฒ์ฌ๊ธฐ๊ฐ ํฌํจ๋์ด์ผ ํ๋ ๊ฒฝ์ฐ์๋ ์ด๋ป๊ฒ ๋ฉ๋๊น?
๊ทธ๋์ ๋๋ ์ก์
์ ๊ทธ๋๋ก ๋ณด๋ด๊ณ ๋๋ถ๋ถ์ ์์
์ ์๋ฒ ์ธก์์ ๊ฐ์๊ธฐ์ ์ํด ์ํ๋ฉ๋๋ค ...
๋จผ์ , ๋ด ์์ด์ ๋ํด ์ฃ์กํฉ๋๋ค. ํ์ง๋ง ์ ๋ ์ฝ๊ฐ ๋ค๋ฅธ ์๊ฒฌ์ ๊ฐ์ง๊ณ ์์ต๋๋ค.
์ ์ ํ์ fat
๋ฆฌ๋์, thin
์ก์
ํฌ๋ฆฌ์์ดํฐ์
๋๋ค.
๋ด ์์ ์์ฑ์๋ ์ผ๋ถ __promise ๋ฏธ๋ค์จ์ด__๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ๋ __dispatch__ ์์ (๋น๋๊ธฐ, ๋๊ธฐํ, ์ง๋ ฌ ๋น๋๊ธฐ, ๋ณ๋ ฌ ๋น๋๊ธฐ, for ๋ฃจํ์ ๋ณ๋ ฌ ๋น๋๊ธฐ)์ ๋๋ค.
๋ด ๋ฆฌ๋์๋ ๋น์ฆ๋์ค ๋ก์ง์ ์ฒ๋ฆฌํ๊ธฐ ์ํด ๋ง์ ์์ ์ํ ์ฌ๋ผ์ด์ค๋ก ๋ถํ ๋ฉ๋๋ค. combineReduers
ํ์ฌ ๊ฒฐํฉํ์ญ์์ค. reducer
๋ __์์ ํจ์__์ด๋ฏ๋ก ์ฌ์ฌ์ฉํ๊ธฐ ์ฝ์ต๋๋ค. ์ธ์ ๊ฐ AngularJS๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ฉด ๋์ผํ ๋น์ฆ๋์ค ๋ก์ง์ ์ํด ๋ด ์๋น์ค์์ reducer
๋ฅผ ์ฌ์ฌ์ฉํ ์ ์์ ๊ฒ์
๋๋ค. reducer
์ ๋ผ์ธ ์ฝ๋๊ฐ ๋ง์ผ๋ฉด ๋ ์์ ๋ฆฌ๋์๋ก ๋ถํ ํ๊ฑฐ๋ ์ผ๋ถ ๊ธฐ๋ฅ์ ์ถ์ํํ ์ ์์ต๋๋ค.
์, A
๊ฐ B, C
์ ์์กดํ๊ณ B, C
๊ฐ ๋น๋๊ธฐ ๋ฐ์ดํฐ์์ ์๋ฏธํ๋ ๊ต์ฐจ ์ํ ์ฌ๋ก๊ฐ ์์ต๋๋ค. A๋ฅผ ์ฑ์ฐ๊ฑฐ๋ ์ด๊ธฐํํ๋ ค๋ฉด B,C
๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ๊ทธ๋์ crossSliceReducer
ํฉ๋๋ค.
__์ก์ ํฌ๋ฆฌ์์ดํฐ์์ ๋ ๋ง์ ์ผ์ ํ๊ณ ๋ฆฌ๋์์์ ๋ ์ ์ ์ผ์ ํ์ญ์์ค__.
redux-thunk
๋ฑ์ ์ฌ์ฉํ๋ค๋ฉด ๊ทธ๋ ์ต๋๋ค. getState()
์ก์
์์ฑ์ ๋ด์์ ์ ์ฒด ์ํ์ ์ก์ธ์คํ ์ ์์ต๋๋ค. ์ด๊ฒ์ ์ ํ์
๋๋ค. ๋๋ ์ผ๋ถ __crossSliceReducer__๋ฅผ ์์ฑํ์ฌ ์ ์ฒด ์ํ์๋ ์ก์ธ์คํ ์ ์๊ณ ์ผ๋ถ ์ํ ์ฌ๋ผ์ด์ค๋ฅผ ์ฌ์ฉํ์ฌ ๋ค๋ฅธ ์ํ๋ฅผ ๊ณ์ฐํ ์ ์์ต๋๋ค.__๋จ์ ํ ์คํธ__ ์ ๋ณด
reducer
๋ __์์ ํจ์__์
๋๋ค. ๊ทธ๋์ ํ
์คํธํ๊ธฐ ์ฝ์ต๋๋ค. ์ง๊ธ์ ๋ค๋ฅธ ๋ถ๋ถ๋ณด๋ค ๊ฐ์ฅ ์ค์ํ๊ธฐ ๋๋ฌธ์ ๊ฐ์๊ธฐ๋ฅผ ํ
์คํธํฉ๋๋ค.
action creators
๋ฅผ ํ
์คํธํ๋ ค๋ฉด? ๋๋ ๊ทธ๋ค์ด "๋ฑ๋ฑํ"๊ฒ์ด๋ผ๋ฉด ํ
์คํธํ๊ธฐ๊ฐ ์ฝ์ง ์์ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ํนํ __async ์ก์
์์ฑ์__.
@mrdulin์ ๋์ํฉ๋๋ค. ์ด์ ์ ๋ ๊ทธ๋ ๊ฒ ๋์์ต๋๋ค.
@mrdulin ๋ค. ๋ฏธ๋ค์จ์ด๊ฐ ๋ถ์ํ ๋
ผ๋ฆฌ๋ฅผ ๋ฐฐ์นํ๊ธฐ์ ์ ํฉํ ์ฅ์์ธ ๊ฒ ๊ฐ์ต๋๋ค.
๊ทธ๋ฌ๋ ๋น์ฆ๋์ค ๋
ผ๋ฆฌ ๊ฐ์๊ธฐ๋ ์ฌ๋ฐ๋ฅธ ์ฅ์์ฒ๋ผ ๋ณด์ด์ง ์์ต๋๋ค. ์ฌ์ฉ์๊ฐ ์์ฒญํ ๊ฒ์ด ์๋๋ผ ๋น์ฆ๋์ค ๋
ผ๋ฆฌ์ ํ์ํ ๊ฒ์ ๋ํ๋ด๋ ์ฌ๋ฌ "์ข
ํฉ์ ์ธ" ์์
์ผ๋ก ๋๋ฉ๋๋ค.
ํจ์ฌ ๋ ๊ฐ๋จํ ์ ํ์ ๋ฏธ๋ค์จ์ด์์ ์ผ๋ถ ์์ ํจ์/ํด๋์ค ๋ฉ์๋๋ฅผ ํธ์ถํ๋ ๊ฒ์ ๋๋ค.
middleware = (...) => {
// if(action.type == 'HIGH_LEVEL')
handlers[action.name]({ dispatch, params: action.payload })
}
const handlers = {
async highLevelAction({ dispatch, params }) {
dispatch({ loading: true });
const data = await api.getData(params.someId);
const processed = myPureLogic(data);
dispatch({ loading: false, data: processed });
}
}
@bvaughn
์ด๋ ๊ฒ ํ๋ฉด ๋ฏธ๋ฌํ๊ฒ ์ ์๋์ง ์์ ๊ฐ์ผ๋ก ์ด์ด์ง๋ ์๋ชป๋ ์ ํ์ ๋ณ์ ๊ฐ๋ฅ์ฑ์ด ์ค์ด๋ค๊ณ ์์ ๊ตฌ์กฐ ๋ฑ์ ๋ณ๊ฒฝ์ด ๊ฐ์ํ๋ฉ๋๋ค.
๋ฉ๋ชจ์ด์ ์ด์ ์ด๋ ์ด๋ค ์ข ๋ฅ์ ๋ฐ์ดํฐ ๋ณํ์ด ํ์ํ์ง ์์ ์ฌ์ํ ์ํ์ ๊ฒฝ์ฐ์๋ ๋ชจ๋ ๊ณณ์์ ์ ํ๊ธฐ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๋ฐ๋ํ๋ ์ ๊ฒฝ์ฐ:
state.stuff.item1
๋ฅผ state.stuff.item2
๋ณ๊ฒฝํ๋ฉด ์ฝ๋๋ฅผ ๊ฒ์ํ์ฌ ๋ชจ๋ ๊ณณ์์ ๋ณ๊ฒฝํฉ๋๋ค. ๋ง์น ๋ค๋ฅธ ์ด๋ฆ์ ์ค์ ๋ก ๋ณ๊ฒฝํ๋ ๊ฒ๊ณผ ๊ฐ์ต๋๋ค. ํนํ IDE๋ฅผ ์ฌ์ฉํ๋ ์ฌ๋๋ค์๊ฒ๋ ์ผ๋ฐ์ ์ธ ์์
์ด๋ฉฐ ์๊ฐํ ํ์๋ ์์ต๋๋ค.๋ถ๋ช ํ ์ ํ์๋ ํ์ํ์ง๋ง ํ์ API๋ก ๋ง๋ค๊ธฐ ์ํ ๋ช ๊ฐ์ง ๋ค๋ฅธ ์ฃผ์ฅ์ ๋ฃ๊ณ ์ถ์ต๋๋ค.
์ค์ฉ์ ์ธ ๊ด์ ์์ ๋ด ๊ฒฝํ์ ๋ฐ๋ฅด๋ฉด ์ข์ ์ด์ ์ค ํ๋๋ reselect ๋๋ redux-saga์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ ํ๊ธฐ๋ฅผ ํ์ฉํ์ฌ ์ํ ์กฐ๊ฐ์ ์ก์ธ์คํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ์ด๊ฒ์ ๋ด๊ฐ ์ ํ๊ธฐ๋ฅผ ์ฌ์ฉํ๊ธฐ์ ์ถฉ๋ถํฉ๋๋ค.
์ฒ ํ์ ์ผ๋ก ๋งํด์, ๋๋ ํญ์ ์ ํ์๋ฅผ ๊ธฐ๋ฅ์ ์ธ๊ณ์ "๊ฒํฐ ๋ฉ์๋"๋ก ๋ด ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ด๊ฐ Java ๊ฐ์ฒด์ public ์์ฑ์ ์ ๋ ์ ๊ทผํ์ง ์๋ ๊ฒ๊ณผ ๊ฐ์ ์ด์ ๋ก Redux ์ฑ์์ ์ง์ ํ์ ์ํ์ ์ ๊ทผํ์ง๋ ์์ ๊ฒ์ ๋๋ค.
@IceOnFire ๊ณ์ฐ์ด ๋น์ธ์ง ์๊ฑฐ๋ ๋ฐ์ดํฐ ๋ณํ์ด ํ์ํ์ง ์์ ๊ฒฝ์ฐ ํ์ฉํ ๊ฒ์ด ์์ต๋๋ค.
Getter ๋ฉ์๋๋ Java์์ ์ผ๋ฐ์ ์ธ ๊ดํ์ผ ์ ์์ง๋ง JS์์ ์ง์ POJO์ ์ก์ธ์คํ๋ ๊ฒ๋ ๋ง์ฐฌ๊ฐ์ง์ ๋๋ค.
@timotgl
์คํ ์ด์ ๋ค๋ฅธ redux ์ฝ๋ ์ฌ์ด์ API๊ฐ ์๋ ์ด์ ๋ ๋ฌด์์ธ๊ฐ์?
์ ํ์๋ ๋ฆฌ๋์์ ์ฟผ๋ฆฌ(์ฝ๊ธฐ) ๊ณต๊ฐ API์ด๊ณ , ์ก์ ์ ๋ฆฌ๋์์ ๋ช ๋ น(์ฐ๊ธฐ) ๊ณต๊ฐ API์ ๋๋ค. Reducer์ ๊ตฌ์กฐ๋ ๊ตฌํ ์ธ๋ถ ์ฌํญ์ ๋๋ค.
์ ํ๊ธฐ์ ์ก์ ์ ๋ฆฌ๋์ ์์ฒด๊ฐ ์๋๋ผ UI ๋ ์ด์ด์ ์ฌ๊ฐ ๋ ์ด์ด(redux-saga๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ)์์ ์ฌ์ฉ๋ฉ๋๋ค.
@sompylasar ์ฌ๊ธฐ์์ ๊ทํ์ ๊ด์ ์ ๋ฐ๋ฅด๋์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ์ก์ ์ ๋ํ ๋์์ ์์ต๋๋ค. redux์ ์ํธ ์์ฉํ๋ ค๋ฉด ์ก์ ์ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ๋๋ ๊ทธ๋ฅ์ผ๋ก ์ค๊ณ๋์ด ๋ ธ์ถ ๋ ์ํ์์ ์ง์ ๋ฌด์ธ๊ฐ๋ฅผ ์ ํํ ์ ์์ต๋๋ค, ๊ทธ๋ฌ๋ ์ ํ๊ธฐ๋ฅผ ์ฌ์ฉํ ํ์๊ฐ ์์ต๋๋ค.
์ ํ๊ธฐ๋ฅผ ๊ฐ์๊ธฐ์ "์ฝ๊ธฐ" API๋ก ์๊ฐํ๋ ๋ฐฉ๋ฒ์ ์ค๋ช ํ๊ณ ์์ง๋ง ์ ์ง๋ฌธ์ ์ ํ๊ธฐ๋ฅผ ์ฒ์์ ํ์ API๋ก ๋ง๋๋ ๊ฒ์ ์ ๋นํํ๋ ๊ฒ์ด์์ต๋๋ค(๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์๋ ํ๋ก์ ํธ์์ ๋ชจ๋ฒ ์ฌ๋ก๋ก ์ํํ ๋ ํ์์ ๋๋ค. ์ค๊ณ).
@timotgl ์, ์ ํ์๋ ํ์๊ฐ ์๋๋๋ค. ๊ทธ๋ฌ๋ ์ฑ ์ฝ๋์ ํฅํ ๋ณ๊ฒฝ ์ฌํญ์ ๋๋นํ์ฌ ๊ฐ๋ณ์ ์ผ๋ก ๋ฆฌํฉํ ๋งํ ์ ์๋๋ก ํ๋ ์ข์ ๋ฐฉ๋ฒ์ ๋๋ค.
์ ์ฅ์ ๊ตฌ์กฐ๋ฅผ ๋ณ๊ฒฝํ๋ ค๊ณ ํ ๋ ์ ํ๊ธฐ ์์ด ์ํฅ์ ๋ฐ๋ ์ํ ์กฐ๊ฐ์ ์ก์ธ์คํ๋ ๋ชจ๋ ์์น๋ฅผ ์ฐพ๊ณ ๋ฆฌํฉํฐ๋งํด์ผ ํ๋ฉฐ ์ด๋ ์ ์ฌ์ ์ผ๋ก ๋จ์ํ ์ฐพ๊ธฐ ๋ฐ-๊ฐ ์๋ ์ฌ์ํ ์์ ์ด ๋ ์ ์์ต๋๋ค. ํนํ ์ ํ๊ธฐ๋ฅผ ํตํ์ง ์๊ณ ์์ ์์ ์ง์ ์ป์ ์ํ ์กฐ๊ฐ์ ์ ๋ฌํ๋ ๊ฒฝ์ฐ ๊ต์ฒดํ์ญ์์ค.
@sompylasar ์ ๋ ฅ
์ด๊ฒ์ ์ ์ฌ์ ์ผ๋ก ์ฌ์ํ ์ผ์ด ๋ ์ ์์ต๋๋ค
๊ทธ๊ฒ์ ํ๋นํ ์ฐ๋ ค์ ๋๋ค. ์ ์๊ฒ๋ ๊ฐ๋น์ผ ์ ์ถฉ์์ฒ๋ผ ๋ณด์ ๋๋ค. ๊ทธ๋ฐ ๋ฌธ์ ๋ฅผ ์ผ์ผํจ ์ํ ๋ฆฌํฉํ ๋ง์ ๋ณธ ์ ์ด ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ๊ทธ๋ฌ๋ ๋๋ "์ ํ์ ์คํ๊ฒํฐ"๋ฅผ ์ ํ๋๋ฐ, ์ํ์ ๋ชจ๋ ์ฌ์ํ ํ์ ๋ถ๋ถ์ ๋ํ ์ค์ฒฉ ์ ํ์๊ฐ ์๋นํ ํผ๋์ ์ผ๊ธฐํ์ต๋๋ค. ์ด ๋์ฑ ์์ฒด๋ ๊ฒฐ๊ตญ ์ ์ง๋์ด์ผ ํฉ๋๋ค. ํ์ง๋ง ์ง๊ธ์ ๊ทธ ์ด์ ๋ฅผ ๋ ์ ์ดํดํ๊ณ ์์ต๋๋ค.
@timotgl ๊ณต๊ฐ์ ์ผ๋ก ๊ณต์ ํ ์ ์๋ ๊ฐ๋จํ ์:
export const PROMISE_REDUCER_STATE_IDLE = 'idle';
export const PROMISE_REDUCER_STATE_PENDING = 'pending';
export const PROMISE_REDUCER_STATE_SUCCESS = 'success';
export const PROMISE_REDUCER_STATE_ERROR = 'error';
export const PROMISE_REDUCER_STATES = [
PROMISE_REDUCER_STATE_IDLE,
PROMISE_REDUCER_STATE_PENDING,
PROMISE_REDUCER_STATE_SUCCESS,
PROMISE_REDUCER_STATE_ERROR,
];
export const PROMISE_REDUCER_ACTION_START = 'start';
export const PROMISE_REDUCER_ACTION_RESOLVE = 'resolve';
export const PROMISE_REDUCER_ACTION_REJECT = 'reject';
export const PROMISE_REDUCER_ACTION_RESET = 'reset';
const promiseInitialState = { state: PROMISE_REDUCER_STATE_IDLE, valueOrError: null };
export function promiseReducer(state = promiseInitialState, actionType, valueOrError) {
switch (actionType) {
case PROMISE_REDUCER_ACTION_START:
return { state: PROMISE_REDUCER_STATE_PENDING, valueOrError: null };
case PROMISE_REDUCER_ACTION_RESOLVE:
return { state: PROMISE_REDUCER_STATE_SUCCESS, valueOrError: valueOrError };
case PROMISE_REDUCER_ACTION_REJECT:
return { state: PROMISE_REDUCER_STATE_ERROR, valueOrError: valueOrError };
case PROMISE_REDUCER_ACTION_RESET:
return { ...promiseInitialState };
default:
return state;
}
}
export function extractPromiseStateEnum(promiseState = promiseInitialState) {
return promiseState.state;
}
export function extractPromiseStarted(promiseState = promiseInitialState) {
return (promiseState.state === PROMISE_REDUCER_STATE_PENDING);
}
export function extractPromiseSuccess(promiseState = promiseInitialState) {
return (promiseState.state === PROMISE_REDUCER_STATE_SUCCESS);
}
export function extractPromiseSuccessValue(promiseState = promiseInitialState) {
return (promiseState.state === PROMISE_REDUCER_STATE_SUCCESS ? promiseState.valueOrError || null : null);
}
export function extractPromiseError(promiseState = promiseInitialState) {
return (promiseState.state === PROMISE_REDUCER_STATE_ERROR ? promiseState.valueOrError || true : null);
}
์ ์ฅ๋๋ ๊ฒ์ด state, valueOrError
์ธ์ง ์๋๋ฉด ๋ค๋ฅธ ๊ฒ์ธ์ง๋ ์ด ๊ฐ์๊ธฐ ์ฌ์ฉ์์ ๊ด์ฌ์ฌ๊ฐ ์๋๋๋ค. ์ํ ๋ฌธ์์ด(์ด๊ฑฐํ), ํด๋น ์ํ์ ๋ํด ์์ฃผ ์ฌ์ฉ๋๋ ๋ช ๊ฐ์ง ๊ฒ์ฌ, ๊ฐ ๋ฐ ์ค๋ฅ๊ฐ ๋
ธ์ถ๋ฉ๋๋ค.
๊ทธ๋ฌ๋ ๋๋ "์ ํ์ ์คํ๊ฒํฐ"๋ฅผ ์ ํ๋๋ฐ, ์ํ์ ๋ชจ๋ ์ฌ์ํ ํ์ ๋ถ๋ถ์ ๋ํ ์ค์ฒฉ ์ ํ์๊ฐ ์๋นํ ํผ๋์ ์ผ๊ธฐํ์ต๋๋ค.
์ด ์ค์ฒฉ์ด ๋ฆฌ๋์ ์ค์ฒฉ(๊ตฌ์ฑ)์ ๋ฏธ๋ฌ๋งํ์ฌ ๋ฐ์ํ ๊ฒฝ์ฐ ๊ถ์ฅํ์ง ์๋ ๊ฒ์ ํด๋น ๊ฐ์๊ธฐ์ ๊ตฌํ ์ธ๋ถ์ ๋ณด์ ๋๋ค. ์์ ์๋ฅผ ์ฌ์ฉํ์ฌ ์ํ์ ์ผ๋ถ์ ๋ํด promiseReducer๋ฅผ ์ฌ์ฉํ๋ ๊ฐ์๊ธฐ๋ ์ด๋ฌํ ๋ถ๋ถ์ ๋ฐ๋ผ ๋ช ๋ช ๋ ์์ฒด ์ ํ๊ธฐ๋ฅผ ๋ด๋ณด๋ ๋๋ค. ๋ํ ์ ํ๊ธฐ์ฒ๋ผ ๋ณด์ด๋ ๋ชจ๋ ๊ธฐ๋ฅ์ ๋ด๋ณด๋ด๊ณ ๊ฐ์๊ธฐ API์ ์ผ๋ถ๊ฐ ๋์ด์ผ ํ๋ ๊ฒ์ ์๋๋๋ค.
function extractTransactionLogPromiseById(globalState, transactionId) {
return extractState(globalState).transactionLogPromisesById[transactionId] || undefined;
}
export function extractTransactionLogPromiseStateEnumByTransactionId(globalState, transactionId) {
return extractPromiseStateEnum(extractTransactionLogPromiseById(globalState, transactionId));
}
export function extractTransactionLogPromiseErrorTransactionId(globalState, transactionId) {
return extractPromiseError(extractTransactionLogPromiseById(globalState, transactionId));
}
export function extractTransactionLogByTransactionId(globalState, transactionId) {
return extractPromiseSuccessValue(extractTransactionLogPromiseById(globalState, transactionId));
}
์, ๋ด๊ฐ ๊ฑฐ์ ์์ด ๋ฒ๋ฆฐ ๋ ํ๋. ํจ์ ์ด๋ฆ๊ณผ ๋ด๋ณด๋ด๊ธฐ/๊ฐ์ ธ์ค๊ธฐ๋ ์๋๊ณ ์์ ํ๊ฒ ์ถ์๋ ์ ์์ต๋๋ค. ์ค์ฒฉ๋ ๊ฐ์ฒด ํค โ ๊ทธ๋ค์ง ๋ง์ง๋ ์์ง๋ง ์ฝ๋๋ฅผ ๋ง์น์ง ์์ผ๋ ค๋ฉด ์ถ์๊ธฐ์ ์ ์ ํ ๋ฐ์ดํฐ ํ๋ฆ ์ถ์ ๊ธฐ๊ฐ ํ์ํฉ๋๋ค.
@timotgl : Redux์ ๋ํด ๊ถ์ฅ๋๋ ๋ง์ ๋ชจ๋ฒ ์ฌ๋ก๋ Redux ๊ด๋ จ ๋ ผ๋ฆฌ ๋ฐ ๋์์ ์บก์ํํ๋ ค๋ ์๋์ ๊ดํ ๊ฒ์ ๋๋ค.
์๋ฅผ ๋ค์ด this.props.dispatch({type : "INCREMENT"})
๋ฅผ ์ํํ์ฌ ์ฐ๊ฒฐ๋ ๊ตฌ์ฑ ์์์์ ์ง์ ์์
์ ์ ๋ฌํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๊ตฌ์ฑ ์์๊ฐ Redux์ ํต์ ํ๊ณ ์์์ "์๊ฒ" ํ๊ธฐ ๋๋ฌธ์ ๊ถ์ฅํ์ง ์์ต๋๋ค. ๋ React ๊ด์ฉ์ ์ธ ๋ฐฉ๋ฒ์ ๋ฐ์ธ๋ฉ๋ ์์
์์ฑ์๋ฅผ ์ ๋ฌํ์ฌ ๊ตฌ์ฑ ์์๊ฐ this.props.increment()
ํธ์ถํ ์ ์๋๋ก ํ๊ณ ํด๋น ํจ์๊ฐ ๋ฐ์ธ๋ฉ๋ Redux ์์
์์ฑ์์ธ์ง ์ฌ๋ถ๋ ์ค์ํ์ง ์์ต๋๋ค. ์ฝ๋ฐฑ ์ ๋ฌ ๋ถ๋ชจ์ ์ํด ๋ค์ด๋๊ฑฐ๋ ํ
์คํธ์ ๋ชจ์ ํจ์.
๋ชจ๋ ๊ณณ์์ ์์ ์ ํ์ ์ง์ ์์ฑํ ์๋ ์์ง๋ง ์์ ๋ณ์๋ฅผ ์ ์ํ์ฌ ๊ฐ์ ธ์ค๊ณ ์ถ์ ํ๊ณ ์คํ ๊ฐ๋ฅ์ฑ์ ์ค์ผ ์ ์๋๋ก ํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
๋ง์ฐฌ๊ฐ์ง๋ก mapState
ํจ์ ๋๋ ์ฝํฌ์์ state.some.deeply.nested.field
์ ์ก์ธ์คํ๋ ๊ฒ์ ๋ฐฉํดํ๋ ๊ฒ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด ์ค๋ ๋์์ ์ด๋ฏธ ์ค๋ช
ํ๋ฏ์ด ์ด๋ ์คํ์ ๊ฐ๋ฅ์ฑ์ ๋์ด๊ณ ํน์ ์ํ๊ฐ ์ฌ์ฉ๋๋ ์์น๋ฅผ ์ถ์ ํ๊ธฐ ์ด๋ ต๊ฒ ๋ง๋ค๊ณ ๋ฆฌํฉํ ๋ง์ ๋ ์ด๋ ต๊ฒ ๋ง๋ค๊ณ ๊ฐ๋น์ผ ๋ณํ ๋
ผ๋ฆฌ๊ฐ - ํ์ํ์ง ์๋๋ผ๋ ๋งค๋ฒ ์คํํฉ๋๋ค.
๋ฐ๋ผ์ ์ ํ์๋ฅผ ์ฌ์ฉํ _๊ฐ์ง๊ณ ์์ง_๋ ์์ง๋ง ์ข์ ์ํคํ ์ฒ ๊ดํ์ ๋๋ค.
๋ด ๊ฒ์๋ฌผ Idiomatic Redux: Using Reselect Selectors for Encapsulation and Performance ๋ฅผ ์ฝ๊ณ ์ถ์ ์๋ ์์ต๋๋ค.
@markerikson ๋๋ ์ผ๋ฐ์ ์ผ๋ก ์ ํ๊ธฐ๋ ๊ฐ๋น์ผ ๊ณ์ฐ์ ์ํ ์ ํ๊ธฐ์ ๋ํด ๋ ผ์ํ์ง ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋๋ ๋์คํจ์น ์์ฒด๋ฅผ ๊ตฌ์ฑ ์์์ ์ ๋ฌํ ์๋๊ฐ ์์์ต๋๋ค. :)
๋ด ์์ ์ ๋ด๊ฐ ์ด ๋ฏฟ์์ ๋์ํ์ง ์๋๋ค๋ ๊ฒ์ ๋๋ค.
์ด์์ ์ผ๋ก๋ ๊ฐ์๊ธฐ ๊ธฐ๋ฅ๊ณผ ์ ํ๊ธฐ๋ง ์ ํํ ์ํ ๊ตฌ์กฐ๋ฅผ ์์์ผ ํ๋ฏ๋ก ์ผ๋ถ ์ํ๊ฐ ์๋ ์์น๋ฅผ ๋ณ๊ฒฝํ๋ ๊ฒฝ์ฐ ์ด ๋ ๊ฐ์ง ๋ ผ๋ฆฌ๋ง ์ ๋ฐ์ดํธํ๋ฉด ๋ฉ๋๋ค.
state.some.deeply.nested.field
๋ํ ๊ทํ์ ์์ ๋ํด, ๋๋ ์ด๊ฒ์ ์ค์ด๊ธฐ ์ํด ์ ํ๊ธฐ๋ฅผ ๊ฐ๋ ๊ฐ์น๋ฅผ ๋ณผ ์ ์์ต๋๋ค. selectSomeDeeplyNestedField()
๋ ํ๋์ ํจ์ ์ด๋ฆ๊ณผ ๋ด๊ฐ ์๋ชป ์๊ฐํ ์ ์๋ 5๊ฐ์ ์์ฑ์
๋๋ค.
๋ฐ๋ฉด์, ์ด ๊ฐ์ด๋๋ผ์ธ์ ํธ์ง์ ๋ฐ๋ฅธ๋ค๋ฉด const selectSomeField = state => state.some.field;
๋๋ const selectSomething = state => state.something;
๋๋ฉฐ ์ด๋ ์์ ์์ ์ด๋ฅผ ์ผ๊ด๋๊ฒ ์ํํ๋ ์ค๋ฒํค๋(๊ฐ์ ธ์ค๊ธฐ, ๋ด๋ณด๋ด๊ธฐ, ํ
์คํธ)๋ฅผ ํ๊ฒ ๋ฉ๋๋ค. ๋ด ์๊ฒฌ์ผ๋ก๋ ๋ ์ด์ (๋
ผ์์ ์ฌ์ง๊ฐ ์๋) ์์ ๊ณผ ์๊ฒฐ์ ์ ๋นํํ์ง ์์ต๋๋ค. ์ข์ ์ทจ์ง์ง๋ง ๊ฐ์ด๋๋ผ์ธ์ ๋
๋จ์ ์ธ ์ ์ ์ ๋จ์น ์ ์๋ค. ๋๋ ๋ด ํ๋ก์ ํธ์ ๊ฐ๋ฐ์๊ฐ ์ ํ๊ธฐ๋ฅผ ํ๋ช
ํ๊ฒ ์ฌ์ฉํ๊ณ ์ ์ฉํ ์ ์๋ค๊ณ ๋ฏฟ์ต๋๋ค. ์๋ํ๋ฉด ์ง๊ธ๊น์ง ๋ด ๊ฒฝํ์ด ๊ทธ๋ ๊ฒ ํ๊ธฐ ๋๋ฌธ์
๋๋ค.
ํน์ ์กฐ๊ฑด์์ ๋๋ ๋น์ ์ด ์ ์์ ๊ณผ ๊ด์ต์ ์ธก๋ฉด์์ ์ค์๋ฅผ ํ๊ณ ์ถ์ดํ๋์ง ์ ์ ์์์ต๋๋ค. ๊ทํ์ ์๊ฐ๊ณผ ์ฐธ์ฌ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค. redux๊ฐ ์์ด์ ์ ๋ฐ์ ์ผ๋ก ๋งค์ฐ ๊ธฐ์ฉ๋๋ค.
ํ์ ํ๋. FWIW์๋ ๋ค๋ฅธ ์ ํ๊ธฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ Reselect ์ฃผ๋ณ์ ๋ํผ ๋ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด https://github.com/planttheidea/selectorator๋ฅผ ์ฌ์ฉํ๋ฉด ์ ํ๊ธฐ๋ฒ ํค ๊ฒฝ๋ก๋ฅผ ์ ์ํ ์ ์์ผ๋ฉฐ ๋ด๋ถ์ ์ผ๋ก ์ค๊ฐ ์ ํ๊ธฐ๋ฅผ ์ํํฉ๋๋ค.
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
@dtinth @denis-sokolov ์ ๋ ๊ทธ ์ ์ ๋์ํฉ๋๋ค. Btw ๋ด๊ฐ redux-saga ํ๋ก์ ํธ๋ฅผ ์ฐธ์กฐํ ๋ ๋๋ actionCreators๋ฅผ ์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ ์ ์ ๋ ๋ณต์กํ๊ฒ ๋ง๋๋ ์์ด๋์ด์ ๋ฐ๋ํ๋ค๋ ๊ฒ์ ๋ถ๋ช ํ ํ์ง ์์์ ์ ์์ต๋๋ค.
Redux-saga ํ๋ก์ ํธ๋ @dtinth์์ ์ค๋ช ํ๋ ๊ฒ์ ์ํํ๋ ค๋ ์๋ ๋ฏธ๋ฌํ ์ฐจ์ด๊ฐ ์์ต๋๋ค. ์ก์ ๋ก๊ทธ์ ๋ฐ์ํ ๋ชจ๋ ์์ ์ด๋ฒคํธ๋ฅผ ์์ฑํ๋ฉด ์ด ์ก์ ๋ก๊ทธ์ ๋ฆฌ๋์์์ ๋ชจ๋ ์ํ๋ฅผ ์ฝ๊ฒ ๊ณ์ฐํ ์ ์๋ค๊ณ ๋งํ๊ณ ์ถ์ ๊ฒ ๊ฐ์ต๋๋ค. ์ด๊ฒ์ ์ ๋์ ์ผ๋ก ์ฌ์ค์ด๋ฉฐ ์์ ๋ก๊ทธ๊ฐ ๋ช ์์ ์ด์ง ์๊ณ ์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ ๊ฐ์๊ธฐ๊ฐ ๋๋ฌด ๋ณต์กํด์ ธ์ ์ฑ์ ์ ์ง ๊ด๋ฆฌํ๊ธฐ๊ฐ ๋งค์ฐ ์ด๋ ค์์ง ๋๊น์ง ํ๋์ ๊ทธ ๊ฒฝ๋ก๋ฅผ ํํ์ต๋๋ค.
Redux ์ฌ๊ฐ ํ ๋ก ์ผ๋ก ์ด์ด์ง๋ ์๋ ํ ๋ก ์ ์ด ์ง์ ์ ๋ณผ ์ ์์ต๋๋ค. https://github.com/paldepind/functional-frontend-architecture/issues/20#issuecomment -162822909
ํด๊ฒฐํ๋ ์ ์ค์ผ์ด์ค
๋ช ๋ฐฑํ TodoCreated ์ด๋ฒคํธ๊ฐ ์๋ Todo ์ฑ์ด ์๋ค๊ณ ์์ํด ๋ณด์ญ์์ค. ๊ทธ๋ฐ ๋ค์ ์ฑ ์จ๋ณด๋ฉ์ ์ฝ๋ฉํ๋๋ก ์์ฒญํฉ๋๋ค. ์ฌ์ฉ์๊ฐ ํ ์ผ์ ์์ฑํ๋ฉด ํ์ ์ผ๋ก ์ถํํด์ผ ํฉ๋๋ค.
"๋ถ์ํ" ๋ฐฉ๋ฒ:
์ด๊ฒ์ @bvaughn ์ด ์ ํธํ๋ ๊ฒ์ ๋๋ค.
๋๋ ์ด ์ ๊ทผ ๋ฐฉ์์ด ์ฑ ๋ณด๊ธฐ์ ๋ ์ด์์๊ณผ ๋ฐ์ ํ๊ฒ ๊ฒฐํฉ๋ ์ก์ ์์ฑ๊ธฐ๋ฅผ ๋ง๋ค๊ธฐ ๋๋ฌธ์ ๋ง์์ ๋ค์ง ์์ต๋๋ค. actionCreator๊ฐ ๊ฒฐ์ ์ ๋ด๋ฆฌ๊ธฐ ์ํด UI ์ํ ํธ๋ฆฌ์ ๊ตฌ์กฐ๋ฅผ ์์์ผ ํ๋ค๊ณ ๊ฐ์ ํฉ๋๋ค.
"์์ ์ด๋ฒคํธ์์ ๋ชจ๋ ๊ฒ์ ๊ณ์ฐ" ๋ฐฉ์:
์ด๊ฒ์ @denis-sokolov @dtinth ๊ฐ ์ ํธํ๋ ๊ฒ์ ๋๋ค:
์, ์ถํ ๋ฉ์์ง๋ฅผ ํ์ํด์ผ ํ๋์ง ์๋ ๊ฐ์๊ธฐ๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ํ์ ์ด ํ์๋์๋ค๋ ์กฐ์น๋ ์์ด ํ์๋๋ ํ์ ์ด ์์ต๋๋ค. ๋ด ์์ ์ ๊ฒฝํ์ ๋ฐ๋ฅด๋ฉด(๊ทธ๋ฆฌ๊ณ ์ฌ์ ํ ๊ทธ๋ ๊ฒ ํ๋ ๋ ๊ฑฐ์ ์ฝ๋๊ฐ ์์) ๋งค์ฐ ๋ช ์์ ์ผ๋ก ๋ง๋๋ ๊ฒ์ด ํญ์ ๋ ์ข์ต๋๋ค. DISPLAY_CONGRATULATION ์์ ์ด ์คํ๋์ง ์์ผ๋ฉด ์ถํ ํ์ ์ ํ์ํ์ง ๋ง์ญ์์ค. ๋ช ์์ ์ ์์์ ๋ณด๋ค ์ ์ง ๊ด๋ฆฌ๊ฐ ํจ์ฌ ์ฝ์ต๋๋ค.
๋จ์ํ๋ ์ฌ๊ฐ ๋ฐฉ์.
redux-saga๋ ์์ฑ๊ธฐ๋ฅผ ์ฌ์ฉํ๋ฉฐ ์ต์ํ์ง ์์ ๊ฒฝ์ฐ ์ฝ๊ฐ ๋ณต์กํด ๋ณด์ผ ์ ์์ง๋ง ๊ธฐ๋ณธ์ ์ผ๋ก ๋ค์๊ณผ ๊ฐ์ ๊ฐ๋จํ ๊ตฌํ์ ์ฌ์ฉํ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์์ฑํ ์ ์์ต๋๋ค.
saga๋ ์ด๋ฒคํธ๋ฅผ ์์ ํ๊ณ ํจ๊ณผ๋ฅผ ์์ฑํ ์ ์๋ ์ํ ์ ์ฅ ์กํฐ์ ๋๋ค. ์ฌ๊ธฐ์์ ์ด๊ฒ์ด ๋ฌด์์ธ์ง์ ๋ํ ์์ด๋์ด๋ฅผ ์ ๊ณตํ๊ธฐ ์ํด ๋ถ์ํ ๊ฐ์๊ธฐ๋ก ๊ตฌํ๋์ง๋ง ์ค์ ๋ก๋ redux-saga ํ๋ก์ ํธ์ ์์ต๋๋ค.
์ฝ๊ฐ ๋ณต์กํ ๊ท์น:
์ด๊ธฐ ๊ท์น์ ์ฒ๋ฆฌํ๋ฉด ๋ชจ๋ ๊ฒ์ ๋ํด ๋งค์ฐ ๋ช ์์ ์ด์ง ์์ต๋๋ค.
์์ ๊ตฌํ์ ๋ณด๋ฉด ์จ๋ณด๋ฉ ์ค์ ํ ์ผ์ ๋ง๋ค ๋๋ง๋ค ์ถํ ํ์ ์ด ์ด๋ฆฌ๋ ๊ฒ์ ์ ์ ์์ต๋๋ค. ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ์จ๋ณด๋ฉ ์ค์ ๋ฐ์ํ๋ ์ฒซ ๋ฒ์งธ ์์ฑ๋ ํ ์ผ์ ๋ํด์๋ง ์ด๋ฆฌ๊ธธ ์ํ๊ณ ๋ชจ๋ ํ ์ผ์ด ์๋๋ผ ์ด๋ฆฌ๊ธธ ์ํ ๊ฒ์ ๋๋ค. ๋ํ ์ฌ์ฉ์๊ฐ ๊ฒฐ๊ตญ ์ฒ์๋ถํฐ ์จ๋ณด๋ฉ์ ๋ค์ ํ ์ ์๋๋ก ํ๊ณ ์ถ์ต๋๋ค.
์จ๋ณด๋ฉ์ด ์ ์ ๋ ๋ณต์กํด์ง์ ๋ฐ๋ผ ์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ 3๊ฐ์ง ๊ตฌํ ๋ชจ๋์์ ์ฝ๋๊ฐ ์ด๋ป๊ฒ ์ง์ ๋ถํด์ก๋์ง ์ ์ ์์ต๋๊น?
redux-saga ๋ฐฉ์
redux-saga์ ์์ ์จ๋ณด๋ฉ ๊ท์น์ ์ฌ์ฉํ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์์ฑํ ์ ์์ต๋๋ค.
์์ ์๋ฃจ์ ๋ณด๋ค ํจ์ฌ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ผ๋ก ์ด ์ฌ์ฉ ์ฌ๋ก๋ฅผ ํด๊ฒฐํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ๋ด๊ฐ ํ๋ ธ๋ค๋ฉด ๋ ๊ฐ๋จํ ๊ตฌํ์ ์๋ ค์ฃผ์ญ์์ค. :)
๋น์ ์ ๋ถ์ํ ์ฝ๋์ ๋ํด ์ด์ผ๊ธฐํ๊ณ ์ด ๊ฒฝ์ฐ์๋ ํ ์ดํฌ/ํ ํจ๊ณผ๊ฐ ์ค์ ๋ก ๋ฐ์ดํฐ์ด๊ธฐ ๋๋ฌธ์ Redux-saga ๊ตฌํ์ ๋ถ์ํจ์ด ์์ต๋๋ค. take() ๊ฐ ํธ์ถ๋๋ฉด ์คํ๋์ง ์๊ณ ์คํํ ํจ๊ณผ์ ์ค๋ช ์๋ฅผ ๋ฐํํ๊ณ ์ด๋ ์์ ์์ ์ธํฐํ๋ฆฌํฐ๊ฐ ์์๋๋ฏ๋ก ๋ฌด์ฉ๋ด์ ํ ์คํธํ๊ธฐ ์ํด ๋ชจ์๊ฐ ํ์ํ์ง ์์ต๋๋ค. ๋น์ ์ด Haskell์ ํ๋ ๊ธฐ๋ฅ์ ์ธ ๊ฐ๋ฐ์๋ผ๋ฉด Free / IO ๋ชจ๋๋๋ฅผ ์๊ฐํ์ญ์์ค.
์ด ๊ฒฝ์ฐ ๋ค์์ ํ์ฉํฉ๋๋ค.
getState
์ ์์กดํ๊ฒ ๋ง๋์ญ์์ค.๋ํ ํด์ ๊ณ์ธต์ ์ ๊ณตํ์ฌ ์์ ์ด๋ฒคํธ๋ฅผ ๋ณด๋ค ์๋ฏธ ์๊ณ ๋์ ์์ค์ ์ด๋ฒคํธ๋ก ๋ณํํ ์ ์์ต๋๋ค(ELM์ด ์ด๋ฒคํธ๋ฅผ ๋ฒ๋ธ๋งํ ๋ ๋ํํ๋ ๊ฒ๊ณผ ์ฝ๊ฐ ์ ์ฌ).
์:
์ค๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ๋ชจ๋์ ์ฑ ๋ ์ด์์์ ๋ฌ์ฑํ๋ ค๋ ๊ฒฝ์ฐ ์ค๋ฆฌ๋ฅผ ํจ๊ป ๊ฒฐํฉํ๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์์ต๋๋ค. ์ฌ๊ฐ๋ ์ฐ๊ฒฐ์ ์ด ๋ฉ๋๋ค. ์ค๋ฆฌ๋ ์์ ์ด๋ฒคํธ๋ฅผ ์์์ผ ํ๊ณ ๋ฌด์ฉ๋ด์ ์ด๋ฌํ ์์ ์ด๋ฒคํธ๋ฅผ ํด์ํฉ๋๋ค. ์ด๊ฒ์ duck1 ํ๋ก์ ํธ๋ฅผ ๋ค๋ฅธ ์ปจํ ์คํธ์์ ๋ ์ฝ๊ฒ ์ฌ์ฌ์ฉํ ์ ์๋๋ก ํ๊ธฐ ๋๋ฌธ์ duck1์ด duck2์ ์ง์ ์์ ์ ๋์คํจ์นํ๋ ๊ฒ๋ณด๋ค ํจ์ฌ ๋ซ์ต๋๋ค. ๊ทธ๋ฌ๋ ๊ฒฐํฉ ์ง์ ์ด actionCreators์์๋ ๊ฐ๋ฅํ๋ค๊ณ ์ฃผ์ฅํ ์ ์์ผ๋ฉฐ ์ด๊ฒ์ด ์ค๋๋ ๋๋ถ๋ถ์ ์ฌ๋๋ค์ด ํ๊ณ ์๋ ์ผ์ ๋๋ค.