createAsync not updating UI on client
the
decryptWithUserKeys
function is set so that it will return the input if running on server but on client it decrypts the data, the console.log
confirms that the function is running and the data is decrypted but the UI never get's update on first load aka ssr load20 Replies
Can you provide a minimal reproduction in a stack blitz?
Raqueebuddin Aziz
StackBlitz
solid-start-create-async-ssr-issue-repro - StackBlitz
Run official live example code for Solid-start With Tailwindcss, created by Solidjs on StackBlitz
note the issue is only on ssr load, if you save a file and hmr triggers, then it'll show right values
It looks fine to me. SSR returns the [0,1,2] array, console.log is
[ '0', '1', '2' ] true
That's what I would expect during SSR.yes but look at browser console, it shows 20,21,22 but the UI doesn't
the actual UI should be 20,21,22 since thats what decrypted is in client
Okay. Checked again and I see what you mean.
But I've also only now realized that you are calling an async function directly in
createAsync
which is not correct. You should provide a regular function that executes the async function like this:
If you do this, there will be only the console.log which returns the isServer = true
which is correct for the initial SSR rendering.
You can force a revalidate with onMount (see comment in code) to trigger a client side revalidation. But I guess there's just a architectual issue in this part of your app.
getBoards
should not return different data during SRR and client side rendering.getboards return same data, its the data processing that's different, how would you do client side decryption with SSR support? I don't wanna use revalidate like your example since its not actually invalid the encrypted data remains same
You can't run client-side code during SSR. And your approach would potentially lead to hydration issues.
One approach would be to make the Component which uses the data a clientOnly component and do the decryption in that component. So you keep SSR for anything you need it, but can opt-out for client-onyl stuff. So you will call decrypt data only client-side and you can simplify it's data.
I've provided 2x alternatives which then show the "decrypted" values:
https://stackblitz.com/edit/github-hwfkud-csok28?file=src%2Froutes%2Findex.tsx
But can't you decrypt also on the server and have encryption through
https
and the SSL certificate?decrypting on the server means sending user private keys to server which breaks the zero trust model, so in solid start there is no way to server side prefetch the encrypted data and decrypt it on client?
or does the data still prefetch with client only
also do I need to clientOnly where the data is consumed or the component where the createAsync call happens
also appreciate all the help 🙂
You only need the clientOnly for client-only code - decrypt - in your example.
So if you decouple fetching boards from decryption you can still
preload
getBoards in the route.
This would be example 1 in stack blitz.An just discovored that @lxsmnsyc 🤖 has created a npm package with nice helpers:
https://github.com/lxsmnsyc/solid-use/blob/main/docs/client-only.md
GitHub
solid-use/docs/client-only.md at main · lxsmnsyc/solid-use
A collection of SolidJS utilities. Contribute to lxsmnsyc/solid-use development by creating an account on GitHub.
appreciate that, but what is the reason for the discrepancy b/w the UI and the console.log anyways?
is it intended or a bug
Not sure. Probably a bug because you've passed the async function directly to
createAsync
but it actually you should pass an "Accessor" which calls the async function without await like in this example where getData
gets called only on the server during SSR. And that's how it should work to avoid hydration issues.
I don't think that's the issue since all async functions return a promise and I need a lot of it to be inline because I want to track upstream dependencies like appContext.path in the original code
if I understand correctly, createAsync is just supposed to be createMemo but with async function support and they track deps only before the first yield to the event loop
I tried sync code with createMemo and it has same issue, maybe this is intentional behaviour, or a bug that got slipped not sure
you mean like this?
Yes
The issue happens with memo as well so don't think its related to async specifically
Sure, createMemo runs on the server and client. If you use the decrypt function inside it you'll potentiall end up with an hydration issue because it evaluates to different values on server and client. You definetly want to avoid it.
I guess I can run decrypt onMount seems like the easiest way
You just have to separate client and server code by using client only stuff after hydration.
onMount will work or use one the Wrappers of solid-use.
Thanks appreciate all the help. I think I have the solution now