tldraw / signia

Reactive signals that scale, by tldraw.
https://signia.tldraw.dev
MIT License
897 stars 15 forks source link

Update atom state in reaction #87

Open c01nd01r opened 5 months ago

c01nd01r commented 5 months ago

Hi! I've come across a situation where it's necessary to change the state of an atom within a reaction.

type AsyncResource = {
  hasError: Signal<boolean>;
  error: Signal<string>;
}

type NotifyStore = {
  messages: Signal<string[]>
  addMessage: (message) => void
}

const notify: NotifyStore = useNotify();
const asyncResource: AsyncResource = useAsyncResource(() => fetch('/error-response'));

useEffect(() => react('add message', () => {
  if (asyncResource.hasError.value) { 
    notify.addMessage(asyncResource.error.value)
  }
}), [])

When a reaction is triggered, the notify.messages atom gets updated, and execution fails with the error 'cannot change atoms during reaction cycle'. From what I understand, this behavior corresponds to this test: https://github.com/tldraw/signia/blob/1d57d3e4d084325149f51fcb15c3eaca5ef8f357/packages/signia/src/__tests__/reactor.test.ts#L20-L30

Are there any workarounds for this situation?

muhajirdev commented 3 months ago

I was having a similar issue. Finally ended up just not using signia for this one particular case.