11import React from 'react' ;
22import { stdChannel , runSaga } from 'redux-saga' ;
3- import { effectTypes } from 'redux-saga/effects' ;
3+ import { take , call , effectTypes } from 'redux-saga/effects' ;
4+
5+ const STATE_READY = '@@STATE_READY' ;
46
57export const useReactSaga = ( { state, dispatch, saga } ) => {
68 const environment = React . useRef ( {
79 state,
810 channel : stdChannel ( ) ,
911 actions : [ ] ,
12+ stateChangePossible : false ,
1013 } ) ;
1114
1215 const [ _ , forceUpdate ] = React . useState ( { } ) ;
1316
1417 const put = React . useCallback (
1518 ( action ) => {
19+ forceUpdate ( { } ) ;
1620 dispatch ( action ) ;
1721 environment . current . actions . push ( action ) ;
18- forceUpdate ( { } ) ;
1922 } ,
2023 [ dispatch ] ,
2124 ) ;
@@ -28,7 +31,12 @@ export const useReactSaga = ({ state, dispatch, saga }) => {
2831 environment . current . actions = [ ] ;
2932
3033 actions . forEach ( ( action ) => environment . current . channel . put ( action ) ) ;
31- environment . current . channel . put ( { } ) ;
34+ environment . current . channel . put ( {
35+ type : STATE_READY ,
36+ payload : state ,
37+ } ) ;
38+
39+ environment . current . stateChangePossible = false ;
3240 }
3341 } ) ;
3442
@@ -40,11 +48,29 @@ export const useReactSaga = ({ state, dispatch, saga }) => {
4048 channel : environment . current . channel ,
4149 effectMiddlewares : [
4250 ( runEffect ) => ( effect ) => {
43- if ( effect . type === effectTypes . SELECT ) {
44- environment . current . channel . take ( ( ) => runEffect ( effect ) ) ;
45- } else {
46- runEffect ( effect ) ;
51+ const stateChangePossible = environment . current . stateChangePossible ;
52+
53+ if ( effect . type === effectTypes . PUT ) {
54+ environment . current . stateChangePossible = true ;
4755 }
56+
57+ if ( effect . type === effectTypes . SELECT && stateChangePossible ) {
58+ environment . current . stateChangePossible = false ;
59+
60+ return runEffect (
61+ call (
62+ function * ( selector , args ) {
63+ const action = yield take ( STATE_READY ) ;
64+
65+ return yield call ( selector , action . payload , ...args ) ;
66+ } ,
67+ effect . payload . selector ,
68+ effect . payload . args ,
69+ ) ,
70+ ) ;
71+ }
72+
73+ return runEffect ( effect ) ;
4874 } ,
4975 ] ,
5076 } ,
0 commit comments