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
Handling async/event-driven renders? #17
Comments
You're right that args.element may be stale (if the underlying node changes), but args will not be. So for deferred rendering, you just need to pass args instead of args.element. args.element gets replaced everytime the underlying node changes. function MailBox() {
let data = [];
async function updateData(args) {
data = await fetchSomething();
rerender(args.element);
}
return {
render(props, args) {
updateData(args);
return data.length === 0 ? (
<div>Nothing to show.</div>
) : (
<div>Loop through data and display.</div>
);
},
};
} |
You could also consider using forgo-state. https://github.com/forgojs/forgo-state It's about 800 bytes gzipped, and does some interesting optimizations. Like for instance, if a parent and child are bound to the same state, it wouldn't run rerender on the child since the parent will be rerendering anyway. |
I'm using forgo-state for some things, but it doesn't feel right for every task (e.g., requiring an extra library to convert a simple The code snippet you gave triggers the data update from inside the fuction Component() {
let value = null;
let es = null;
return {
async mount() {
value = await fetchInitialValue();
rerender(???);
es = new EventSource(`/events?since=${value.id}`);
es.onmessage = (event) => {
value = event.data;
rerender(???);
}
},
render() {
return <p>{value}</p>;
},
unmount() {
es?.close();
}
}
} I tried basically this, passing |
Does it make any sense for Forgo to assign |
Actually, I'd expect the code above to work - provided you've defined mount() as mount(props, args). |
I did consider it, but I wanted to avoid the this pointer. |
I've made a codesandbox link for you here: https://codesandbox.io/s/dank-pond-3dgxk You could have done it from render() as well, instead of mount. |
I can no longer reproduce with the latest forgo+forgo-state+forgo-router, though I could from the combination of those I had after capturing the #14 fixes. The rerender-from- Thanks for the input. I'll submit a PR for the README documenting async logic soon-ish. |
Thank you. It could have been that forgo-state and forgo-router were referencing older forgo versions. I expect all of them to stabilize this week. Fragment support is the big outstanding ticket, coming soon. |
How should I handle components that need to rerender when a promise resolves, or when an event fires? I'd figured I could set up my promise/event handler inside
mount()
and callrerender()
, but in the context of #14 I now realize that theargs.element
provided tomount()
will be stale by the time something tries to use it to rerender. The docs show some event handlers, but only ones used in the context of element references that are safe to recreate each render, and not situations where a handler should last the lifetime of the component.Is there a recommended way to handle this?
The text was updated successfully, but these errors were encountered: