YousefED / SyncedStore

SyncedStore CRDT is an easy-to-use library for building live, collaborative applications that sync automatically.
https://syncedstore.org
MIT License
1.71k stars 51 forks source link

Observe changes to object in array #42

Closed jasonm closed 1 year ago

jasonm commented 2 years ago

Hello! I am using SyncedStore in a React application and have come across an issue that I cannot figure out.

Context

It appears that if I have an array of objects in a store, and I change a property of one object, then a component whose render depends on that object does not get updated.

The state data looks like this:

const sections = [
  {
    id: 1,
    todos: [
      { completed: true, title: "Write some code" },
      { completed: false, title: "Write a test" }
    ]
  },
  {
    id: 2,
    todos: [
      { completed: false, title: "Read a paper" }
    ]
  },
];

Repro CSB and video

I have made a minimal repro as a fork of the documentation’s CSB react app and a brief video describing the behavior that I see:

Modifying the data structure to use an object instead of an array seems to work like I’d expect:

Failing test PR

I have tried to write a good failing test in this PR https://github.com/YousefED/reactive/pull/4 but I have not read that code carefully enough to know if this is a good repro case.

If it is more helpful to try to write a test against this repo, I'm happy to try that.

Thanks!

YousefED commented 2 years ago

Wow @jasonm! I am actually out the rest of the week, but your issue was so well-documented I definitely had to take a look. Really appreciate it.

So for now just a quick response:

It seems that using const todos = useSyncedStore(section.todos); on line 10 fixes your problem. I realize this is undocumented and I also didn't omitting this would break your app, so I'll still have to dive deeper. For now, this trick should help you to move along

jasonm commented 2 years ago

Thanks @YousefED! Haha, please go enjoy your time off. I'll look into adding the additional useSyncedStore call in my application.

valstu commented 1 year ago

@jasonm did you ever figure this out? Having exactly the same problem atm.

jasonm commented 1 year ago

Hey @valstu, I haven't revisited this particular issue or used SyncedStore lately. My best recollection is that following @YousefED's recommendation did help. There have been many releases since then so it may be fixed without that extra line, but I'm not sure. It appears to still be necessary in the linked codesandbox from this issue's description, and the package.json in that CSB uses the latest version of @syncedstore/core and @syncedstore/react so I'd guess that it's still needed.

valstu commented 1 year ago

After reading a bit more YJS documentation I think it could be related to fact that YJS doesn't subscribe to subdocuments automatically. And according to @syncedstore docs if we have nested objects those will be "subdocuments". Didn't figure out yet how to subscribe to subdocs.

robhicks commented 1 year ago

Just ran into the same issue with Svelte. Makes it really hard to use.

songispm commented 1 year ago

anything new?

Jordan-Lane commented 1 year ago

Hello!

I am also unfortunately facing the same issue. Setting properties in my nested objects doesn't trigger a rerender of my react components.

I tried the fix described above, however it still did not fix my issue. I would love to use this library, are there any plans to fix this in the future?

YousefED commented 1 year ago

Hi all! This is fixed in release 0.4.3. The sandbox @ https://g9wfx.csb.app/ also works now I think. Thanks for the discussion, and sorry the fix has been a bit late

jasonm commented 1 year ago

Thanks @YousefED ! I can confirm that the linked sandbox works as expected when using 0.4.3/latest (and that changing the deps to 0.4.2 repros the original issue). 🙌