Hey!
Good job on a detailed post.
Your app, as well as the example app you’re referencing (Split Bill), seems to be incorrectly utilizing the useSyncExternalStore hook. From its docs:
The store snapshot returned by
getSnapshotmust be immutable. If the underlying store has mutable data, return a new immutable snapshot if the data has changed. Otherwise, return a cached last snapshot.
What you are doing inside your getSnapshot function is return the same object every time. Which, I assume, what React detects as “the value didn’t change, so I don’t need to re-render”. Here is a solution that I came up with:
diff --git a/js/ystore.js b/js/ystore.js
index a1e7034..6d3e1f4 100644
--- a/js/ystore.js
+++ b/js/ystore.js
@@ -22,6 +22,7 @@ export const provider = new WebxdcProvider({
class YStore {
#isSubscribed = false;
#listeners = new Set();
+ #cached = uuidsArray.toJSON()
#handleEvent = (event) => {
console.log("Received an event for the YStore!");
@@ -29,6 +30,8 @@ class YStore {
console.log(`There are ${this.#listeners.size} listeners.`);
+ this.#cached = uuidsArray.toJSON()
+
this.#listeners.forEach((l) => {
console.log("Calling a listener.");
@@ -72,7 +75,7 @@ class YStore {
// If I do this, the app freezes: empty page, infinite logs in the web browser console...
// return uuidsArray.toArray();
- return uuidsArray;
+ return this.#cached;
};
}
But maybe it’s worth checking out examples of using React together with Yjs, maybe there is a better approach.