Share
Embed
次はたぶん挫折しないredux(react-redux社内勉強会資料)
react-reduxの社内勉強資料のうち、公開できる箇所を公開します。
スライド上では、課題の解説はあまりしていません。
課題の回答・解説は以下のレポジトリをご参照ください。
https://github.com/sadnessOjisan/todo_react
https://github.com/sadnessOjisan/react-brother-bothering-update-example
https://github.com/sadnessOjisan/redux-count-handson
https://github.com/sadnessOjisan/react-redux-count-handson
https://github.com/sadnessOjisan/react-redux-todo
sadnessOjisan
February 25, 2019
Transcript
118 slides
-
͜ͷߨ࠲ͷҐஔ͚ • 3FBDUߨ࠲ • ͳͥɺ3FBDU͕ඞཁʹͳͬͨͷ͔Λղઆ͢Δճ • ඇಉظॲཧߨ࠲ • $BMMCBDL 1SPNJTF
"TZOD "XBJUͰ"1*ͷ'FUDIΛؤுΔճ • ڥߏஙߨ࠲ • /1. #BCFM XFCQBDLͷઃఆΛղઆ͢Δճ • 3FEVYߨ࠲ • 3FBDUΛར༻ͨ͠େن։ൃߨ࠲ • 3FEVDFSͷׂNJEEMFXBSFͷ͍ํΛֶͿɻ 3 -
5BCMFPG$POUFOUT ͡Ίʹ ࠲ֶ3FEVYΛֶͿϞνϕʔγϣϯʹ͍ͭͯ B ͳͥ"JS3FBDUΛ࠾༻ͨ͠ͷ͔ͳͥࢲͨͪ3FBDU3FEVYΛֶͿͷ͔ C ͳͥ3FEVYΛֶͿͷ͔3FBDU୯ମͰར༻͢ΔͱԿ͕ਏ͘ͳΔͷ͔ D
3FEVYͰঢ়ଶΛཧ͢ΔͨΊʹΔ͖֓೦ ϋϯζΦϯ3FEVYͰΧϯτػೳΛ࡞Δ ϥϯν ࠲ֶ3FBDU͔Β3FEVYΛར༻͢ΔʹͲ͏͢Ε͍͍͔ B SFBDUSFEVYͰొ͢Δ֓೦ ϋϯζΦϯ3FBDU3FEVYͰΧϯτΞϓϦΛ࡞Δ ϋϯζΦϯ3FBDU3FEVYͰ5PEPΞϓϦΛ࡞Δ 5 -
ࣄલ४උ ࣄલʹ͍͑ͯ·͕ͨ͠ɺ͠४උ͕Ͱ͖͍ͯͳ͍ํɺͪ͜Βͷ४උ Λ͓ئ͍͠·͢ɻϋϯζΦϯ·Ͱʹ༻ҙ͍ͯͩ͘͠͞ɻ .VTU • (JU • (JU)VCͷΞΧϯτ(JUUFSͷϩάΠϯ #FUUFS •
74$PEF 'MPX-BOHVBHF4VQQPSUͷFYUFOTJPO 6 -
ར༻͢Διʔείʔυ 8 "QQ໊ 63- આ໌ UPEP@SFBDU IUUQTHJUIVCDPNTBEOFTT0KJTBOUPEP@ SFBDU લճͷϋϯζΦϯͰ։ൃͨ͠UPEPΞϓϦͷճ Ͱ͢ɻࠓ͜ΕΛSFEVYԽ͢Δ͜ͱ͕࠷
ऴඪͰ͢ɻ SFBDUCSPUIFSCPUIFSJOHVQEBUFFYBNQMF IUUQTHJUIVCDPNTBEOFTT0KJTBOSFBDU CSPUIFSCPUIFSJOHVQEBUFFYBNQMF ܑఋίϯϙʔωϯτΛSFEVYͳ͠Ͱߋ৽͢Δ ͱΊΜͲ͍͘͞ྫ SFEVYDPVOUIBOETPO IUUQTHJUIVCDPNTBEOFTT0KJTBOSFEVY DPVOUIBOETPO SFEVYͰ؆୯ͳঢ়ଶཧΛ͠·͢ʢΧϯ τʣ SFBDUSFEVYDPVOUIBOETPO IUUQTHJUIVCDPNTBEOFTT0KJTBOSFBDU SFEVYDPVOUIBOETPO SFEVYͰཧ͍ͯ͠ΔΧϯτTUBUFΛSFBDU ͔ΒΞΫηεɾߋ৽Ͱ͖ΔΑ͏ʹ͠·͢ɻ SFBDUSFEVYUPEP IUUQTHJUIVCDPNTBEOFTT0KJTBOSFBDU SFEVYUPEP UPEPϦετΛSFEVYԽͨ͠ͷ ͦΕͧΕɺܗ෦༷ &4%PD Λ/FUMJGZʹσϓϩΠ͍ͯ͠·͢ɻ ϦϯΫɺ֤ϨϙδτϦͷ3&"%.&ʹॻ͍ͯ͋Γ·͢ɻ -
SFBDUSFEVYͷͭ·͖ͮϙΠϯτ u ొਓ͕ଟ͍ u SFBDUSFEVYSFEVY͕ཁٻ͢Δ͕ؔɺͳͥඞཁʹͳΔ͔Θ͔Γʹ ͍͘ Ø FY ఆٛࣗମSFEVYͱ͕ؔͳ͍ͨͩͷؔͱͳΔͷ͕ଟ͍ u
最小限を動かすフェイズに至れなく、検証しながら壊しながら学ぶというこ とが難しい Ø "Λ࡞ΔͨΊʹ#͕ඞཁ͕ͩɺ#Λಈ͔ͨ͢Ίʹ"ͷϝιου͕ඞཁͩ 11 -
SFBDUSFEVYͲ͏ֶ͍͍͔ u SFEVYͱSFBDUSFEVYઈରʹֶ͚ͯͿ Ø SFEVYͱSFBDUSFEVYผͩΑʂ Ø SFEVY୯ମSFBDU͕ແͯ͘ಈ͘Αʂ u ·ͣ֓೦ͱ͍͔͚֮ͨͩ͑ͯ͠·͓͏ʂ u
ಈ͘͜ͱ͕֬͞Ε͍ͯΔαϯϓϧʢެࣜͳͲʣʹܕΛॻ͍ͯΈΔ Ø Ͳͷ͕ؔɺͲΜͳҾΛཁٻ͠ɺͲΜͳฦΓΛฦֶ͖͔͕͢Δ 12 -
ܕͷಡΈํ 15 u ܕมҾ͕ॴଐ͢Δάϧʔϓͷ͜ͱ Ͱ͢ɻ u IPHF ͰIPHFܕΛมҾʹએݴ͢Δ ͜ͱ͕Ͱ͖·͢ɻ u
DPOTU G BSHOVNCFS TUSJOH\^ ɺOVNCFSܕΛҾʹɺTUSJOHܕͷฦΓ GΛఆ͍ٛͯ͠·͢ɻ u ܕ͕͋ΕɺͲΜͳؔʹͲΜͳมΛ ͍͍͔͕ͤΘ͔ΔͷͰɺίʔυΛཧղ͠ ͘͢ͳΓ·͢ɻ カーソルを合わせると、型 の定義が表示されます。 型の上で「コマンドキー + クリック」すると 型の定義元にジャンプできます。 -
5BCMFPG$POUFOUT ͡Ίʹ ࠲ֶ3FEVYΛֶͿϞνϕʔγϣϯʹ͍ͭͯ B ͳͥ"JS3FBDUΛ࠾༻ͨ͠ͷ͔ͳͥࢲͨͪ3FBDU3FEVYΛֶͿͷ͔ C ͳͥ3FEVYΛֶͿͷ͔3FBDU୯ମͰར༻͢ΔͱԿ͕ਏ͘ͳΔͷ͔ D
3FEVYͰঢ়ଶΛཧ͢ΔͨΊʹΔ͖֓೦ ϋϯζΦϯ3FEVYͰΧϯτػೳΛ࡞Δ ϥϯν ࠲ֶ3FBDU͔Β3FEVYΛར༻͢ΔʹͲ͏͢Ε͍͍͔ B SFBDUSFEVYͰొ͢Δ֓೦ ϋϯζΦϯ3FBDU3FEVYͰΧϯτΞϓϦΛ࡞Δ ϋϯζΦϯ3FBDU3FEVYͰ5PEPΞϓϦΛ࡞Δ 16 -
ฐࣾΛऔΓר͘"QQ։ൃڥ 18 ػೳɾॊೈੑɾ։ൃʹର͢Δ ཁٻқ͕ߴ͘ͳ͍ͬͯΔ ͜Ε·Ͱͷ։ൃ ϝσΟΞ։ൃ اըಛू୯ҐͰͷػೳཁ݅ ʹ࣮ͳ։ൃ ίϯςϯπΛૌٻ͢ΔͨΊͷ ੩తͳ8FCϖʔδ
࠷ۙ૿͑ͭͭ͋Δ։ൃ 4BB4։ൃ ͍͢͞Λߟྀ͠ɺܭଌ͠ͳ͕ ΒΤϯϋϯεΛ܁Γฦ͢։ൃ ಈతͰߴػೳͰͨ͘͞Μͷঢ়ଶ ذΛ࣋ͬͨෳࡶͳ"QQ -
ͦ͜Ͱ3FBDUΛͬͨϑϩϯτΤϯυ։ൃ u 3FBDUͬͯͲΜͳϥΠϒϥϦʁ u 6*Λએݴతʹॻ͚Δʢ%FDMBUJWFʣ u UIを宣言すれば、状態やデータを勝手にレンダリングしてくれるよ! (React will efficiently
update and render just the right components when your data changes.) u 6*Λύʔπ͝ͱʹ࡞͍ͬͯ͘ $PNQPOFOU#BTFE u UIのパーツを作って、それを組み合わせてページを作るよ! (Build encapsulated components that manage their own state, then compose them to make complex UIs.) 20 G TUBUF 6*ͱͳΔੈքͰɺύʔπΛΈ߹Θͤͯ։ൃʂ -
3FBDUશͯΛղܾ͢Δۜͷؙ ͔͠Εͳ͍ u 6*Λએݴ͢Δ͜ͱͰɺࡶͳঢ়ଶߋ৽ɺঢ়ଶ͔Βͷ6*ੜΛߦΘͳ ͯ͘͢ΈɺιʔείʔυͷෳࡶੑΛݮΒ͢ u ίϯϙʔωϯτΛ࠶ར༻͢Δ͜ͱͰɺ։ൃΛݮΒͤΔ u ͞ΒʹίϯϙʔωϯτΛׂ͢Δ͜ͱͰۀ͘͢͠ɺೲظΛ ॖͰ͖Δ
21 3FBDUΛಋೖ͢Δ͜ͱͰɺ ෳࡶͳཁ݅Λγϯϓϧʹߴʹ։ൃͰ͖Δɾɾɾʁ -
TUBUFϋϯυϥͷόέπϦϨʔ 25 Root ίϯϙʔωϯτ AB2 ABB3 A1 D1 E1 DA2
DB2 TUBUF A1のstateをABB3に伝えたい -
TUBUFϋϯυϥͷόέπϦϨʔ 26 Root ίϯϙʔωϯτ AB2 ABB3 A1 D1 E1 DA2
DB2 TUBUF A1 A1 -
TUBUFϋϯυϥͷόέπϦϨʔ 27 Root ίϯϙʔωϯτ AB2 ABB3 A1 D1 E1 DA2
DB2 TUBUF まあまだ許容範囲 -
TUBUFϋϯυϥͷόέπϦϨʔ 28 Root ίϯϙʔωϯτ AB2 ABB3 A1 D1 E1 DA2
DB2 TUBUF ABB3のstateを、ABB3がクリックされ た時に、 E1のstateに応じて更新した い -
TUBUFϋϯυϥͷόέπϦϨʔ 29 Root ίϯϙʔωϯτ AB2 ABB3 A1 D1 E1 DA2
DB2 TUBUF &ͷTUBUFΛड͚औΔͨΊͷؔ'Λఆٛ -
TUBUFϋϯυϥͷόέπϦϨʔ 30 Root ίϯϙʔωϯτ AB2 ABB3 A1 D1 E1 DA2
DB2 TUBUF &ͷTUBUFΛड͚औΔͨΊͷؔ'Λఆٛ 'Λ࣮ߦ͠ɺ&ͷ TUBUFΛϧʔτʹ͑Δ E1 -
TUBUFϋϯυϥͷόέπϦϨʔ 31 Root ίϯϙʔωϯτ AB2 ABB3 A1 D1 E1 DA2
DB2 TUBUF &ͷTUBUFΛड͚औΔͨΊͷؔ'Λఆٛ 'Λ࣮ߦ͠ɺ&ͷ TUBUFΛϧʔτʹ͑Δ E1 E1 E1 E1 -
TUBUFϋϯυϥͷόέπϦϨʔ 33 Root ίϯϙʔωϯτ AB2 ABB3 A1 D1 E1 DA2
DB2 TUBUF &ͷTUBUFΛड͚औΔͨΊͷؔ'Λఆٛ 'Λ࣮ߦ͠ɺ&ͷ TUBUFΛϧʔτʹ͑Δ E1 E1 E1 E1 なかなかめんどくさい -
ղܾࡦ u TUBUFΛSPPUίϯϙʔωϯτ͚͕ͩ࣋ͪɺTUBUFͱͦΕΛߋ৽͢Δϋ ϯυϥΛࢠڙίϯϙʔωϯτʹ͢ 38 ϝϦοτ • ࢠ͔ΒʹϋϯυϥΛ͢Θ͠͞ Λશʹͳͤ͘Δ σϝϦοτ
• ίϯϙʔωϯτ͕ΊͪΌͪ͘Όେ͖͘ ͳͬͯ͠·͍ɺཧ͕େมͦ͏ • όέπϦϨʔͷํ౷ҰͰ͖Δ͕ɺό έπϦϨʔࣗମͳ͘ͳ͍ͬͯͳ͍ • ίϯϙʔωϯτͷπϦʔࣗମ͕มΘΔͱɺ मਖ਼͕ࠔ -
SFEVYͰঢ়ଶΛߋ৽͢Δྫ 44 const redux = require("redux"); const initialState = {
count: 0 }; const reducer = (state = initialState, action) => { switch (action.type) { case "COUNT_UP": return { ...state, count: state.count + 1 }; default: return; } }; const store = redux.createStore(reducer); store.dispatch({ type: "COUNT_UP" }); -
SFEVYͰঢ়ଶΛߋ৽͢Δྫ 45 const redux = require("redux"); const initialState = {
count: 0 }; const reducer = (state = initialState, action) => { switch (action.type) { case "COUNT_UP": return { ...state, count: state.count + 1 }; default: return; } }; const store = redux.createStore(reducer); store.dispatch({ type: "COUNT_UP" }); Count数を状態として扱うことを宣言する -
SFEVYͰঢ়ଶΛߋ৽͢Δྫ 46 const redux = require("redux"); const initialState = {
count: 0 }; const reducer = (state = initialState, action) => { switch (action.type) { case "COUNT_UP": return { ...state, count: state.count + 1 }; default: return; } }; const store = redux.createStore(reducer); store.dispatch({ type: "COUNT_UP" }); どういうときに、どういう風に状態を更新 するかを定義する。 -
SFEVYͰঢ়ଶΛߋ৽͢Δྫ 47 const redux = require("redux"); const initialState = {
count: 0 }; const reducer = (state = initialState, action) => { switch (action.type) { case "COUNT_UP": return { ...state, count: state.count + 1 }; default: return; } }; const store = redux.createStore(reducer); store.dispatch({ type: "COUNT_UP" }); COUNT_UP という命令が来たら、カウント をアップすることを定義する -
SFEVYͰঢ়ଶΛߋ৽͢Δྫ 48 const redux = require("redux"); const initialState = {
count: 0 }; const reducer = (state = initialState, action) => { switch (action.type) { case "COUNT_UP": return { ...state, count: state.count + 1 }; default: return; } }; const store = redux.createStore(reducer); store.dispatch({ type: "COUNT_UP" }); 上で作った状態と状態更新ルールを持っ た状態管理オブジェクトを作る -
SFEVYͰঢ়ଶΛߋ৽͢Δྫ 49 const redux = require("redux"); const initialState = {
count: 0 }; const reducer = (state = initialState, action) => { switch (action.type) { case "COUNT_UP": return { ...state, count: state.count + 1 }; default: return; } }; const store = redux.createStore(reducer); store.dispatch({ type: "COUNT_UP" }); 状態を保つオブジェクトに対して、状態更 新の命令を送る -
TUPSF།Ұͷঢ়ଶͷอॴ u ΞϓϦέʔγϣϯͰ།Ұͷঢ়ଶཧॴ u 3FEVYʹ શͯͷঢ়ଶΛTUPSFͷΈ͕ཧ͢Δ ͱ͍͏ݪଇ͕͋Δ u ޙड़͢ΔSFEVDFSΛҾʹɺDSFBUF4UPSF ͱ͍͏ϝιουΛ࣮ߦ͢
Δ͜ͱͰ࡞Δ͜ͱ͕Ͱ͖Δ 51 const store = redux.createStore(reducer); -
SFEVDFSTUPSFΛߋ৽͢Δؔ 53 const reducer = (state = initialState, action) =>
{ switch (action.type) { case ”HOGE": return { ...state, message: ‘パンケーキ’ }; case ”FUGA": return { ...state, message: ‘シフォンケーキ’ }; case "RESET": return initialState; default: return; } }; {type: “HOGE”}を受け取ると、新しいstate として{message: ‘パンケーキを返す’} -
SFEVDFSTUPSFΛߋ৽͢Δؔ 54 const reducer = (state = initialState, action) =>
{ switch (action.type) { case ”HOGE": return { ...state, message: ‘パンケーキ’ }; case ”FUGA": return { ...state, message: ‘シフォンケーキ’ }; case "RESET": return initialState; default: return; } }; {type: “FUGA”}を受け取ると、新しいstate として{message: ‘シフォンケーキ’}を返す -
BDUJPOߋ৽༰ʹ͍ͭͯͷϝοηʔδ u TUPSFʹରͯ͠ɺͲͷΑ͏ͳมߋΛͯ͠΄͍͔͠ॻ͔Εͨϝοηʔδ u \UZQFTUSJOH QBZMPBE NJYFE^ܗࣜͷͨͩͷΦϒδΣΫτ u UZQF༷ʑͳΞΫγϣϯͷࣝผࢠɺQBZMPBEߋ৽ͯ͠΄͍͠σʔ λɻUZQFඞਢ͕ͩɺQBZMPBEͳͯ͘ྑ͍ɻ
UZQFQBZMPBEͱ ͍͏Ωʔ໊׳श u store.dispatch(action) ΛݺͿͱɺSFEVDFS͕࣮ߦ͞ΕΔ ʮBDUJPOΛEJTQBUDI͢Δʯͱදݱ͞ΕΔ ɻͦͷ݁ՌɺBDUJPOΛݩʹ TUPSFΛߋ৽͢Δ͜ͱ͕Ͱ͖Δɻ 55 -
5BCMFPG$POUFOUT ͡Ίʹ ࠲ֶ3FEVYΛֶͿϞνϕʔγϣϯʹ͍ͭͯ B ͳͥ"JS3FBDUΛ࠾༻ͨ͠ͷ͔ͳͥࢲͨͪ3FBDU3FEVYΛֶͿͷ͔ C ͳͥ3FEVYΛֶͿͷ͔3FBDU୯ମͰར༻͢ΔͱԿ͕ਏ͘ͳΔͷ͔ D
3FEVYͰঢ়ଶΛཧ͢ΔͨΊʹΔ͖֓೦ ϋϯζΦϯ3FEVYͰΧϯτػೳΛ࡞Δ ϥϯν ࠲ֶ3FBDU͔Β3FEVYΛར༻͢ΔʹͲ͏͢Ε͍͍͔ B SFBDUSFEVYͰొ͢Δ֓೦ ϋϯζΦϯ3FBDU3FEVYͰΧϯτΞϓϦΛ࡞Δ ϋϯζΦϯ3FBDU3FEVYͰ5PEPΞϓϦΛ࡞Δ 56 -
͑ • SFEVDFSʹ$06/5@%08/ͱ 3&4&5Λఆٛ • ͦΕͧΕɺͨ͋͠ͱͷTUBUF JOJUJBM4UBUFΛฦͯ͋͛͠Δ • $06/5@%08/ͱ3&4&5Λ
TUPSFEJTQBUDIͯ͋͛͠Δ 61 const redux = require("redux"); const initialState = { count: 0 }; const reducer = (state = initialState, action) => { switch (action.type) { case "COUNT_UP": return { ...state, count: state.count + 1 }; case "COUNT_DOWN": return { ...state, count: state.count - 1 }; case "RESET": return initialState; default: return; } }; const store = redux.createStore(reducer); store.dispatch({ type: "COUNT_UP" }); console.log("1回COUNT_UPしてみた結果: ", store.getState()); store.dispatch({ type: "COUNT_DOWN" }); store.dispatch({ type: "COUNT_DOWN" }); console.log("2回COUNT_DOWNしてみた結果: ", store.getState()); store.dispatch({ type: "RESET" }); console.log("RESETしてみた結果: ", store.getState()); 回答URL) https://github.com/sadnessOjisan/redux-count-handson -
ղ 62 "QQ໊ 63- આ໌ UPEP@SFBDU IUUQTHJUIVCDPNTBEOFTT0KJTBOUPEP@ SFBDU લճͷϋϯζΦϯͰ։ൃͨ͠UPEPΞϓϦͷճ Ͱ͢ɻࠓ͜ΕΛSFEVYԽ͢Δ͜ͱ͕࠷
ऴඪͰ͢ɻ SFBDUCSPUIFSCPUIFSJOHVQEBUFFYBNQMF IUUQTHJUIVCDPNTBEOFTT0KJTBOSFBDU CSPUIFSCPUIFSJOHVQEBUFFYBNQMF ܑఋίϯϙʔωϯτΛSFEVYͳ͠Ͱߋ৽͢Δ ͱΊΜͲ͍͘͞ྫ SFEVYDPVOUIBOETPO IUUQTHJUIVCDPNTBEOFTT0KJTBOSFEVY DPVOUIBOETPO SFEVYͰ؆୯ͳঢ়ଶཧΛ͠·͢ʢΧϯ τʣ SFBDUSFEVYDPVOUIBOETPO IUUQTHJUIVCDPNTBEOFTT0KJTBOSFBDU SFEVYDPVOUIBOETPO SFEVYͰཧ͍ͯ͠ΔΧϯτTUBUFΛSFBDU ͔ΒΞΫηεɾߋ৽Ͱ͖ΔΑ͏ʹ͠·͢ɻ SFBDUSFEVYUPEP IUUQTHJUIVCDPNTBEOFTT0KJTBOSFBDU SFEVYUPEP UPEPϦετΛSFEVYԽͨ͠ͷ ͦΕͧΕɺܗ෦༷ &4%PD Λ/FUMJGZʹσϓϩΠ͍ͯ͠·͢ɻ ϦϯΫɺ֤ϨϙδτϦͷ3&"%.&ʹॻ͍ͯ͋Γ·͢ɻ -
5BCMFPG$POUFOUT ͡Ίʹ ࠲ֶ3FEVYΛֶͿϞνϕʔγϣϯʹ͍ͭͯ B ͳͥ"JS3FBDUΛ࠾༻ͨ͠ͷ͔ͳͥࢲͨͪ3FBDU3FEVYΛֶͿͷ͔ C ͳͥ3FEVYΛֶͿͷ͔3FBDU୯ମͰར༻͢ΔͱԿ͕ਏ͘ͳΔͷ͔ D
3FEVYͰঢ়ଶΛཧ͢ΔͨΊʹΔ͖֓೦ ϋϯζΦϯ3FEVYͰΧϯτػೳΛ࡞Δ ϥϯν ࠲ֶ3FBDU͔Β3FEVYΛར༻͢ΔʹͲ͏͢Ε͍͍͔ B SFBDUSFEVYͰొ͢Δ֓೦ ϋϯζΦϯ3FBDU3FEVYͰΧϯτΞϓϦΛ࡞Δ ϋϯζΦϯ3FBDU3FEVYͰ5PEPΞϓϦΛ࡞Δ 64 -
SFBDUSFEVY u Official React bindings for Redux. (https://react-redux.js.org/introduction/quick-start) u コンポーネントから
redux の store を参照したり、action を dispatch するこ とを可能にするライブラリ u react + redux を実現するために必要なライブラリ 66 -
SFBDUSFEVY͕ʂਓʑΛ࠳ંͤ͞Δʂʂʂ 70 人 畜 無 害 そ う な 顔
を し て い る が 数 え 切 れ な い ほ ど の 人 間 を 挫 折 さ せ て い る -
SFBDUSFEVYͷ͠͞ u Reactとreduxの接続方法が少なくとも4通りある。特にdispatcherのつなぎ こみが混乱しやすい。 u そもそも、登場人物が多い! u provider, connect, mapStateToProps,
mapDispatchToProps, dispatch, … u しかし、react-reduxが提供している関数は、providerとconnectのみである 71 えっ、残りの登場人物はどこから登場してきたの? -
SFBDUSFEVYͷ͠͞ u 登場人物が多い! u provider, connect, mapStateToProps, mapDispatchToProps, dispatch, bindActionCreators,
… u しかし、react-reduxが提供している関数は、providerとconnectのみである 72 えっ、残りの登場人物はどこから登場してきたの? ͋ͳ͕ͨ࡞ΔͷͰ͢ -
SFBDUSFEVYͷొਓΛཧ͢Δ SFBDUSFEVY • QSPWJEFSSFEVYͷTUPSFΛಡΈࠐΊΔΑ͏ʹͯ͘͠ΕΔ • DPOOFDUDPNQPOFOUͱTUPSFΛܨ͛ͯ͘ΕΔ ࣗ࡞ • BDUJPO$SFBUPSݺͼग़͢͜ͱͰɺBDUJPOΛ࡞ͬͯฦͯ͘͠ΕΔؔ •
NBQ4UBUF5P1SPQTTUPSFͷTUBUF͔ΒಡΈࠐΉΛબ͢Δ • NBQ%JTQBUDI5P1SPQTTUPSFʹର͢ΔEJTQBUDIFSΛબ͢Δ 73 -
QSPWJEFS u <provider />で囲ったコンポーネント以下では、reduxのstoreにアクセスで きるようになる u 通常、アプリケーションのトップレベルで利用される。 79 ReactDOM.render( <Provider
store={store}> <TodoView /> </Provider>, document.getElementById("root") ); -
DPOOFDU u 任意のReactコンポーネントをreduxのstoreと接続するために利用する関数 80 class Component extends React.Component { }
// Component -> Reactコンポーネント const ConnectedComponent = connect()(Component) // ConnectedComponent -> redux storeと接続されたコンポーネント -
DPOOFDU u connect関数は4つの引数を取ることができる • mapStateToProps?: Function • mapDispatchToProps?: Function |
Object • mergeProps?: Function • options?: Object u connect関数は、コンポーネントを引数に取る関数を返す u connect()が返した関数はコンポーネントを引数に取り、storeにアクセスできるコンポー ネントを作って返してくれるよ! 81 「?」はなくても良いという意味. Maybe Types. Ex) function f1(name:string, age? number) は、 関数f1はstring型 のnameが必要で、number型のageは必要というわけではない あまり使うことはないです。 すくなくとも今は考えなくても良いですー。 -
BDUJPO$SFBUPS u BDUJPOΛ࡞Δؔ u ͜Ε·Ͱɺstore.dispatch({type: ”SAMPLE_ACTION”})ͳͲͱఆٛͯ͠ ͍͕ͨɺຖճBDUJPOΦϒδΣΫτΛखͰ࡞Δͷେม͡Όͳ͍Ͱ͔͢ʁ u ίϯϙʔωϯτ͔Β؆୯ʹΞΫγϣϯ࡞ΛͰ͖ΔΑ͏ʹ͢ΔͨΊʹɺBDUJPOΛ ฦؔ͢ఆٛͨ͠ํ͕ྑ͍ɻ
ݺͿ͚ͩͰBDUJPO͕࡞Δ͜ͱ͕Ͱ͖ΔΑ͏ʹͳΔ 83 const checkUser = (userId) => { return { type: CHECK_USER, payload: id }; }; -
NBQ4UBUF5P1SPQT u DPOOFDUͷୈҰҾ NBQ4UBUF5P1SPQTͱݺΕ͍ͯΔɻ u ͜ΕɺҰൠతʹɺ const mapStateToProps = state
=> ({ hoge: state.fuga, … }) ͱ͍͏ܗͷؔ u ίϯϙʔωϯτͰɺTUPSFͷͲͷΛಡΈऔΓ͍͔ͨΛબ͢Δػ ೳʢTFMFDUPSͱݺΕΔ͜ͱʣɻTUBUFΛTUPSFͱߟ͑Δͱཧղ͠ ͍͢ 84 -
NBQ%JTQBUDI5P1SPQT u connectの第二引数。mapDispatchToPropsと呼ばれている u 一般的には、 const mapDispatchToProps = dispatch =>
{ return {hoge: dispatch(hogeActionCreator())} } と定義される u action creatorを渡すことで、どのactionをdispatchさせるかを定義する 85 dispatchは、ただの引数の名前 -
DPOOFDUΛਂ۷Δ TUPSFͱͷଓΛઃఆ͢Δؔʢલʣͱɺ࣮ࡍʹTUPSFͱଓ ͯ͘͠ΕΔؔʢޙʣʹ͚ͯߟ͑Δͱཧղ͍͢͠Αʂ DPOOFDU NBQ4UBUF5P1SPQT NBQ%JTQBUDI5P1SPQT $PNQPOFOU 4UPSFͷͲͷ෦Λ͏͔ɺͲΜͳΞΫγϣϯΛ ͍͍͔ͨઃఆ͢Δ
3FEVYͱͷଓͷઃఆΛɺίϯϙʔωϯτ ʹөͤ͞Δॲཧ f()() という書き方は、なにかの設定をしてあげ、 その設定を反映させるみたいなことをしたいとき に、よくあるテクニックです。なんか変な呼び出し 方だよね。 -
ΫΠζ 87 class Component extends React.Component{ constructor(){ console.log(this.props); } }
const mapStateToProps = state => { return { hoge: state.hoge, fuga: state.fuga } } const mapDispatchToProps = dispatch => { return { foo: dispatch(foo()) } } export default connect(mapStateToProps)(Component) このコンポーネントはどんな propsが入っているでしょう! -
ΫΠζ 88 class Component extends React.Component{ constructor(){ console.log(this.props); } }
const mapStateToProps = state => { return { hoge: state.hoge, fuga: state.fuga } } const mapDispatchToProps = dispatch => { return { foo: dispatch(foo()) } } export default connect(mapStateToProps,mapDispatchToProps)(Component) このコンポーネントはどんな propsが入っているでしょう! -
ΫΠζ 89 class Component extends React.Component{ constructor(){ console.log(this.props); } }
const mapStateToProps = state => { return { hoge: state.hoge, fuga: state.fuga } } const mapDispatchToProps = dispatch => { return { foo: dispatch(foo()) } } export default connect(null,mapDispatchToProps)(Component) このコンポーネントはどんな propsが入っているでしょう! -
͍͠ΫΠζ̐ 90 class Component extends React.Component{ constructor(){ console.log(this.props); } }
const mapStateToProps = state => { return { hoge: state.hoge, fuga: state.fuga } } const mapDispatchToProps = dispatch => { return { foo: dispatch(foo()) } } export default connect()(Component) このコンポーネントはどんな propsが入っているでしょう! -
SFBDUSFEVY͕ʂਓʑΛ࠳ંͤ͞Δʂʂʂ 92 人 畜 無 害 そ う な 顔
を し て い る が 数 え 切 れ な い ほ ど の 人 間 を 挫 折 さ せ て い る -
SFBDUSFEVY͕ʂਓʑΛ࠳ંͤ͞Δʂʂʂ 93 人 畜 無 害 そ う な 顔
を し て い る が 数 え 切 れ な い ほ ど の 人 間 を 挫 折 さ せ て い る -
5BCMFPG$POUFOUT ͡Ίʹ ࠲ֶ3FEVYΛֶͿϞνϕʔγϣϯʹ͍ͭͯ B ͳͥ"JS3FBDUΛ࠾༻ͨ͠ͷ͔ͳͥࢲͨͪ3FBDU3FEVYΛֶͿͷ͔ C ͳͥ3FEVYΛֶͿͷ͔3FBDU୯ମͰར༻͢ΔͱԿ͕ਏ͘ͳΔͷ͔ D
3FEVYͰঢ়ଶΛཧ͢ΔͨΊʹΔ͖֓೦ ϋϯζΦϯ3FEVYͰΧϯτػೳΛ࡞Δ ϥϯν ࠲ֶ3FBDU͔Β3FEVYΛར༻͢ΔʹͲ͏͢Ε͍͍͔ B SFBDUSFEVYͰొ͢Δ֓೦ ϋϯζΦϯ3FBDU3FEVYͰΧϯτΞϓϦΛ࡞Δ ϋϯζΦϯ3FBDU3FEVYͰ5PEPΞϓϦΛ࡞Δ 94 -
͑ • DPVOUΛTUPSFʹఆٛ • SFEVDFSʹCOUNT_UPͱ COUNT_DOWNのcaseΛఆٛ • ͦΕͧΕʹରԠͨ͠ BDUJPO$SFBUPSΛFYQPSU͢Δ 99
回答URL) https://github.com/sadnessOjisan/react-redux-count-handson const countUp = (): TCountUpAction => { return { type: COUNT_UP }; }; const countDown = (): TCountDownAction => { return { type: COUNT_DOWN}; }; export const actionCreators = { countUp, countDown }; const initialState = { count: 0 }; // reducer const reducer = (state: TState = initialState, action: TAction) => { switch (action.type) { case COUNT_UP: return { ...state, count: state.count + 1 }; case COUNT_DOWN: return { ...state, count: state.count - 1 }; default: return initialState; } }; -
͑ • TUPSFͷΧϯτΛಡΈࠐΉͨΊͷؔ NBQ4UBUF5P1SPQTΛఆٛ • DPVOUͷૢ࡞ΛQSPQT͔ΒͰ͖ΔΑ͏ʹ ͢ΔؔNBQ%JTQBUDI5P1SPQTΛఆٛ • DPOOFDUʹNBQ4UBUF5P1SPQTͱ NBQ%JTQBUDI5P1SPQTΛͯ͠ɺίϯ
ϙʔωϯτͷத͔ΒTUBUFͱEJTQBUDIFS ʹΞΫηεͰ͖ΔΑ͏ʹͯ͋͛͠Δ 100 回答URL) https://github.com/sadnessOjisan/react-redux-count-handson const mapStateToProps = (state: TStore) => { return { count: state.count }; }; const mapDispatchToProps = (dispatch: Dispatch<*>) => { return { countUp: ()=>dispatch(countUp()), countDown: ()=>dispatch(countDown()) }; }; export default connect( mapStateToProps, mapDispatchToProps )(Counter); -
ղ 101 "QQ໊ 63- આ໌ UPEP@SFBDU IUUQTHJUIVCDPNTBEOFTT0KJTBOUPEP@ SFBDU લճͷϋϯζΦϯͰ։ൃͨ͠UPEPΞϓϦͷճ Ͱ͢ɻࠓ͜ΕΛSFEVYԽ͢Δ͜ͱ͕࠷
ऴඪͰ͢ɻ SFBDUCSPUIFSCPUIFSJOHVQEBUFFYBNQMF IUUQTHJUIVCDPNTBEOFTT0KJTBOSFBDU CSPUIFSCPUIFSJOHVQEBUFFYBNQMF ܑఋίϯϙʔωϯτΛSFEVYͳ͠Ͱߋ৽͢Δ ͱΊΜͲ͍͘͞ྫ SFEVYDPVOUIBOETPO IUUQTHJUIVCDPNTBEOFTT0KJTBOSFEVY DPVOUIBOETPO SFEVYͰ؆୯ͳঢ়ଶཧΛ͠·͢ʢΧϯ τʣ SFBDUSFEVYDPVOUIBOETPO IUUQTHJUIVCDPNTBEOFTT0KJTBOSFBDU SFEVYDPVOUIBOETPO SFEVYͰཧ͍ͯ͠ΔΧϯτTUBUFΛSFBDU ͔ΒΞΫηεɾߋ৽Ͱ͖ΔΑ͏ʹ͠·͢ɻ SFBDUSFEVYUPEP IUUQTHJUIVCDPNTBEOFTT0KJTBOSFBDU SFEVYUPEP UPEPϦετΛSFEVYԽͨ͠ͷ ͦΕͧΕɺܗ෦༷ &4%PD Λ/FUMJGZʹσϓϩΠ͍ͯ͠·͢ɻ ϦϯΫɺ֤ϨϙδτϦͷ3&"%.&ʹॻ͍ͯ͋Γ·͢ɻ -
5BCMFPGDPOUFOUT ͡Ίʹ ࠲ֶSFEVYΛֶͿϞνϕʔγϣϯʹ͍ͭͯ B ͳͥBJSSFBDUΛ࠾༻ͨ͠ͷ͔ͳͥࢲͨͪSFBDUSFEVYΛֶͿͷ͔ C ͳͥSFEVYΛֶͿͷ͔SFBDU୯ମͰར༻͢ΔͱԿ͕ਏ͘ͳΔͷ͔ D
SFEVYͰঢ়ଶΛཧ͢ΔͨΊʹΔ͖֓೦ ϋϯζΦϯSFEVYͰΧϯτػೳΛ࡞Δ ϥϯν ࠲ֶSFBDU͔ΒSFEVYΛར༻͢ΔʹͲ͏͢Ε͍͍͔ B SFBDUSFEVYͰొ͢Δ֓೦ ϋϯζΦϯSFBDUSFEVYͰΧϯτΞϓϦΛ࡞Δ ϋϯζΦϯSFBDUSFEVYͰUPEPΞϓϦΛ࡞Δ 102 -
ਐΊํ u Ҏલ࡞ͨ͠ɺSFBDUUPEPཧΞϓϦΛSFEVYԽͯ͠Β͍·͢ɻ u ϨϕϧΛͭ༻ҙ͓ͯ͠Γ·͢ u -WSFBDUΞϓϦέʔγϣϯ͔Βͷελʔτ u -WOQN JOJU͔Βશਅͬനελʔτ
106 https://github.com/sadnessOjisan/react-redux-todo https://github.com/sadnessOjisan/todo_react -
ղ 108 "QQ໊ 63- આ໌ UPEP@SFBDU IUUQTHJUIVCDPNTBEOFTT0KJTBOUPEP@ SFBDU લճͷϋϯζΦϯͰ։ൃͨ͠UPEPΞϓϦͷճ Ͱ͢ɻࠓ͜ΕΛSFEVYԽ͢Δ͜ͱ͕࠷
ऴඪͰ͢ɻ SFBDUCSPUIFSCPUIFSJOHVQEBUFFYBNQMF IUUQTHJUIVCDPNTBEOFTT0KJTBOSFBDU CSPUIFSCPUIFSJOHVQEBUFFYBNQMF ܑఋίϯϙʔωϯτΛSFEVYͳ͠Ͱߋ৽͢Δ ͱΊΜͲ͍͘͞ྫ SFEVYDPVOUIBOETPO IUUQTHJUIVCDPNTBEOFTT0KJTBOSFEVY DPVOUIBOETPO SFEVYͰ؆୯ͳঢ়ଶཧΛ͠·͢ʢΧϯ τʣ SFBDUSFEVYDPVOUIBOETPO IUUQTHJUIVCDPNTBEOFTT0KJTBOSFBDU SFEVYDPVOUIBOETPO SFEVYͰཧ͍ͯ͠ΔΧϯτTUBUFΛSFBDU ͔ΒΞΫηεɾߋ৽Ͱ͖ΔΑ͏ʹ͠·͢ɻ SFBDUSFEVYUPEP IUUQTHJUIVCDPNTBEOFTT0KJTBOSFBDU SFEVYUPEP UPEPϦετΛSFEVYԽͨ͠ͷ ͦΕͧΕɺܗ෦༷ &4%PD Λ/FUMJGZʹσϓϩΠ͍ͯ͠·͢ɻ ϦϯΫɺ֤ϨϙδτϦͷ3&"%.&ʹॻ͍ͯ͋Γ·͢ɻ -
͓ർΕ༷Ͱͨ͠ u SFEVYʹঢ়ଶΛҕৡ͠ɺSFBDUੈքͰ6*ʹؔ͢Δϓϩάϥϛϯάʹઐ ೦Ͱ͖ΔΑ͏ʹͳΓ·ͨ͠ɻ u ࠓͬͯΒͬͨ͜ͱ࣮Ͱ͓͜ͳ͏࡞ۀͱɺ࣮͋·ΓมΘ Γ͋Γ·ͤΜɻ u ࣮ͱͷࠩઃܭ ෭࡞༻ཧ
SFEVDFSͷׂ $44ͷهड़͘Β͍ u ࠷ޙʹ෮शͱ࣍ճ༧ࠂ͚ͩͯ͠ɺऴ͑·͠ΐ͏ʂ 110 -
SFEVYSFBDUSFEVYΛ͏خ͠͞ u TJOHMFTUPSFͰ͋ΔͨΊɺΞϓϦέʔγϣϯͷঢ়ଶΛҰՕॴͰཧ Ͱ͖Δ u ͭ·ΓɺG TUBUF 6*͕ G TUPSF
6*ͱͳΔ u SFEVYʹଓͨ͠ DPNQPOFOUɺͲ͔͜ΒͰ BDUJPO$SFBUPS Λ ݺͿ͜ͱͰ TUPSFΛߋ৽͢Δ͜ͱ͕Ͱ͖Δ 114 -
SFEVYͲͷΑ͏ʹͯ͠͏͔ u TUBUFͱ BDUJPOΛड͚औͬͯ৽͍͠ TUBUFΛฦؔ͢ SFEVDFSΛ ఆٛ͢Δ u SFEVDFS͔Β TUPSFΛ࡞Δ
u TUPSF͔Β BDUJPOΛ EJTQBUDIͯ͠ SFEVDFSΛಈ͔ͯ͠ TUPSFΛ ߋ৽͢Δ 115 -
開催方式 • 講義はしません • 課題を解いて来てもらいます • 自習がメインになります • keyword: redux-logger,
redux-saga, react-router, combineReducer 117