ã ããç§ã¯ç§ã®ç¶æ ã®äžã§ãã®ãã¹ããããæ§é ãæã£ãŠããŸã
state = {
plans: [
{title: 'A', exercises: [{title: 'exe1'}, {title: 'exe2'},{title: 'exe3'}]},
{title: 'B', exercises: [{title: 'exe5'}, {title: 'exe1'},{title: 'exe2'}]}
]
}
以åã®ç¶æ ãå€æŽããªãreduceãäœæããããšããŠããŸããããããè¡ãæ¹æ³ãç解ããŠããã¢ããªã®æ®ãã®éšåãã³ãŒãã£ã³ã°ããããšã«å€ãã®æéãè²»ããããã«ãªããããªãã€ã©ã€ã©ããŠããŸãã
ããšãã°ãæ°ãã空ã®ãšã¯ãµãµã€ãºãè¿œå ããããæ¢åã®ãšã¯ãµãµã€ãºãæŽæ°ãããããå Žåã¯ãããŒã¿ãå€æŽããã ãã§ãã
state.plans[planIdx].exercises.push({})
state.plans[planIdx].exercises[exerciseIdx] = exercise
ãããããã®ãã¹ããããæ§é ã§åãããšãè¡ãããã®ç§ã®æåã®ã¢ãããŒãã¯äœã§ããããïŒ Reduxã®ããã¥ã¡ã³ããšãã©ãã«ã·ã¥ãŒãã£ã³ã°ã®éšåãèªã¿ãŸããããæãé ãã®ã¯èšç»ã®æŽæ°ã§ããã
case 'UPDATE_PLAN':
return {
...state,
plans: [
...state.plans.slice(0, action.idx),
Object.assign({}, state.plans[action.idx], action.plan),
...state.plans.slice(action.idx + 1)
]
};
ãããæäœããããéãæ¹æ³ã¯ãããŸãããïŒ å€éšã©ã€ãã©ãªã䜿çšããå¿ èŠãããå Žåã§ããå°ãªããšã誰ããããã«ããŸã察åŠããæ¹æ³ã説æããŠãããå Žåã§ã...
ããããšãããããŸããïŒ
https://github.com/gaearon/normalizrã®ããã«ãã¹ããããJSONãæ£èŠåããããšããå§ãã
ã¯ããããŒã¿ãæ£èŠåããããšããå§ãããŸãã
ãã®ããã«ããæ·±ããé²ãå¿
èŠã¯ãããŸããããã¹ãŠã®ãšã³ãã£ãã£ãåãã¬ãã«ã«ãããŸãã
ã ããããªãã®ç¶æ ã¯æ¬¡ã®ããã«ãªããŸã
{
entities: {
plans: {
1: {title: 'A', exercises: [1, 2, 3]},
2: {title: 'B', exercises: [5, 1, 2]}
},
exercises: {
1: {title: 'exe1'},
2: {title: 'exe2'},
3: {title: 'exe3'}
}
},
currentPlans: [1, 2]
}
ããªãã®ã¬ãã¥ãŒãµãŒã¯æ¬¡ã®ããã«èŠãããããããŸãã
import merge from 'lodash/object/merge';
const exercises = (state = {}, action) => {
switch (action.type) {
case 'CREATE_EXERCISE':
return {
...state,
[action.id]: {
...action.exercise
}
};
case 'UPDATE_EXERCISE':
return {
...state,
[action.id]: {
...state[action.id],
...action.exercise
}
};
default:
if (action.entities && action.entities.exercises) {
return merge({}, state, action.entities.exercises);
}
return state;
}
}
const plans = (state = {}, action) => {
switch (action.type) {
case 'CREATE_PLAN':
return {
...state,
[action.id]: {
...action.plan
}
};
case 'UPDATE_PLAN':
return {
...state,
[action.id]: {
...state[action.id],
...action.plan
}
};
default:
if (action.entities && action.entities.plans) {
return merge({}, state, action.entities.plans);
}
return state;
}
}
const entities = combineReducers({
plans,
exercises
});
const currentPlans = (state = [], action) {
switch (action.type) {
case 'CREATE_PLAN':
return [...state, action.id];
default:
return state;
}
}
const reducer = combineReducers({
entities,
currentPlans
});
ã§ã¯ãããã§äœãèµ·ãã£ãŠããã®ã§ããããã ãŸããç¶æ ãæ£èŠåãããŠããããšã«æ³šæããŠãã ããã ä»ã®ãšã³ãã£ãã£å ã«ãšã³ãã£ãã£ãååšããããšã¯ãããŸããã 代ããã«ãIDã§çžäºã«åç §ããŸãã ãããã£ãŠããªããžã§ã¯ããå€æŽããããã³ã«ãæŽæ°ãå¿ èŠãªå Žæã¯1ã€ã ãã§ãã
次ã«ã plans
ã¬ãã¥ãŒãµãŒã«é©åãªãšã³ãã£ãã£ãè¿œå ããããšãšcurrentPlans
ã¬ãã¥ãŒãµãŒã«IDãè¿œå ããããšã®äž¡æ¹ã«ãã£ãŠã CREATE_PLAN
ã©ã®ããã«åå¿ãããã«æ³šç®ããŠãã ããã ããã¯éèŠã ããè€éãªã¢ããªã§ã¯ãé¢ä¿ãããå ŽåããããŸããããšãã°ã plans
ã¬ãã¥ãŒãµãŒã¯ããã©ã³å
ã®é
åã«æ°ããIDãè¿œå ããããšã§ãåãæ¹æ³ã§ADD_EXERCISE_TO_PLAN
ãåŠçã§ããŸãã ãã ããæŒââç¿èªäœãæŽæ°ãããå Žåã_ IDã¯å€æŽãããŠããªãããã plans
ã¬ãã¥ãŒãµãŒããããç¥ãå¿
èŠã¯ãããŸãã_ã
第3ã«ããšã³ãã£ãã£ã¬ãã¥ãŒãµãŒïŒ plans
ããã³exercises
ïŒã«ã¯ã action.entities
ç£èŠããç¹å¥ãªå¥ãããããšã«æ³šæããŠãã ããã ããã¯ããã¹ãŠã®ãšã³ãã£ãã£ãæŽæ°ããŠåæ ãããããæ¢ç¥ã®çå®ããå«ããµãŒããŒå¿çãããå Žåã§ãã ã¢ã¯ã·ã§ã³ããã£ã¹ãããããåã«ãã®æ¹æ³ã§ããŒã¿ãæºåããã«ã¯ã normalizrã䜿çšã§ããŸãã Reduxãªããžããªã®ãå®äžçãã®äŸã§äœ¿çšãããŠããããšãããããŸãã
æåŸã«ããšã³ãã£ãã£ãªãã¥ãŒãµãŒãã©ã®ããã«é¡äŒŒããŠãããã«æ³šç®ããŠãã ããã ããããçæããé¢æ°ãäœæããããšããå§ãããŸãã ããã¯ç§ã®çãã®ç¯å²å€ã§ããæè»æ§ãé«ãããå Žåãããã°ãå®åæãæžããããå ŽåããããŸãã åæ§ã®ã¬ãã¥ãŒãµãŒãçæããäŸã«ã€ããŠã¯ããå®äžçãã®ã¬ãã¥ãŒãµãŒã®äŸã§ããŒãžããŒã·ã§ã³ã³ãŒãã確èªã§ããŸãã
ãããç§ã¯{ ...a, ...b }
æ§æã䜿çšããŸããã ES7ããããŒã¶ã«ãšããŠBabelã¹ããŒãž2ã§æå¹ã«ãªããŸãã ããã¯ããªããžã§ã¯ãæ¡æ£æŒç®åããšåŒã°ãã Object.assign({}, a, b)
ãèšè¿°ããã®ãšåãã§ãã
ã©ã€ãã©ãªã«é¢ããŠã¯ãLodashïŒãã ããå€æŽããªãããã«æ³šæããŠãã ãããããšãã°ã merge({}, a, b}
ã¯æ£ãããã merge(a, b)
ã¯æ£ãããªãïŒã updeep ã react- addons -updateãªã©ã䜿çšã§ããŸãã ãã ãã詳现ãªæŽæ°ãè¡ãå¿
èŠãããå Žåã¯ãç¶æ
ããªãŒãååã«å¹³åŠã§ãªããæ©èœæ§æãååã«æŽ»çšããŠããªãããšãæå³ããŠããå¯èœæ§ããããŸãã ããªãã®æåã®äŸã§ããïŒ
case 'UPDATE_PLAN':
return {
...state,
plans: [
...state.plans.slice(0, action.idx),
Object.assign({}, state.plans[action.idx], action.plan),
...state.plans.slice(action.idx + 1)
]
};
次ã®ããã«æžãããšãã§ããŸã
const plan = (state = {}, action) => {
switch (action.type) {
case 'UPDATE_PLAN':
return Object.assign({}, state, action.plan);
default:
return state;
}
}
const plans = (state = [], action) => {
if (typeof action.idx === 'undefined') {
return state;
}
return [
...state.slice(0, action.idx),
plan(state[action.idx], action),
...state.slice(action.idx + 1)
];
};
// somewhere
case 'UPDATE_PLAN':
return {
...state,
plans: plans(state.plans, action)
};
ãããã¬ã·ãã«ãããšããã§ããã
çæ³çã«ã¯ãããã°ãããŒãã®äŸãå¿
èŠã§ãã
ãã¬ãŒã³ãã«ã¯ãã«ãŒãããå«ãŸããŠããå¯èœæ§ãããããããã¹ãããããšã³ãã£ãã£ã«æé©ã§ãã
@ andre0799ãŸãã¯ãImmutable.jsã䜿çšããããšãã§ããŸãïŒïŒ
çæ³çã«ã¯ãããã°ãããŒãã®äŸãå¿ èŠã§ãã
ç§ã¯1ã€æžããã ããããããªãã¯ããããã©ãŒã¯ããŠããªãã®å¥œã¿ã«åŸ®èª¿æŽããããšãã§ããŸãã
Immutable.jsã¯å¿ ãããè¯ã解決çã§ã¯ãããŸããã å€æŽããããŒãããå§ãŸãç¶æ ã®ãã¹ãŠã®èŠªããŒãã®ããã·ã¥ãåèšç®ããç¹å®ã®å Žåã«ããã«ããã¯ã«ãªããŸãïŒããã¯ããŸãäžè¬çãªã±ãŒã¹ã§ã¯ãããŸããïŒã ãããã£ãŠãçæ³çã«ã¯ãImmutable.jsãã¢ããªã±ãŒã·ã§ã³ã«çµ±åããåã«ãããã€ãã®ãã³ãããŒã¯ãäœæããå¿ èŠããããŸãã
çããŠãããŠããããšã@gaearon ãçŽ æŽããã説æïŒ
ãããã£ãŠã CREATE_PLAN
å®è¡ãããšãã¯ãããã©ã«ãã®æŒç¿ãèªåçã«äœæããŠè¿œå ããå¿
èŠããããŸãã ãã®ãããªã±ãŒã¹ãã©ã®ããã«åŠçããå¿
èŠããããŸããïŒ æ¬¡ã«ã3ã€ã®ã¢ã¯ã·ã§ã³ãç¶ããŠåŒã³åºãå¿
èŠããããŸããïŒ CREATE_PLAN, CREATE_EXERCISE, ADD_EXERCISE_TO_PLAN
ãããããªããã©ããããããã®é»è©±ããããã¹ãã§ããïŒ
ãããã£ãŠãCREATE_PLANãå®è¡ãããšãã¯ãããã©ã«ãã®æŒç¿ãèªåçã«äœæããŠè¿œå ããå¿ èŠããããŸãã ãã®ãããªã±ãŒã¹ãã©ã®ããã«åŠçããå¿ èŠããããŸããïŒ
äžè¬çã«ãç§ã¯åãã¢ã¯ã·ã§ã³ãåŠçããå€ãã®ã¬ãã¥ãŒãµãŒãæ¯æããŠããŸãããé¢ä¿ãæã€ãšã³ãã£ãã£ã«ãšã£ãŠã¯è€éãããå¯èœæ§ããããŸãã 確ãã«ãç§ã¯ããããå¥ã ã®ã¢ã¯ã·ã§ã³ãšããŠã¢ãã«åããããšãææ¡ããŠããŸãã
Redux Thunkããã«ãŠã§ã¢ã䜿çšããŠãäž¡æ¹ãåŒã³åºãã¢ã¯ã·ã§ã³ã¯ãªãšãŒã¿ãŒãäœæã§ããŸãã
function createPlan(title) {
return dispatch => {
const planId = uuid();
const exerciseId = uuid();
dispatch({
type: 'CREATE_EXERCISE',
id: exerciseId,
exercise: {
id: exerciseId,
title: 'Default'
}
});
dispatch({
type: 'CREATE_PLAN',
id: planId,
plan: {
id: planId,
exercises: [exerciseId],
title
}
});
};
}
次ã«ãRedux Thunkããã«ãŠã§ã¢ãé©çšãããšãéåžžã©ããã«åŒã³åºãããšãã§ããŸãã
store.dispatch(createPlan(title));
ãããã£ãŠããã®ãããªé¢ä¿ïŒæçš¿ãäœæè ãã¿ã°ãæ·»ä»ãã¡ã€ã«ãªã©ïŒãæã€æçš¿ãšãã£ã¿ãŒãããã¯ãšã³ãã®ã©ããã«ãããšããŸãããã
ããŒã®currentPlans
é
åãšåæ§ã«currentPosts
衚瀺ããã«ã¯ã©ãããã°ããã§ããïŒ ç§ã¯ãåããŒã«ãããããå¿
èŠããããŸãcurrentPosts
ããŠãããã«å¯Ÿå¿ãããªããžã§ã¯ãã«entities.posts
ã§mapStateToProps
æ©èœïŒ currentPosts
䞊ã¹æ¿ããŠã¿ãŸãããïŒ
ããã¯ãã¹ãŠã¬ãã¥ãŒãµãŒæ§æã«å±ããŸããïŒ
ããã«äœãã足ããŸãã...
å ã®è³ªåã«é¢ããŠã¯ã React ImmutabilityHelpersã¯ãã®ç®çã®ããã«äœæããããšæããŸã
ããŒã®currentPlansé åãšåæ§ã«currentPostsã衚瀺ããã«ã¯ã©ãããã°ããã§ããïŒ currentPostsã®åããŒãmapStateToPropsé¢æ°ã®entities.postsã®å¯Ÿå¿ãããªããžã§ã¯ãã«ãããããå¿ èŠããããŸããïŒ currentPostsã䞊ã¹æ¿ããã®ã¯ã©ãã§ããïŒ
ããã¯æ£ããã§ãã ããŒã¿ãååŸãããšãã¯ããã¹ãŠãè¡ããŸãã Reduxãªããžããªã«ä»å±ããŠãããã·ã§ããã³ã°ã«ãŒãããšãå®äžçãã®äŸãåç §ããŠãã ããã
ãããã§ãç§ã¯ããã¥ã¡ã³ãã®Computing Derived Dataãèªãã åŸããã§ã«ã¢ã€ãã¢ãåŸå§ããŸããã
ãããã®äŸãããäžåºŠç¢ºèªããŸãã ããããèªãã ãšããæåã¯äœãèµ·ãã£ãŠããã®ãããç解ã§ããªãã£ãã§ãããã
@ andre0799
connect()
edã³ã³ããŒãã³ãã«ã¯ãããã©ã«ãã§å°éå
·ãšããŠdispatch
æ¿å
¥ãããŠããŸãã
this.props.dispatch(createPlan(title));
ããã¯ããã®ã¹ã¬ãããšã¯é¢ä¿ã®ãªã䜿çšæ³ã®è³ªåã§ãã ããã«ã€ããŠã¯ãäŸãåç §ããããStackOverflowã®è³ªåãäœæããããšããå§ãããŸãã
ç§ã¯ãããŒã¿ãæ£èŠåããç¶æ æ§é ãå¯èœãªéãå¹³åŠåããããšã§ãã³ã«åæããŸãã ããã¯ç§ã«ããã€ãã®é çãæã£ãã§ãããã®ã§ãããã¯ããã¥ã¡ã³ããŒã·ã§ã³ã®ã¬ã·ã/ãã¹ããã©ã¯ãã£ã¹ãšããŠçœ®ããããããããŸããã
èªåã®ç¶æ
ã«å°ãæ·±ã¿ããããšããééããç¯ããã®ã§ãReduxã§æ·±ãç¶æ
ãæ¹è¯ããŠç®¡çããã®ã«åœ¹ç«ã€ããã«ãã®ã©ã€ãã©ãªãäœæããŸããïŒ https ïŒ
å€åç§ã¯ããããã¹ãŠééããŸããããç§ã¯ããªãã®ãã£ãŒãããã¯ã«èå³ããããŸãã ããã誰ããå©ããããšãé¡ã£ãŠããŸãã
ããã¯åœ¹ã«ç«ã¡ãŸããã ããããšãããããŸãã
å®éã®äŸãšåãæ§é ã䜿çšããŠãèšç»ã«æŒç¿ãè¿œå ããã«ã¯ã©ãããã°ããã§ããïŒ ãšã¯ãµãµã€ãºãè¿œå ãããšã planId
ãã£ãŒã«ããæã€æ°ããäœæããããšã¯ãµãµã€ãºãšã³ãã£ãã£ãè¿ããããšããŸãããã ãã©ã³ã®ã¬ãã¥ãŒãµãŒãäœæããã«ãã®ãã©ã³ã«æ°ããæŒç¿ãè¿œå ããç¹ã«CREATE_EXERCISE
ã¢ã¯ã·ã§ã³ããªãã¹ã³ããããšã¯å¯èœã§ããïŒ
ããã§çŽ æŽãããè°è«ãšæ å ±ã ãããžã§ã¯ãã«normalizrã䜿çšãããã®ã§ãããæŽæ°ãããããŒã¿ããªã¢ãŒããµãŒããŒã«ä¿åããããšã«é¢ããŠè³ªåããããŸãã äž»ã«ãæŽæ°åŸã«æ£èŠåããã圢ç¶ããªã¢ãŒãAPIã«ãã£ãŠæäŸããããã¹ãããã圢ç¶ã«æ»ãç°¡åãªæ¹æ³ã¯ãããŸããïŒ ããã¯ãã¯ã©ã€ã¢ã³ããå€æŽãå ããæŽæ°ãªã¯ãšã¹ãã®åœ¢ç¶ãå¶åŸ¡ã§ããªããªã¢ãŒãAPIã«ãã£ãŒãããã¯ããå¿ èŠãããå Žåã«éèŠã§ãã
äŸïŒã¯ã©ã€ã¢ã³ãã¯ãã¹ãããããšã¯ãµãµã€ãºããŒã¿ããã§ããããŸã->ã¯ã©ã€ã¢ã³ãã¯ãããæ£èŠåããŠreduxã«ä¿åããŸã->ãŠãŒã¶ãŒã¯ã¯ã©ã€ã¢ã³ãåŽã§æ£èŠåãããããŒã¿ã«å€æŽãå ããŸã->ãŠãŒã¶ãŒã¯ä¿åãã¯ãªãã¯ããŸã->ã¯ã©ã€ã¢ã³ãã¢ããªã¯æŽæ°ãããæ£èŠåãããããŒã¿ããã¹ãããã圢åŒã«å€æããŸããªã¢ãŒããµãŒããŒã«éä¿¡ã§ããããã«ãã->ã¯ã©ã€ã¢ã³ãããµãŒããŒã«éä¿¡ãã
normalizrã䜿çšããå Žåã倪åã®ã¹ãããçšã«ã«ã¹ã¿ã ãã©ã³ã¹ãã©ãŒããŒãäœæããå¿ èŠããããŸããããããšãããã«æšå¥šããã©ã€ãã©ãªãŸãã¯ãã«ããŒã¡ãœããããããŸããïŒ ä»»æã®æšå¥šäºé ãããã ããã°å¹žãã§ãã
ããããšã
https://github.com/gpbl/denormalizrãšåŒã°ãããã®ããã
ãã£ãããç§ã¯ééããªãéæ£èŠåãèŠãŠãäœããã§ãããããªãã®ãããžã§ã¯ãã«è²¢ç®ããŸãã æ°æéã®çŽ æŽãããä»äº;-)ç§ã«æ»ã£ãŠããŠãããŠããããšãã
æ·±ããã¹ããããããŒã¿ãå€æŽããã®ãšåãç¶æ³ã§ãããimmutable.jsã䜿çšããå®çšçãªãœãªã¥ãŒã·ã§ã³ãèŠã€ããŸããã
ããã§ãœãªã¥ãŒã·ã§ã³ã«é¢ãããã£ãŒãããã¯ãæ±ããŠäœæããStackOverflowã®æçš¿ã«ãªã³ã¯ããŠã倧äžå€«ã§ããïŒ
ä»ã®ãšãããªã³ã¯ããŠããŸããæçš¿ãåé€ããããããã«ãªã³ã¯ããã®ãäžé©åãã©ãããèšã£ãŠãã ããã
http://stackoverflow.com/questions/37171203/manipulating-data-in-nested-arrays-in-redux-with-immutable-js
ç§ã¯éå»ã«ãã®ã¢ãããŒããæšå¥šãããŠããã®ãèŠãŠããŸããã ãã ãããã¹ãããããªããžã§ã¯ããåé€ããå¿ èŠãããå Žåããã®ã¢ãããŒãã¯ããŸãæ©èœããªãããã§ãã ãã®å Žåãã¬ãã¥ãŒãµãŒã¯ããªããžã§ã¯ãèªäœãåé€ããåã«ããªããžã§ã¯ããžã®ãã¹ãŠã®åç §ã調ã¹ãŠããããåé€ããå¿ èŠããããŸããããã¯OïŒnïŒã®æäœã§ãã 誰ããåæ§ã®åé¡ã«ééããããã解決ããŸãããïŒ
@ariofrio ïŒãã...ç§ã¯æ··ä¹±ããŠããŸãã æ£èŠåã®ãã€ã³ãã¯ããªããžã§ã¯ãããã¹ããããŠä¿åãããŠããããç¹å®ã®ã¢ã€ãã ãžã®åç §ã1ã€ãããªãããããã®ã¢ã€ãã ãç°¡åã«æŽæ°ã§ããããšã§ãã ããŠãIDã§ãã®ã¢ã€ãã ããåç §ãããä»ã®ãšã³ãã£ãã£ãè€æ°ããå Žåã¯ãæ£èŠåãããŠããªãå Žåãšåãããã«ãããããæŽæ°ããå¿ èŠããããŸãã
ããªããæ±ããŠããç¹å®ã®æžå¿µããŸãã¯ããªããæ±ã£ãŠããåä»ãªã·ããªãªã¯ãããŸããïŒ
ãããç§ã®èšãããããšã§ãã çŸåšã®ç¶æ ã次ã®ããã«ãªã£ãŠãããšããŸãã
{
entities: {
plans: {
1: {title: 'A', exercises: [1, 2, 3]},
2: {title: 'B', exercises: [5, 6]}
},
exercises: {
1: {title: 'exe1'},
2: {title: 'exe2'},
3: {title: 'exe3'}
5: {title: 'exe5'}
6: {title: 'exe6'}
}
},
currentPlans: [1, 2]
}
ãã®äŸã§ã¯ãåæŒç¿ã¯1ã€ã®ãã©ã³ã§ã®ã¿åç §ã§ããŸãã ãŠãŒã¶ãŒã[éåãåé€]ãã¯ãªãã¯ãããšãã¡ãã»ãŒãžã¯æ¬¡ã®ããã«ãªããŸãã
{type: "REMOVE_EXERCISE", payload: 2}
ãã ãããããé©åã«å®è£ ããã«ã¯ããã¹ãŠã®ãã©ã³ãç¹°ãè¿ãåŠçããŠãããåãã©ã³å ã®ãã¹ãŠã®æŒç¿ãç¹°ãè¿ããŠãåç §ãã¶ãäžãããªãããã«ãID2ã®æŒç¿ãåç §ããŠãããã®ãèŠã€ããå¿ èŠããããŸãã ãããç§ãå¿é ããŠããOïŒnïŒæäœã§ãã
ãããåé¿ããæ¹æ³ã¯ãREMOVE_EXERCISEã®ãã€ããŒãã«ãã©ã³IDãå«ããããšã§ãããçŸæç¹ã§ã¯ãæ§é äœã®ãã¹ãã䜿çšããããšã«åãå©ç¹ã¯ãããŸããã 代ããã«ãã¹ããããç¶æ ã䜿çšããå Žåãç¶æ ã¯æ¬¡ã®ããã«ãªããŸãã
{
plans: [
{title: 'A', exercises: [{title: 'exe1'}, {title: 'exe2'},{title: 'exe3'}]},
{title: 'B', exercises: [{title: 'exe5'}, {title: 'exe6'}]}
]
}
ãŸããæŒç¿ãåé€ããã¡ãã»ãŒãžã¯æ¬¡ã®ããã«ãªããŸãã
{type: "REMOVE_EXERCISE", payload: {plan_index: 0, exercise_index: 1}}
ããã€ãã®èãïŒ
{id, planId, exerciseId}
ããªãã¬ãããå«ãŸããŸãã 確ãã«OïŒnïŒã¹ãã£ã³ã§ãããç°¡åãªã¹ãã£ã³ã§ããæçµçã«ããã¹ããããç¶æ ãšæ£èŠåãããç¶æ ã¯ã©ã¡ããæ £äŸã§ãã Reduxã§æ£èŠåãããç¶æ ã䜿çšããã®ã«ã¯ååãªçç±ããããç¶æ ãæ£èŠåãããŸãŸã«ããã®ã«ã¯ååãªçç±ããããããããŸããã ããªãã®ããã«åããã®ãéžãã§ãã ãã:)
ãã®ãããªç§ã®è§£æ±ºçïŒ
function deepCombinReducer(parentReducer, subReducer) {
return function (state = parentReducer(void(0) /* get parent reducer initial state */, {}) {
let finalState = {...state};
for (var k in subReducer) {
finalState[k] = subReducer(state[k], action);
}
return parentReducer(finalState, action);
};
}
const parentReducer = function(state = {}, action) {
return state;
}
const subReducer = function(state = [], action) {
state = Immutable.fromJS(state).toJS();
switch(action.type) {
case 'ADD':
state.push(action.sub);
return state;
default:
return state;
}
}
export default combineReducers({
parent: deepCombinReducer(parentReducer, {
sub: subReducer
})
})
次ã«ã次ã®ãããªã¹ãã¢ãååŸã§ããŸãã
{
parent: {
sub: []
}
}
dispatch({
type: 'ADD',
sub: '123'
});
// the store will change to:
{
parent: {
sub: ['123']
}
}
@smashercosmo immutable.js
æ·±ããã¹ãç¶æ
ïŒ ã©ã®ããã«èå³ããããŸã
@gaearon
ä»ã®ãšã³ãã£ãã£å ã«ãšã³ãã£ãã£ãååšããããšã¯ãããŸããã
ããããŸããã ããã«ã¯ãå°ãªããšã3ã€ã®ã¬ãã«ã®ãã¹ãããããŸãã
{
entities: {
plans: {
1: {title: 'A', exercises: [1, 2, 3]},
2: {title: 'B', exercises: [5, 1, 2]}
},
exercises: {
1: {title: 'exe1'},
2: {title: 'exe2'},
3: {title: 'exe3'}
}
},
currentPlans: [1, 2]
}
entities.plans[1] - three levels
entities.exercises[1] - three levels
ããã¯ãã¹ããããŠããªããªããžã§ã¯ãã§ãã 1ã€ã®ã¬ãã«ã®ã¿ã
{
plans: [1,2, 3],
exercises: [1,2,3],
'so forth': [1,2,3]
}
@wzup ïŒ
ããã§ã®ããã¹ããã®æå³ã¯ãã¹ã¬ããã®ååã®äŸã®ããã«ãããŒã¿èªäœããã¹ããããŠããå Žåã§ãã
{
plans: [
{title: 'A', exercises: [{title: 'exe1'}, {title: 'exe2'},{title: 'exe3'}]},
{title: 'B', exercises: [{title: 'exe5'}, {title: 'exe6'}]}
]
}
ãã®äŸã§ã¯ãæŒç¿ãexe6ãã«ã¢ã¯ã»ã¹ããå¯äžã®æ¹æ³ã¯ã plans[1].exercises[2]
ãããªæ§é ãæãäžããããšã§ãã
@tmonteã®è³ªåã«èå³ããããŸãïŒ
å®éã®äŸãšåãæ§é ã䜿çšããŠãèšç»ã«æŒç¿ãè¿œå ããã«ã¯ã©ãããã°ããã§ããïŒ ãšã¯ãµãµã€ãºãè¿œå ãããšãplanIdãã£ãŒã«ããæã€æ°ããäœæããããšã¯ãµãµã€ãºãšã³ãã£ãã£ãè¿ããããšããŸãããã ãã©ã³ã®ã¬ãã¥ãŒãµãŒãäœæããã«ãã®ãã©ã³ã«æ°ããæŒç¿ãè¿œå ããCREATE_EXERCISEã¢ã¯ã·ã§ã³ãå ·äœçã«ãªãã¹ã³ããããšã¯å¯èœã§ããïŒ
ãšã³ãã£ãã£ãå€æ°ããå Žåããšã³ãã£ãã£ããšã«1ã€ã®ã¬ãã¥ãŒãµãŒãäœæããã®ã¯é¢åã§ããããã®ã¢ãããŒãã§è§£æ±ºã§ããŸãã ç§ã¯ä»ã®ãšããããã«å¯Ÿãã解決çãèŠã€ããŠããŸããã
ç§ã¯presonnaly䜿çšmergeWith
ã®ä»£ããã«merge
ããå€ãã®æè»æ§ã®ããã«ïŒ
import mergeWith from 'lodash/mergeWith';
// Updates an entity cache in response to any action with `entities`.
function entities(state = {}, action) {
// Here where we STORE or UPDATE one or many entities
// So check if the action contains the format we will manage
// wich is `payload.entities`
if (action.payload && action.payload.entities) {
// if the entity is already in the store replace
// it with the new one and do not merge. Why?
// Assuming we have this product in the store:
//
// products: {
// 1: {
// id: 1,
// name: 'Awesome product name',
// rateCategory: 1234
// }
// }
//
// We will updated with
// products: {
// 1: {
// id: 1,
// name: 'Awesome product name',
// }
// }
//
// The result if we were using `lodash/merge`
// notice the rate `rateCategory` hasn't changed:
// products: {
// 1: {
// id: 1,
// name: 'Awesome product name',
// rateCategory: 1234
// }
// }
// for this particular use case it's safer to use
// `lodash/mergeWith` and skip the merge
return mergeWith({}, state, action.payload.entities, (oldD, newD) => {
if (oldD && oldD.id && oldD.id === newD.id) {
return newD;
}
return undefined;
});
}
// Here you could register other handlers to manipulate
// the entities
switch (action.type) {
case ActionTypes.SOME_ACTION:
// do something;
default:
return state;
}
}
const rootReducer = combineReducers({
entities,
});
export default rootReducer;
æãåèã«ãªãã³ã¡ã³ã
ã¯ããããŒã¿ãæ£èŠåããããšããå§ãããŸãã
ãã®ããã«ããæ·±ããé²ãå¿ èŠã¯ãããŸããããã¹ãŠã®ãšã³ãã£ãã£ãåãã¬ãã«ã«ãããŸãã
ã ããããªãã®ç¶æ ã¯æ¬¡ã®ããã«ãªããŸã
ããªãã®ã¬ãã¥ãŒãµãŒã¯æ¬¡ã®ããã«èŠãããããããŸãã
ã§ã¯ãããã§äœãèµ·ãã£ãŠããã®ã§ããããã ãŸããç¶æ ãæ£èŠåãããŠããããšã«æ³šæããŠãã ããã ä»ã®ãšã³ãã£ãã£å ã«ãšã³ãã£ãã£ãååšããããšã¯ãããŸããã 代ããã«ãIDã§çžäºã«åç §ããŸãã ãããã£ãŠããªããžã§ã¯ããå€æŽããããã³ã«ãæŽæ°ãå¿ èŠãªå Žæã¯1ã€ã ãã§ãã
次ã«ã
plans
ã¬ãã¥ãŒãµãŒã«é©åãªãšã³ãã£ãã£ãè¿œå ããããšãšcurrentPlans
ã¬ãã¥ãŒãµãŒã«IDãè¿œå ããããšã®äž¡æ¹ã«ãã£ãŠãCREATE_PLAN
ã©ã®ããã«åå¿ãããã«æ³šç®ããŠãã ããã ããã¯éèŠã ããè€éãªã¢ããªã§ã¯ãé¢ä¿ãããå ŽåããããŸããããšãã°ãplans
ã¬ãã¥ãŒãµãŒã¯ããã©ã³å ã®é åã«æ°ããIDãè¿œå ããããšã§ãåãæ¹æ³ã§ADD_EXERCISE_TO_PLAN
ãåŠçã§ããŸãã ãã ããæŒââç¿èªäœãæŽæ°ãããå Žåã_ IDã¯å€æŽãããŠããªããããplans
ã¬ãã¥ãŒãµãŒããããç¥ãå¿ èŠã¯ãããŸãã_ã第3ã«ããšã³ãã£ãã£ã¬ãã¥ãŒãµãŒïŒ
plans
ããã³exercises
ïŒã«ã¯ãaction.entities
ç£èŠããç¹å¥ãªå¥ãããããšã«æ³šæããŠãã ããã ããã¯ããã¹ãŠã®ãšã³ãã£ãã£ãæŽæ°ããŠåæ ãããããæ¢ç¥ã®çå®ããå«ããµãŒããŒå¿çãããå Žåã§ãã ã¢ã¯ã·ã§ã³ããã£ã¹ãããããåã«ãã®æ¹æ³ã§ããŒã¿ãæºåããã«ã¯ã normalizrã䜿çšã§ããŸãã Reduxãªããžããªã®ãå®äžçãã®äŸã§äœ¿çšãããŠããããšãããããŸããæåŸã«ããšã³ãã£ãã£ãªãã¥ãŒãµãŒãã©ã®ããã«é¡äŒŒããŠãããã«æ³šç®ããŠãã ããã ããããçæããé¢æ°ãäœæããããšããå§ãããŸãã ããã¯ç§ã®çãã®ç¯å²å€ã§ããæè»æ§ãé«ãããå Žåãããã°ãå®åæãæžããããå ŽåããããŸãã åæ§ã®ã¬ãã¥ãŒãµãŒãçæããäŸã«ã€ããŠã¯ããå®äžçãã®ã¬ãã¥ãŒãµãŒã®äŸã§ããŒãžããŒã·ã§ã³ã³ãŒãã確èªã§ããŸãã
ãããç§ã¯
{ ...a, ...b }
æ§æã䜿çšããŸããã ES7ããããŒã¶ã«ãšããŠBabelã¹ããŒãž2ã§æå¹ã«ãªããŸãã ããã¯ããªããžã§ã¯ãæ¡æ£æŒç®åããšåŒã°ããObject.assign({}, a, b)
ãèšè¿°ããã®ãšåãã§ããã©ã€ãã©ãªã«é¢ããŠã¯ãLodashïŒãã ããå€æŽããªãããã«æ³šæããŠãã ãããããšãã°ã
merge({}, a, b}
ã¯æ£ããããmerge(a, b)
ã¯æ£ãããªãïŒã updeep ã react- addons -updateãªã©ã䜿çšã§ããŸãã ãã ãã詳现ãªæŽæ°ãè¡ãå¿ èŠãããå Žåã¯ãç¶æ ããªãŒãååã«å¹³åŠã§ãªããæ©èœæ§æãååã«æŽ»çšããŠããªãããšãæå³ããŠããå¯èœæ§ããããŸãã ããªãã®æåã®äŸã§ããïŒæ¬¡ã®ããã«æžãããšãã§ããŸã