New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to make wasm reactive? #203
Comments
Vugu does re-render on state changes. The way it works is the main() blocks on a channel in it's main loop and there is some glue under the hood that drives the wasm application by doing various calls back and forth from JS->WASM. Logically your application "continues to run" and stays alive for as long as you like. Under the hood it's broken up into various calls back and forth. If you're interested in that part, have a read through https://github.com/golang/go/blob/master/misc/wasm/wasm_exec.js But for practical purposes, it appears to work like any other Go program and keeps running in a loop for as long as the page is open. |
The question is what happens when you have multiple components working with the same state altering it async. Once an app outgrows the single component behavior and has many async operations this becomes quite hard to handle. Most of the time shared structs have nil pointers when dereferencing because the reference is not there yet due to the multiple async calls. It all comes down to being able to manage state separately and re-rerender only the components that receive an updated state automatically as the state changes. Without a state store and reactivity that is comparable to nowadays JS frameworks no one would consider wasm for production. |
You would use an EventEnv for that. You call Lock() whenever you change a variable and UnlockRender() when you are done changing the variable and ready to re-render. |
OK, let's take the fetch and display example. Say we use Root.bpi in another component at the same time. In my experience during the async call the value there can not be dereferenced until the call completes so it returns a nil pointer in that other component while being locked in the current one. |
Hi, You can see that I am using a component that acts as the main state component. https://github.com/Xumeiquer/wallets/blob/main/webapp/middleware/state.go. On the other hand, the element I want to be sync across the application is stored as a pointer like in this case https://github.com/Xumeiquer/wallets/blob/main/webapp/components/header.vugu#L171, Then, I check and store a local copy on the I am sure that implementation can be improved. But it does the job. |
The solution has been standardized it seems: I will try to create a package for it that is universal for all Go wasm frameworks and share it with you. |
Closing this issue as this looks like there is a solution. |
The way Go treats wasm as an application means it runs and exits. This is quite limiting compared to modern JS frameworks with their reactive APIs which allow real-time reactivity on external changes.
Is this even possible with the current state of things? Maybe keeping dedicated channels open infinite? This would allow all kind of things from state management stores to webhooks to websockets etc.
https://www.aaron-powell.com/posts/2019-02-06-golang-wasm-3-interacting-with-js-from-go/
Here is an example:
I would like to connect the app to an external state management store and make it re-render on state changes.
By the time the state changed the runtime has exited, hence unless there is a channel open to keep it alive it can't react to external events after exit.
The text was updated successfully, but these errors were encountered: