Skip to content

Commit 48e2093

Browse files
committed
perf(useTrackerSuspense): Subsequent updates now return data directly instead of throwing a Promise.
1 parent 6fe3e6a commit 48e2093

File tree

2 files changed

+84
-9
lines changed

2 files changed

+84
-9
lines changed

packages/react-meteor-data/suspense/useTracker.tests.js

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ runForVariants(
8585
}
8686
);
8787

88-
runForVariants(
88+
Meteor.isServer && runForVariants(
8989
'suspense/useTracker - Test proper cache invalidation',
9090
async function (test, useTrackerFn) {
9191
const { Coll, simpleFetch } = setupTest();
@@ -163,6 +163,74 @@ runForVariants(
163163
}
164164
);
165165

166+
Meteor.isClient && runForVariants(
167+
'suspense/useTracker - Test responsive behavior',
168+
async function (test, useTrackerFn) {
169+
const { Coll, simpleFetch } = setupTest();
170+
171+
let returnValue;
172+
173+
const Test = () => {
174+
returnValue = useTrackerFn('TestDocs', simpleFetch);
175+
return null;
176+
};
177+
178+
// first return promise
179+
renderToString(
180+
<TestSuspense>
181+
<Test />
182+
</TestSuspense>
183+
);
184+
// wait promise
185+
await new Promise((resolve) => setTimeout(resolve, 100));
186+
// return data
187+
renderToString(
188+
<TestSuspense>
189+
<Test />
190+
</TestSuspense>
191+
);
192+
193+
test.equal(
194+
returnValue[0].updated,
195+
0,
196+
'Return value should be an array with initial value as find promise resolved'
197+
);
198+
199+
Coll.updateAsync({ id: 0 }, { $inc: { updated: 1 } });
200+
201+
// second await promise
202+
renderToString(
203+
<TestSuspense>
204+
<Test />
205+
</TestSuspense>
206+
);
207+
208+
test.equal(
209+
returnValue[0].updated,
210+
0,
211+
'Return value should still not updated as second find promise unresolved'
212+
);
213+
214+
// wait promise
215+
await new Promise((resolve) => setTimeout(resolve, 100));
216+
217+
// return data
218+
renderToString(
219+
<TestSuspense>
220+
<Test />
221+
</TestSuspense>
222+
);
223+
224+
test.equal(
225+
returnValue[0].updated,
226+
1,
227+
'Return value should be an array with one document with value updated'
228+
);
229+
230+
await clearCache();
231+
}
232+
);
233+
166234
Meteor.isClient &&
167235
runForVariants(
168236
'suspense/useTracker - Test useTracker with skipUpdate',

packages/react-meteor-data/suspense/useTracker.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,14 @@ export function useTrackerSuspenseNoDeps<T = any>(key: string, reactiveFn: IReac
114114
if (comp.firstRun) {
115115
// Always run the reactiveFn on firstRun
116116
refs.trackerData = data
117-
} else if (!skipUpdate || !skipUpdate(await refs.trackerData, await data)) {
118-
cacheMap.delete(key)
117+
} else {
118+
const dataResult = await data;
119119

120-
// For any reactive change, forceUpdate and let the next render rebuild the computation.
121-
refs.isMounted && forceUpdate()
120+
if (!skipUpdate || !skipUpdate(await refs.trackerData, dataResult)) {
121+
const cached = cacheMap.get(key);
122+
cached && (cached.result = dataResult);
123+
refs.isMounted && forceUpdate()
124+
}
122125
}
123126
}))
124127

@@ -171,10 +174,14 @@ export const useTrackerSuspenseWithDeps =
171174

172175
if (comp.firstRun) {
173176
refs.trackerData = data
174-
} else if (!skipUpdate || !skipUpdate(await refs.trackerData, await data)) {
175-
cacheMap.delete(key)
176-
177-
refs.isMounted && forceUpdate()
177+
} else {
178+
const dataResult = await data;
179+
180+
if (!skipUpdate || !skipUpdate(await refs.trackerData, dataResult)) {
181+
const cached = cacheMap.get(key);
182+
cached && (cached.result = dataResult);
183+
refs.isMounted && forceUpdate()
184+
}
178185
}
179186
})
180187
)

0 commit comments

Comments
 (0)