æ®å¿µãªããããããã®ã©ã€ãã©ãªã¯ãã¹ãŠãäž»èŠãªåé¡ã§ããèšèªèæ§ã®ãµããŒãã®æ¬ åŠã解決ããŠããŸããã ããšãã°ã
update-in
ã¯çŸããClojureScriptã³ã³ã¹ãã©ã¯ãã§ãããJavaScriptã§å®è£ ãããåæ§ã®ã¢ã€ãã¢ã¯ãäž»ã«äžäŸ¿ãªæååãã¹ã«äŸåããŸãã ãã®ã¢ãããŒãã¯ãšã©ãŒãèµ·ããããããåãã§ãã¯ãè€éã«ããç¹å¥ãªAPIã®èª¿æ»ãå¿ èŠã§ãã
JavaScriptã®ã€ãã¥ããã£åé¡ã解決ããæ¹æ³ã¯ïŒ ããããã代ããã«ãã®æ©èœãå©çšããŠãèšèªãšã®æŠãããããã¹ãã§ãã ãã®ã¢ãããŒãã«ãããæšæºã®ããŒã¿æ§é ãæäŸãã䟿å©ããšåçŽãã倱ããªãããã«ã§ããŸãã å®éã®ãšãããä»æ¥ã話ãããæ²¡å ¥åã©ã€ãã©ãªã¯ãäžå€ã®ç¶æ ã§äœæ¥ãããšãã«æšæºã®JSããŒã«ã䜿çšããããšãç®çãšããŠããŸãã
ãããã¥ãŒãµãŒ
液浞ã®å®éã®äœ¿çšã¯ãçç£è ã®äœæã«åºã¥ããŠããŸãã éåžžã«ã·ã³ãã«ãªãããã¥ãŒãµãŒã¯æ¬¡ã®ããã«ãªããŸãã
import produce from "immer" const nextState = produce(currentState, draft => { // }) console.log(nextState === currentState) // true
ãã®ç©ºã®ãããã¥ãŒãµãŒã解決ããå¯äžã®ã¿ã¹ã¯ã¯ãåæç¶æ ãè¿ãããšã§ãã
produce
é¢æ°ã¯2ã€ã®åŒæ°ãåããŸãã ããã¯ã
currentState
ãçŸåšã®ç¶æ ãããã³ãããã¥ãŒãµãŒé¢æ°ã§ãã çŸåšã®ç¶æ ã¯éå§äœçœ®ã§ããããããã¥ãŒãµãŒã¯çŸåšã®ç¶æ ã«å¯ŸããŠè¡ãå¿ èŠã®ããå€æŽãè¡šçŸããŸãã
ãããã¥ãŒãµãŒé¢æ°ã¯ã
draft
ãšãã1ã€ã®åŒæ°ãåããŸããããã¯ãå°æ¥ã®ç¶æ ã®ãã©ããã®ãããªãã®ã§ãæž¡ãããçŸåšã®ç¶æ ã®ãããã·ãªããžã§ã¯ãã§ãã
draft
ãžã®å€æŽã¯èšé²ãããæ°ããç¶æ ã®äœæã«äœ¿çšãããŸãã çŸåšã®ç¶æ
currentState
ããã®ããã»ã¹äžã«å€æŽãããããšã¯ãããŸããã
äžèšã®äŸã§ã¯ãimmerã¯å ±éã®ããŒã¿æ§é ã䜿çšãããããã¥ãŒãµãŒã¯äœãå€æŽããªãããã次ã®ç¶æ ã¯ã
produce
é¢æ°ã®å ¥åã§åä¿¡ããç¶æ ãšåãã«ãªããŸãã
次ã«ããããã¥ãŒãµãŒã§
draft
ãªããžã§ã¯ããå€æŽããå Žåã«äœãèµ·ããããèŠãŠã¿ãŸãããã ãããã¥ãŒãµãŒé¢æ°ã¯äœãè¿ããªãããšã«æ³šæããŠãã ããã圹å²ãæããã®ã¯ããã®äžã§è¡ãããå€æŽã ãã§ãã
import produce from "immer" const todos = [ /* 2 todo */ ] const nextTodos = produce(todos, draft => { draft.push({ text: "learn immer", done: true }) draft[1].done = true }) // console.log(todos.length) // 2 console.log(todos[1].done) // false // , draft console.log(nextTodos.length) // 3 console.log(nextTodos[1].done) // true // console.log(todos === nextTodos) // false console.log(todos[0] === nextTodos[0]) // true console.log(todos[1] === nextTodos[1]) // false
ããã§ã¯ãå®éã®ãããã¥ãŒãµãŒã®äŸãèŠãããšãã§ããŸãã
draft
ãžã®ãã¹ãŠã®å€æŽã¯æ°ããç¶æ ã«åæ ããã以åã®ç¶æ ãšãšãã«äžå€èŠçŽ ã䜿çšããŸãã
ããã§ã
produce
æ©èœã®åäœã確èªã§ããŸãã 1ã€ã®è¿œå ã®
todo
èŠçŽ ãå«ãæ°ããç¶æ ããªãŒãäœæããŸããã ããã«ã2çªç®ã®èŠçŽ ãå€æŽãããŸããã ãããã¯
draft
ãªããžã§ã¯ãã«å ããããå€æŽã§ãããçµæã®ç¶æ ã«åæ ãããŸãã
ãã ããããã ãã§ã¯ãããŸããã ãªã¹ãã®æåŸã®è¡šçŸã¯ã
draft
å€æŽãããç¶æ ã®éšåãæ°ãããªããžã§ã¯ãã«ãªã£ãããšãå®éã«ç€ºããŠããŸãã ãã ããæ°ããç¶æ ãšåã®ç¶æ ã®äžå€éšåã¯äžç·ã«äœ¿çšãããŸãã ãã®å Žåããããæåã®
todo
èŠçŽ ã§ãã
ã¬ãã¥ãŒãµãŒãšãããã¥ãŒãµãŒ
ãããã¥ãŒãµãŒã®å©ããåããŠæ°ããç¶æ ãäœæããåºæ¬ãåŠç¿ããã®ã§ããã®ç¥èã䜿çšããŠå žåçãªReduxã¬ãã¥ãŒãµãŒãäœæããŸãã 次ã®äŸã¯å ¬åŒã®ã·ã§ããã³ã°ã«ãŒãã®äŸã«åºã¥ããŠãããïŒããããïŒæ°è£œåã«é¢ããæ å ±ãå·ã«ããŒãããŸãã 補åæ å ±ã¯ã
reduce
ã䜿çšããŠå€æãããé åã®åœ¢åŒã§æäŸããã
ID
ãããŒãšããŠäœ¿çšããŠã³ã¬ã¯ã·ã§ã³ã«ä¿åãããŸãã 以äžã¯ã³ãŒãã®ç°¡ç¥çã§ã ãå®å šçã¯ãã¡ãã«ãããŸã ã
const byId = (state, action) => { switch (action.type) { case RECEIVE_PRODUCTS: return { ...state, ...action.products.reduce((obj, product) => { obj[product.id] = product return obj }, {}) } default: return state } }
ããã§ããã®å®å šã«éåžžã®Reduxã¬ãã¥ãŒãµãŒã§ã¯ãæåã«ãåºæ¬ç¶æ ãä¿åãããæ°ãã補åã®ã³ã¬ã¯ã·ã§ã³ãè¿œå ãããæ°ããç¶æ ãªããžã§ã¯ããæ§ç¯ããå¿ èŠããããŸãã ãã®åçŽãªã±ãŒã¹ã§ã¯ãããã¯ããã»ã©æªãã¯ãããŸãããããã®ããã»ã¹ã¯ã¢ã¯ã·ã§ã³ããšã«ããŸãäœããå€æŽããå¿ èŠãããåã¬ãã«ã§ç¹°ãè¿ãå¿ èŠããããŸãã 第äºã«ãããã§ã¯ããªãã¥ãŒãµãŒãç¶æ ã«å€æŽãå ããŠããªãå Žåãæ¢åã®ç¶æ ã®æ»ããä¿èšŒããå¿ èŠããããŸãã
èšè¿°ãããç¶æ³ã§immerã䜿çšãããå Žåãè¡ãå¿ èŠãããå¯äžã®æ±ºå®ã¯ãçŸåšã®ç¶æ ã«å¯ŸããŠè¡ãå¿ èŠãããå€æŽã§ãã æ°ããç¶æ ãäœæããããã«è¿œå ã®äœæ¥ã¯å¿ èŠãããŸããã ãã®çµæããªãã¥ãŒãµãŒã§
produce
é¢æ°ã䜿çšãããšã次ã®ã³ãŒãã«ãªããŸãã
const byId = (state, action) => produce(state, draft => { switch (action.type) { case RECEIVE_PRODUCTS: action.products.forEach(product => { draft[product.id] = product }) break } })
æ²¡å ¥æ©èœã䜿çšããã¬ãã¥ãŒãµãŒã®ç°¡ç¥åã以äžã«ç€ºããŸãã
RECEIVE_PRODUCTS
圹å²ãç解ããããšãã©ãã»ã©ç°¡åãã«æ³šæããŠãã ããã æ å ±ãã€ãºã®ã¿ãè¿œå ããã³ãŒãã¯æé€ãããŸãã ãŸããããã§ã¯ããã©ã«ãã®ã¢ã¯ã·ã§ã³ãåŠçããŠããªãããšã«æ³šæããŠãã ããã
draft
ãªããžã§ã¯ããå€æŽãããŠããªãå Žåãããã¯åºæ¬ç¶æ ã«æ»ãããšãšåçã§ãã å ã®ã¬ãã¥ãŒãµãŒãšæ°ããã¬ãã¥ãŒãµãŒã®äž¡æ¹ããŸã£ããåãã¢ã¯ã·ã§ã³ãå®è¡ããŸãã
immerã䜿çšããªãæååèå¥åã«ã€ããŠ
äžæçãªãç²ãããªããžã§ã¯ããå€æŽããŠæ¬¡ã®äžå€ã®ç¶æ ãçæãããšããèãæ¹ã¯æ°ãããã®ã§ã¯ãããŸããã ããšãã°ãImmutableJSã«ã¯åæ§ã®ã¡ã«ããºã ïŒ withMutationsïŒããããŸãã ãã ãã液浞ã®å€§ããªå©ç¹ã¯ããã®ã©ã€ãã©ãªã䜿çšããããã«ããŒã¿æ§é ã®ãŸã£ããæ°ããã©ã€ãã©ãªãåŠç¿ïŒãŸãã¯ããŒãïŒããå¿ èŠããªãããšã§ãã Immerã¯ãéåžžã®JavaScriptãªããžã§ã¯ããšé åã§åäœããŸãã
æ²¡å ¥æã®åŒ·ãã¯ããã ãã§ã¯ãããŸããã ãã€ã©ãŒãã¬ãŒãã³ãŒããæžããããã«ãImmutableJSããã³ãã®ä»ã®å€ãã®ã©ã€ãã©ãªã䜿çšããŠãç¹å¥ãªæ¹æ³ã䜿çšããŠè©³çŽ°ãªæŽæ°ïŒããã³ãã®ä»ã®å€ãã®æäœïŒãè¡šçŸã§ããŸãã ãã ããããã§ã¯éåžžã®æååèå¥åã䜿çšãããŠãããããåãã§ãã¯ã·ã¹ãã ãæ©èœããŸããã ãã®ã¢ãããŒãã¯ãšã©ãŒã®åå ã§ãã ããšãã°ã次ã®ãªã¹ãã§ã¯ãImmutableJSã䜿çšããŠ
list
ã¿ã€ããæšæž¬ããããšã¯ã§ããŸããã ä»ã®ã©ã€ãã©ãªã¯åæ§ã®ã¡ã«ããºã ãæ¡åŒµããããè€éãªã³ãã³ããå®è¡ã§ããããã«ããŸãã ããããã¹ãŠã®æ©èœã®äŸ¡æ Œã¯ãæ¢åã®ããã°ã©ãã³ã°èšèªã§ç¹å¥ãªããèšèªãäœæããããšã§ãã ImmutableJSãšimmerã®æ©èœã䜿çšããã³ãŒãã®äŸã次ã«ç€ºããŸãã
// ImmutableJS const newMap = map.updateIn(['inMap', 'inList'], list => list.push(4)) // Immer draft.inMap.inList.push(4)
ããã§ã¯ãã€ããŒã ã§ã®äœæ¥äžã«ã詳现æŽæ°äžã«ã¿ã€ãæ å ±ã倱ãããªãæ¹æ³ã瀺ããŸãã ã芧ã®ãšãããimmerã¯åã®åé¡ã«æ©ãŸãããŠããŸããã ãã®ã©ã€ãã©ãªã¯ãçµã¿èŸŒã¿ã®JavaScriptããŒã¿æ§é ã§åäœããããŒã¿ã®å€æŽã¯æšæºã®ã¡ã«ããºã ã䜿çšããŠå®è¡ãããŸãã ããã¯ãã¹ãŠã®ã¿ã€ããã§ãã¯ã·ã¹ãã ã«ãã£ãŠå®å šã«èªèãããŸãã
ãªããžã§ã¯ãã®èªååçµ
æ²¡å ¥ã®ãã1ã€ã®åªããæ©èœã¯ããã®ã©ã€ãã©ãªã ã
produce
é¢æ°ã䜿çšã
produce
äœæãããããŒã¿æ§é ãèªåçã«ããªãŒãº
produce
ããšã§ãã ïŒéçºã¢ãŒãã§ïŒã ãã®çµæãããŒã¿ã¯æ¬åœã«äžå€ã«ãªããŸãã ãã€ã±ã«ãã£ã©ãŒã¯åœŒã®ãã€ãŒãã§ããã«ã€ããŠæžããŠããŸãã ç¶æ å šäœãããªãŒãºããã®ã¯éåžžã«å€ãã®ãªãœãŒã¹ãæ¶è²»ããæé ã§ãããimmerãå€æŽãããéšåãããªãŒãºã§ãããšããäºå®ã«ããããã®ã©ã€ãã©ãªã¯éåžžã«å¹ççã§ãã ãããŠãç¶æ å šäœã
produce
é¢æ°ã䜿çšã
produce
ååŸãããå Žåãæçµçµæã¯ç¶æ å šäœãåžžã«åçµãããããšã§ãã ã€ãŸããäœããã®æ¹æ³ã§å€æŽããããšãããšäŸå€ãçºçããŸãã
ã«ã¬ãŒ
ããããæåŸã®æ²¡å ¥æ©èœã§ãã ãããŸã§ã¯ã
baseState
ãš
baseState
é¢æ°ãšãã2ã€ã®åŒæ°ã䜿çšããŠåžžã«
baseState
é¢æ°ãåŒã³åºããŸããã ãã ããå Žåã«ãã£ãŠã¯ãé¢æ°ã®éšåçãªé©çšã®ã¡ã«ããºã ã䜿çšãããšäŸ¿å©ãªå ŽåããããŸãã ãã®ã¢ãããŒãã䜿çšãããšãproduceré¢æ°ãåŒã³åºããŠãproduceré¢æ°ã®ã¿ãæž¡ãããšãã§ããŸãã ããã«ãããç¶æ ãæž¡ããããšãã«ãããã¥ãŒãµãŒãå®è¡ããæ°ããé¢æ°ãäœæãããŸãã ããã«ããã®ãããªé¢æ°ã¯ãä»»æã®æ°ã®è¿œå ã®åŒæ°ãåãããããããããã¥ãŒãµãŒã«æž¡ããŸãã
ããã§æãéèŠãªããšã¯ãã«ãªãŒåã«ããã¬ãã¥ãŒãµãŒã®ãã³ãã¬ãŒãã³ãŒããããã«åæžã§ããããšã§ãã
const byId = produce((draft, action) => { switch (action.type) { case RECEIVE_PRODUCTS: action.products.forEach(product => { draft[product.id] = product }) break } })
ã«ã¬ãŒçç£è ã¯ããã«ç€ºãããŠããŸãã ãã®ã³ãŒããããããç解ããããã«ãåã®äŸã®1ã€ãèŠãŠãã ããã
äžè¬çã«ãããã§ã¯æ²¡å ¥ã®äž»ãªæ©èœããã¹ãŠèª¿ã¹ãŸããã ãã®ã©ã€ãã©ãªã䜿ãå§ããã«ã¯ããã§ååã§ãã 次ã«ããã®ã©ã€ãã©ãªã®å éšã¡ã«ããºã ã«ã€ããŠèª¬æããŸãã
浞挬宀å æ©
Immerã¯2ã€ã®æŠå¿µã«åºã¥ããŠããŸãã 1ã€ç®ã¯é²é³äžã®ã³ããŒã§ãã 2ã€ç®ã¯ãããã·ãªããžã§ã¯ãã§ãã ããã説æããŸãã
çŸåšã®ç¶æ ããããã·ãªããžã§ã¯ããããã³å€æŽããããããã·ãªããžã§ã¯ã
ç·ã®æšã¯åæç¶æ ã®æšã§ãã ç·ã®æšã®äžéšã®åã«éããã¬ãŒã ãããããšã«æ°ä»ããããããŸããã ãããã¯ãããã·ãªããžã§ã¯ããšåŒã°ããŸãã ãããã¥ãŒãµãŒãäœæ¥ãéå§ããåœåããã®ãããªãããã·ã¯1ã€ãããããŸããã ããã¯ãé¢æ°ã«æž¡ããã
draft
ãªããžã§ã¯ãã§ãã ãã®æåã®ãããã·ããéããªããã£ãå€ãèªã¿åããšããã®å€ã®ãããã·ãäœæãããŸãã ã€ãŸããæçµçã«ã¯ãããã·ããªãŒããããããã¯åºæ¬ç¶æ ã®ãã·ã£ããŠã³ããŒãã®ãããªãã®ã§ãã ãããã¯ããããã¥ãŒãµãŒã«ãã£ãŠã¢ã¯ã»ã¹ãããç¶æ ã®äžéšã§ãã
ãããã·ã®å éšææ決å®ã¡ã«ããºã ã èŠæ±ã¯ãããŒã¹ããªãŒãŸãã¯ããŒã¹ããªãŒã®ã¯ããŒã³ããŒãã®ããããã«åããããŸãã
ããã§ããããã·ã§äœããïŒçŽæ¥ããŸãã¯ä»»æã®APIãä»ããŠïŒå€æŽããããšãããšããã«ãåç §å ã®ãœãŒã¹ããªãŒã«ããŒãã®å°ããªã³ããŒãããã«äœæ
modified
ã
modified
ãã©ã°ãèšå®
modified
ãŸãã ãã以éããã®ãããã·ã«åããããåŸç¶ã®èªã¿åãããã³æžã蟌ã¿æäœã¯ããœãŒã¹ããªãŒã§ã¯ãªãããã®ã³ããŒã«ã€ãªãããŸãã ããã«ããŸã å€æŽãããŠããªã芪ãªããžã§ã¯ãã¯ã
modified
ãšããŠããŒã¯ã
modified
ãŸãã
ãããã¥ãŒãµãŒãæçµçã«äœæ¥ãçµäºãããšãåã«ãããã·ããªãŒããã€ãã¹ãããããã·ãå€æŽãããå Žåãã³ããŒãååŸããŸãã ãŸãã¯ããããã·ãå€æŽãããŠããªãå Žåãåã«ãœãŒã¹ããŒããè¿ããŸãã ãã®ããã»ã¹ã«ããã以åã®ç¶æ ãšå ±éã®éšåãæã€ç¶æ ããªãŒã衚瀺ãããŸãã
ãããã·ãªããžã§ã¯ããªãã®æµžæŒ¬
ãããã·ãªããžã§ã¯ãã¯ãææ°ã®ãã¹ãŠã®ãã©ãŠã¶ãŒã§äœ¿çšã§ããŸãã ãããããããã¯ãŸã ã©ãã«ããããŸããã æãé¡èãªäŸå€ã¯ãMicrosoft Internet ExplorerãšAndroidçšã®React Nativeã§ãã Immerã«ã¯ããã®ãããªç°å¢ã§åäœããããã®ã¡ã«ããºã ã®ES5å®è£ ããããŸãã å®éã®ã¢ããªã±ãŒã·ã§ã³ã®èŠ³ç¹ããã¯ãããã¯åãã§ãããåäœãå°ãé ããªããŸãã ãããã®ã¡ã«ããºã
import produce from "immer/es5"
ã®
import produce from "immer/es5"
ã䜿çšããŠé©çšã§ããŸãã
æ§èœ
æ²¡å ¥ã¯ãããã§äœæããããããžã§ã¯ãã®ããã©ãŒãã³ã¹ã«ã©ã®ããã«åœ±é¿ããŸããïŒ ãã³ãããŒã¯ã瀺ãããã«ãimmerã¯ImmutableJSãšã»ãŒåãé床ã§åäœããå¹ççãªæåã§äœæãããæžéæ©ã®2åã®é床ã§ãã ããã¯ãŸã£ããåé¡ãããŸããã ãã ããES5ã§ã®å®è£ ã¯ã¯ããã«é ããããçµæãšããŠãES5ããŒãžã§ã³ã察象ãšãããã©ãããã©ãŒã ã§è² è·ã®é«ãã¬ãã¥ãŒãµãŒã«æ²¡é ããããšãæåŠããããšã¯æ£åœåãããŸãã 幞ããªããšã«ããããžã§ã¯ãã§immerã䜿çšããå Žåãããã¯ãã¹ãŠã®ã¬ãã¥ãŒãµãŒã§ãã®ã©ã€ãã©ãªã䜿çšããå¿ èŠããããšããæå³ã§ã¯ãªããã©ã®ã¬ãã¥ãŒãµãŒãšã¢ã¯ã·ã§ã³ã§ã©ã®immeræ©èœãå¿ èŠããæ£ç¢ºã«æ±ºå®ã§ããŸãã
浞挬æ§èœè©Šéš
ãããããããã©ãŒãã³ã¹ã«é¢ããŠã¯ãéçºã®å©äŸ¿æ§ã«æåã«æ³šæãæãããšãæåã§ãããé©åãªæž¬å®ã«ãã£ãŠãã®ãããªæé©åã®å¿ èŠæ§ã蚌æãããå Žåã«ã®ã¿ãå®è¡å¯èœã³ãŒãã®é床ãæé©åããå¿ èŠããããŸãã
ãŸãšã
æ²¡å ¥åã®äœæ¥ã¯ããããã·ãªããžã§ã¯ãã®å°ããªå®éšãšããŠéå§ãããŸããã çµæã®ã©ã€ãã©ãªã¯ãç»å ŽããŠããæåã®1é±éã§ãGitHubã«1000以äžã®æãéããŸããã Immerã¯ãJavaScriptã§äžå€ããŒã¿ãåŠçããéã«ãããã€ãã®ãŠããŒã¯ãªæ©èœãåããŠããŸãã ããããéçºè ã³ãã¥ããã£ã¯ããããæ°ã«å ¥ã£ãŠããŸããã ãããããã€ããŒã¯èšèªãšæŠãã®ã§ã¯ãªãããã®æšæºæ©èœã䜿çšãããšããããšã§ãããã ã€ããŒã®åŒ·ã¿ã«ã¯æ¬¡ã®ãã®ããããŸãã
- æšæºã®JSã¡ã«ããºã ã䜿çšããŸãã
- ã¿ã€ãã®ãµããŒãã
- å
ã®ç¶æ
ãšæ°ããç¶æ
ã®éã§å
±æãããããŒã¿ã®å
±æã®çµç¹ã
- ãªããžã§ã¯ããåçµããŸãã
- å®åã³ãŒãã®éãæžãã絶奜ã®æ©äŒã
浞挬ãè©ŠããŠãã ããã ãã®ã©ã€ãã©ãªã¯ããªãã«ãšã£ãŠæçšã§ããå¯èœæ§ããããŸãã
芪æãªãèªè ïŒ ãããžã§ã¯ãã«æ²¡é ããããšãèšç»ããŠããŸããïŒ