Skip to content

Commit 5316910

Browse files
fix: select helper performance
1 parent 9338e04 commit 5316910

1 file changed

Lines changed: 33 additions & 7 deletions

File tree

src/index.js

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
11
import React from 'react';
22
import { 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

57
export 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

Comments
 (0)