ã·ããªãªïŒãããžã§ã¯ãã«ã¢ãã«Aãšã¢ãã«Bã«å¯Ÿå¿ãã2ã€ã®ããŒãžAãšBãããå ŽåãåããŒãžã«ããã€ãã®éåæãããã¯ãŒã¯ãªã¯ãšã¹ããããããããã¯æå¹ã«éå§ãããè¿ãããããŒã¿ã¯ã¬ãã¥ãŒãµãŒãä»ããŠçŸåšã®ã¢ãã«ã«æžã蟌ãŸããŸãå·ã
ããŒãžAãŸãã¯ããŒãžBãé¢ãããšãã¯ã次ååå©çšãããšãã«ããŒãã£ããŒã¿ã«ãªããªãããã«ã察å¿ããã¢ãã«ã®ããŒã¿ãã¯ãªã¢ããããšæããŸãã
componentWillUnmountã¡ãœããã§ãã¢ãã«ã«æ確ãªã¬ãã¥ãŒãµãŒãèšè¿°ããŸãã
dispatchïŒ{typeïŒ$ {model.namespace} / clear}ïŒ
ãŠãŒã¶ãŒãããŒãžAããããŒãžBã«å ¥ããšãã¢ãã«Aã®ããŒã¿ãã¯ãªãŒã³ã¢ãããããåæç¶æ ã«åŸ©å ãããŸãã
ãŠãŒã¶ãŒãããŒãžAããããŒãžBã«å ¥ããšããéåæãããã¯ãŒã¯èŠæ±ãããŒãžAã§çºçãããããã¯ãŒã¯èŠæ±ãå®äºããåã«ããŒãžBã«å ¥ããšãããŒãžAã¯æåã«ã¯ãªã¢ã¬ãã¥ãŒãµãŒãä»ããŠã¢ãã«AããŒã¿ãã¯ãªã¢ããŸããããããã¯ãŒã¯ãæå¹ãªå Žåãªã¯ãšã¹ããå®äºãããšãè¿ãããããŒã¿ã¯ã¢ãã«Aã«æžãæãããããããã¢ãã«Aã®åã®ããžãã¹ã®ããŒã¿ãããŒãã£ã«ãªããŸãã
AããŒãžãé¢ãããšãã«æå®ãããå¹æããã£ã³ã»ã«ããããåå空éå ã®ãã¹ãŠã®å¹æããã£ã³ã»ã«ãããã§ããŸããïŒ ïŒredux-sagaã§ãã£ã³ã»ã«ããã®ãšåæ§ïŒ
v2.2.3
ã¢ãã«ã®ãµãã¹ã¯ãªãã·ã§ã³ã®ã«ãŒãã£ã³ã°å€æŽãç£èŠããããŒãžãéAããŒãžïŒAããŒãžãé¢ããïŒãŸãã¯AããŒãžïŒAããŒãžã«å ¥ãïŒã®å Žåãã¢ãã«Aã®ç¶æ ãæåã§ã¯ãªã¢ã§ããŸãã
åçããããšãããããŸãããã®æ¹æ³ãè©ŠããŸãããç¶æ
èªäœãã¯ãªã¢ããŠãåé¡ãããŸãããcomponentWillUnmountã§ã¯ãªã¢ããããšãããµãã¹ã¯ãªãã·ã§ã³ãã«ãŒãã£ã³ã°ã®å€æŽãç£èŠãããšãã«ã¯ãªã¢ããããšãã§ããŸããåé¡ã¯ãã¢ãŒãã«ç¶æ
ãã¯ãªã¢ããåŸãéåææäœã«ãã£ãŠè¿ãããããŒã¿ããšãã§ã¯ãã§è¿ãããããšã§ããããã§ãã¢ãŒãã«ç¶æ
ã«æžãæãããããããåã®ããžãã¹ã®ããŒã¿ãããŒãã£ã«ãªããŸãã
ãµãã¹ã¯ãªãã·ã§ã³ã®ã«ãŒãã£ã³ã°ã®å€æŽãç£èŠããŠããŸããããŒãžAãé¢ãããšãã¯ãunmodelã䜿çšããŠã¢ãã«Aãã¢ã³ã€ã³ã¹ããŒã«ããŸããããŒãžAã«å
¥ããã¢ãã«Aãæåã§ããŒãããããšã¯ç¡æå³ã§ããéåæéä¿¡ãæ»ã£ãå Žåãã¢ãã«AãèŠã€ãã£ãŠããéãããã®ã¢ãã«ãããžãã¹ã§æåŸã«äœ¿çšãããã¢ãã«ã§ããããæ°ããããŒããããã¢ãã«ã§ãããã«é¢ä¿ãªããããŒã¿ãæžã蟌ãŸããŸãã
ãããã£ãŠãæè¯ã®æ¹æ³ã¯ãã¢ãã«ã®ç¶æ
ãã¯ãªã¢ããçŸåšã®åå空éã®ãã¹ãŠã®å¹æããã£ã³ã»ã«ããããšã§ãããåŒã³åºãã¡ãœãããèŠã€ãããŸãããã¢ããã€ã¹ãæ±ããã
å ã®ãã¹ã¿ãŒã®åé¡ãçºçããŸãããã³ã³ããŒãã³ããã¢ã³ã€ã³ã¹ããŒã«ããããšãã«æªå®æã®å¹æããã£ã³ã»ã«ãããã£ãã®ã§ãããæ¹æ³ããªãããšãããããŸãããDvaã¯ãã®çš®ã®api @ sorryccãæäŸããŠããªãããã§ãã
å¹æããã£ã³ã»ã«ããŠãµã¬ãåé¢ããããšã¯å¯èœã§ããïŒ
@dlamonãåãç¶æ³ã«ééããã«ãŒããåãæ¿ãããããšãã«ã¯ãªãŒã³ã¢ããããããšèããŠããŸãããä»è§£æ±ºçã¯ãããŸããïŒ
ã«ãŒãåãæ¿ããå®äºããåŸãéä¿¡ãæ»ããªãå¯èœæ§ããããéä¿¡ãæ»ã£ãåŸãããŒãã£ããŒã¿ãã¯ãªãŒã³ã¢ãããããã¢ãã«ããŒã¿é åã«æžãæ»ãããããã @ KyrieChenã¯ã«ãŒãåãæ¿ãäžã«ã¯ãªãŒã³ã¢ããããããšã¯æåŸ ãããŠããŸããã
ç§ã®çŸåšã®ã¢ãããŒãã¯ãçŸåšã®ãã©ã³ã¶ã¯ã·ã§ã³ã§äœ¿çšãããããŒã¿ãæ ŒçŽããããã«äœ¿çšããããã©ã³ã¶ã¯ã·ã§ã³ãå
¥åãããã³ã«ïŒcomponentWillMountã®å ŽåïŒãçŸåšã®ãã©ã³ã¶ã¯ã·ã§ã³ã«å¯Ÿå¿ããã¢ãã«ããŒã¿é åã«UUIDãæã€ãµãããŒã¿é åãçæããããšã§ããUUIDãæžã蟌ãŸããŸããã©ã³ã¶ã¯ã·ã§ã³ãçµäºãããšã¯ãªã¢ãããŸãïŒcomponentWillUnmountïŒã以äžã®ã¢ãã«æ§é ãšåæ§ã§ãã
ã¯ãªã¢ã¢ãã«ã®åŸã«éä¿¡ãæ»ã£ãŠããå ŽåãããŒã¿ãæžã蟌ããšãã«ãçŸåšã®ã¬ãã¥ãŒãµãŒã«ãã£ãŠäœ¿çšãããUUIDã¯åã®ãã©ã³ã¶ã¯ã·ã§ã³ã§äœ¿çšãããUUIDã§ãããããããŒãã£ããŒã¿ã¯åã®ãã©ã³ã¶ã¯ã·ã§ã³ã®ããŒã¿é åã«æžã蟌ãŸãã次ã®ãã©ã³ã¶ã¯ã·ã§ã³ã§ã¯çæãããŸããã圱é¿ã
ãã ãããã®æ¹æ³ãé©åã§ã¯ãããŸããã1ã€ã¯ããžãã¯ã®è€éããå¢ãã2ã€ç®ã¯åæå€ãååŸããã«ã¯nullå€ã®å€æãè¿œå ããå¿
èŠããããããã³ãŒããè€éã«ãªãããšã§ããç§ããã£ãŠããããšã¯äž»ã«éèã·ã¹ãã ã®ãããªã®ã§ããã®ãããªæ±ãããŒã¿ãæãã®ã§ããã®æ¹æ³ãéžã³ãŸãã
æåã®æ¹æ³ã¯redux-sagaã®ãã£ã³ã»ã«å¹æã¡ã«ããºã ã«äŒŒãŠãããšæããŸãããdvaã¯çŸåšããããµããŒãããŠããªãããã§ãã
ããè¯ã解決çãããå Žåã¯ã@æ
@dlamonç§ãããã«ééããŸãããç§ã¯èªåã§ãã¢ãæžããŸããããããŠç§ã¯å°ãåé¡ãæããŸãhttps://codesandbox.io/s/yqwqpmvwvj
namespace
ããproducts
ããmodel
ãeffect
ã¡ãœããã§ãã£ã³ã»ã«ããŸãïŒ
dispatch({ type: 'products/@<strong i="10">@CANCEL_EFFECTS</strong>' });
yield sagaEffects.fork(function*() {
yield sagaEffects.take(`${model.namespace}/@@CANCEL_EFFECTS`);
yield sagaEffects.cancel(task);
});
@ wss1942ãã®ã¡ãœããã«è¿ä¿¡ããŠããã ãããããšãããããŸããè©ŠããŠã¿ãŸãããdispatch ïŒ{typeïŒ 'products / @ ïŒ796ã«äŒŒãŠããŸã
@dlamon dvaã¯ãå¹æãã¯ãªã¢ããããã®APIãæäŸããŠããªãããã§ãããã ããã¢ãã«ã§å®çŸ©ãããå¹æã§è€æ°ã®ãµã¬ãæžã蟌ãããšãã§ããŸãã
namespace: 'products',
effects: {
*start(){},
*stop(){},
watchLogin: [
function* ({ take, put, call, cancel, fork, cancelled }) {
yield take('start');
const timerTask = yield fork(timer)
const bgSyncTask = yield fork(bgSync)
yield take('stop')
yield cancel(bgSyncTask)
yield cancel(timerTask)
function* bgSync() {
try {
while (true) {
const result = yield call(delay, 5 * 1000);
yield put({ type: 'stop' })
}
} finally {
if (yield cancelled())
yield put({ type: 'log', payload: 'fetchð' })
}
}
function* timer(time) {
let i=0;
while (true) {
yield put({ type: 'log', payload: i++ })
yield delay(1000)
}
}
},
{ type: 'watcher' },
],
}
bgSyncã¯éåæã¿ã¹ã¯ã§ããã actionïŒ startã䜿çšããŠã¿ã¹ã¯ãéå§ãã actionïŒstopã䜿çšããã£ã³ã»ã«ã§ããŸããããã¯ãç¹å®ã®å¹æããã£ã³ã»ã«ããããã«å®è¡ã§ããŸãã
ãŸããéåæã¿ã¹ã¯ããããã¯ãŒã¯ãªã¯ãšã¹ãã®å Žåããããã¯ãŒã¯ãªã¯ãšã¹ãããã£ã³ã»ã«ããæäœãå¿
èŠã«ãªãå ŽåããããŸããããšãã°ãaxios.CancelTokenã䜿çšããŠaxiosããã£ã³ã»ã«ã§ããŸãã
@ wss1942ããããšãïŒ
ãã®ããã«ããšãã§ã¯ãããã£ã³ã»ã«ããããšãã§ããŸããããŒãã¹ããŒã¿ã¹ã衚瀺ããã®ã¯é¢åã§ããdvaã«ä»å±ã®loading.effectsãçŽæ¥äœ¿çšããŠããŒãã¹ããŒã¿ã¹ã衚瀺ããããšã¯ã§ããŸãããå€æŽããã«ã¯ãç¬èªã®ã³ãŒããäœæããå¿
èŠããããŸãã
ç§ã¯ãããå€æŽããå®å
šãªã¢ãã«ã³ãŒããæçš¿ããŸãã
import { getProduct } from '@/services/Products';
import { isRespSucc, showErrorMsg } from '@/utils/utils';
const initState = {};
export default {
namespace: 'product',
state: initState,
effects: {
/**
åšäž€äžª Effects ä¹éŽè§Šåäžäžªç«èµïŒraceïŒ
åŠætaskå
ç»æïŒç«èµç»æã
åŠætaskæªç»ææ¶æ¶å°cancelïŒrace effect å°èªåšåæ¶ taskã
*/
*cancelable({ task, payload }, { call, race, take }) {
yield race({
task: call(task, payload),
cancel: take('cancel'),
});
},
/**
åæ¶æææªå®æçä»»å¡ïŒå¹¶æ§è¡æ°æ®æž
ç
*/
*clear(_, { put }) {
yield put.resolve({ type: 'cancel' });
yield put({ type: 'clearState' });
},
*getProduct({ payload }, { call, put, cancelled }) {
// eslint-disable-next-line
yield put.resolve({ type: 'cancelable', task: getProductCancelable, payload });
function* getProductCancelable(params) {
try {
// è°çšçœç»è¯·æ±
const response = yield call(getProduct, params);
// è¿åç»æå€æ
if (!isRespSucc(response)) {
showErrorMsg(response);
return;
}
// ååŒ
const { productName } = response.data;
// è°çšreducerååŒ
yield put({
type: 'saveState',
payload: { productName },
});
} finally {
if (yield cancelled()) {
// TODO: åæ¶çœç»è¯·æ±
}
}
}
},
*getCity(_, { call, put, cancelled }) {
// eslint-disable-next-line
yield put.resolve({ type: 'cancelable', task: getCityCancelable });
function* getCityCancelable() {
// TODO: å
·äœå®ç°
}
},
reducers: {
saveState(state, { payload }) {
const newState = { ...state, ...payload };
return newState;
},
clearState() {
return initState;
},
},
};
ãã©ã³ã¶ã¯ã·ã§ã³ïŒcomponentWillUnmountïŒãé¢ãããšããdispatch clearã¯çŸåšã®ã¢ãã«ã®ãã¹ãŠã®æªå®äºã®å¹æããã£ã³ã»ã«ã§ããgetProductLoadingãšgetCityLoadingãéåžžã©ãã䜿çšã§ããŸãã
componentWillMount() {
const { dispatch } = this.props;
dispatch({
type: 'product/getProduct',
payload: {
productNumber: '123456',
},
});
dispatch({
type: 'product/getCity',
});
}
componentWillUnmount() {
const { dispatch } = this.props;
dispatch({
type: 'product/clear',
});
}
function mapStateToProps(state) {
return {
getProductLoading: state.loading.effects['product/getProduct'],
getCityLoading: state.loading.effects['product/getCity'],
};
}
æãåèã«ãªãã³ã¡ã³ã
@ wss1942ããããšãïŒ
ãã®ããã«ããšãã§ã¯ãããã£ã³ã»ã«ããããšãã§ããŸããããŒãã¹ããŒã¿ã¹ã衚瀺ããã®ã¯é¢åã§ããdvaã«ä»å±ã®loading.effectsãçŽæ¥äœ¿çšããŠããŒãã¹ããŒã¿ã¹ã衚瀺ããããšã¯ã§ããŸãããå€æŽããã«ã¯ãç¬èªã®ã³ãŒããäœæããå¿ èŠããããŸãã
ç§ã¯ãããå€æŽããå®å šãªã¢ãã«ã³ãŒããæçš¿ããŸãã
ãã©ã³ã¶ã¯ã·ã§ã³ïŒcomponentWillUnmountïŒãé¢ãããšããdispatch clearã¯çŸåšã®ã¢ãã«ã®ãã¹ãŠã®æªå®äºã®å¹æããã£ã³ã»ã«ã§ããgetProductLoadingãšgetCityLoadingãéåžžã©ãã䜿çšã§ããŸãã