Skip to content

Commit 1d6d29f

Browse files
fix(overmind-react): improve logic and fix fast refresh
1 parent 6862975 commit 1d6d29f

File tree

1 file changed

+54
-79
lines changed
  • packages/node_modules/overmind-react/src

1 file changed

+54
-79
lines changed

packages/node_modules/overmind-react/src/index.ts

Lines changed: 54 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ import {
1717
const IS_PRODUCTION = ENVIRONMENT === 'production'
1818
const IS_TEST = ENVIRONMENT === 'test'
1919
const isNode =
20-
!IS_TEST && typeof process !== "undefined" && process.title && process.title.includes('node')
20+
!IS_TEST &&
21+
typeof process !== 'undefined' &&
22+
process.title &&
23+
process.title.includes('node')
2124

2225
export type IReactComponent<P = any> =
2326
| react.StatelessComponent<P>
@@ -60,15 +63,7 @@ export const Provider: react.ProviderExoticComponent<
6063
> = context.Provider
6164

6265
function useForceRerender() {
63-
const [{ flushId }, setTick] = react.useState({ tick: 0, flushId: 0 })
64-
65-
const forceRerender = react.useCallback((flushId?) => {
66-
setTick((current) => ({
67-
...current,
68-
tick: current.tick + 1,
69-
flushId: flushId || current.flushId,
70-
}))
71-
}, [])
66+
const [flushId, forceRerender] = react.useState(-1)
7267

7368
return {
7469
flushId,
@@ -101,53 +96,35 @@ const useState = <Context extends IContext<any>>(
10196
return overmind.state
10297
}
10398

104-
const trackingRef = react.useRef<any>(null)
105-
99+
const mountedRef = react.useRef<any>(false)
106100
const { flushId, forceRerender } = useForceRerender()
101+
const tree = react.useMemo(
102+
() => (overmind as any).proxyStateTreeInstance.getTrackStateTree(),
103+
[flushId]
104+
)
107105

108-
if (!trackingRef.current) {
109-
const tree = (overmind as any).proxyStateTreeInstance.getTrackStateTree()
110-
trackingRef.current = {
111-
tree,
112-
hasUpdatedBeforeCommit: false,
113-
stopTrackingTask: unstable_scheduleCallback(
114-
unstable_getCurrentPriorityLevel(),
115-
() => {
116-
trackingRef.current.tree.stopTracking()
117-
}
118-
),
119-
state: cb ? cb(tree.state) : tree.state,
120-
}
121-
}
106+
const state = cb ? cb(tree.state) : tree.state
122107

123108
if (IS_PRODUCTION) {
124-
react.useLayoutEffect(() => {
125-
trackingRef.current.mounted = true
126-
127-
if (trackingRef.current.hasUpdatedBeforeCommit) {
128-
forceRerender()
129-
}
109+
react.useLayoutEffect(
110+
() => {
111+
mountedRef.current = true
112+
tree.stopTracking()
130113

131-
return () => {
132-
;(overmind as any).proxyStateTreeInstance.disposeTree(
133-
trackingRef.current.tree
134-
)
135-
}
136-
}, [])
114+
return () => {
115+
tree.dispose()
116+
}
117+
},
118+
[tree]
119+
)
137120

138-
react.useLayoutEffect(() => {
139-
if (trackingRef.current.stopTrackingTask) {
140-
unstable_cancelCallback(trackingRef.current.stopTrackingTask)
141-
trackingRef.current.stopTrackingTask = null
142-
}
143-
trackingRef.current.tree.stopTracking()
144-
})
145-
trackingRef.current.tree.track(() => {
146-
if (trackingRef.current.mounted) {
147-
forceRerender()
148-
} else {
149-
trackingRef.current.hasUpdatedBeforeCommit = true
121+
tree.track((_, __, flushId) => {
122+
if (!mountedRef.current) {
123+
// This one is not dealt with by the useLayoutEffect
124+
tree.dispose()
125+
return
150126
}
127+
forceRerender(flushId)
151128
})
152129
} else {
153130
const component = useCurrentComponent()
@@ -162,22 +139,15 @@ const useState = <Context extends IContext<any>>(
162139
)
163140

164141
react.useLayoutEffect(() => {
165-
trackingRef.current.mounted = true
142+
mountedRef.current = true
166143
overmind.eventHub.emitAsync(EventType.COMPONENT_ADD, {
167144
componentId: component.__componentId,
168145
componentInstanceId,
169146
name,
170-
paths: Array.from(trackingRef.current.tree.pathDependencies) as any,
147+
paths: Array.from(tree.pathDependencies) as any,
171148
})
172149

173-
if (trackingRef.current.hasUpdatedBeforeCommit) {
174-
forceRerender()
175-
}
176-
177150
return () => {
178-
;(overmind as any).proxyStateTreeInstance.disposeTree(
179-
trackingRef.current.tree
180-
)
181151
overmind.eventHub.emitAsync(EventType.COMPONENT_REMOVE, {
182152
componentId: component.__componentId,
183153
componentInstanceId,
@@ -186,30 +156,35 @@ const useState = <Context extends IContext<any>>(
186156
}
187157
}, [])
188158

189-
react.useLayoutEffect(() => {
190-
if (trackingRef.current.stopTrackingTask) {
191-
unstable_cancelCallback(trackingRef.current.stopTrackingTask)
192-
trackingRef.current.stopTrackingTask = null
193-
}
194-
trackingRef.current.tree.stopTracking()
195-
overmind.eventHub.emitAsync(EventType.COMPONENT_UPDATE, {
196-
componentId: component.__componentId,
197-
componentInstanceId,
198-
name,
199-
flushId,
200-
paths: Array.from(trackingRef.current.tree.pathDependencies) as any,
201-
})
202-
})
203-
trackingRef.current.tree.track(() => {
204-
if (trackingRef.current.mounted) {
205-
forceRerender()
206-
} else {
207-
trackingRef.current.hasUpdatedBeforeCommit = true
159+
react.useLayoutEffect(
160+
() => {
161+
tree.stopTracking()
162+
163+
overmind.eventHub.emitAsync(EventType.COMPONENT_UPDATE, {
164+
componentId: component.__componentId,
165+
componentInstanceId,
166+
name,
167+
flushId,
168+
paths: Array.from(tree.pathDependencies) as any,
169+
})
170+
171+
return () => {
172+
tree.dispose()
173+
}
174+
},
175+
[tree]
176+
)
177+
tree.track((_, __, flushId) => {
178+
if (!mountedRef.current) {
179+
// This one is not dealt with by the useLayoutEffect
180+
tree.dispose()
181+
return
208182
}
183+
forceRerender(flushId)
209184
})
210185
}
211186

212-
return trackingRef.current.state
187+
return state
213188
}
214189

215190
const useActions = <Context extends IContext<any>>(): Context['actions'] => {

0 commit comments

Comments
 (0)