Skip to content

Commit e55d118

Browse files
authored
[fix] Using queue instead of updated flag for store state (#1341)
[fix]: Using queue instead of updated flag for store state Fixes [CLNP-6886](https://sendbird.atlassian.net/browse/CLNP-6886) ### Changelogs - Improved the store state management ### Checklist Put an `x` in the boxes that apply. You can also fill these out after creating the PR. If unsure, ask the members. This is a reminder of what we look for before merging your code. - [x] **All tests pass locally with my changes** - [ ] **I have added tests that prove my fix is effective or that my feature works** - [ ] **Public components / utils / props are appropriately exported** - [ ] I have added necessary documentation (if appropriate) ## External Contributions This project is not yet set up to accept pull requests from external contributors. If you have a pull request that you believe should be accepted, please contact the Developer Relations team <[email protected]> with details and we'll evaluate if we can set up a [CLA](https://en.wikipedia.org/wiki/Contributor_License_Agreement) to allow for the contribution. [CLNP-6886]: https://sendbird.atlassian.net/browse/CLNP-6886?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
1 parent d3f9c3c commit e55d118

File tree

1 file changed

+19
-15
lines changed

1 file changed

+19
-15
lines changed

src/utils/storeManager.ts

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,31 +22,35 @@ export function hasStateChanged<T>(prevState: T, updates: Partial<T>): boolean {
2222
});
2323
}
2424

25+
interface StoreSetStateJob<T> {
26+
partial: Partial<T> | ((state: T) => Partial<T>);
27+
force?: boolean;
28+
}
29+
2530
/**
2631
* A custom store creation utility
2732
*/
2833
export function createStore<T extends object>(initialState: T): Store<T> {
2934
let state = { ...initialState };
35+
const queue: StoreSetStateJob<T>[] = [];
3036
const listeners = new Set<() => void>();
31-
let isUpdating = false;
32-
33-
const setState = (partial: Partial<T> | ((state: T) => Partial<T>), force?: boolean) => {
34-
// Prevent nested updates
35-
if (isUpdating) return;
3637

37-
try {
38-
isUpdating = true;
39-
const nextState = typeof partial === 'function' ? partial(state) : partial;
40-
const hasChanged = hasStateChanged(state, nextState);
38+
const processQueue = () => {
39+
const job = queue.shift();
40+
if (!job) return;
4141

42-
if (force || hasChanged) {
43-
state = { ...state, ...nextState };
44-
listeners.forEach((listener) => listener());
45-
}
46-
} finally {
47-
isUpdating = false;
42+
const { partial, force } = job;
43+
const nextState = typeof partial === 'function' ? partial(state) : partial;
44+
const hasChanged = hasStateChanged(state, nextState);
45+
if (force || hasChanged) {
46+
state = { ...state, ...nextState };
47+
listeners.forEach((listener) => listener());
4848
}
4949
};
50+
const setState = (partial: Partial<T> | ((state: T) => Partial<T>), force?: boolean) => {
51+
queue.push({ partial, force });
52+
processQueue();
53+
};
5054

5155
return {
5256
getState: () => state,

0 commit comments

Comments
 (0)