Open jplhomer opened 2 years ago
I love this proposal! A few thoughts:
<Form>
component for mutations? That form // default to a method="post", and the action would also default to the current url
<Form action="/cart" method="post" >
<input type="hidden" name="productId" value={productId} />
<button type="submit">Add to cart</button>
</Form>
And the <Form>
component would automatically add a few other hidden form fields:
<input type="hidden" name="redirect" value="/somePath" />
<input type="hidden" name="serverState" value="stringified server state" />
So when you click the submit button
FormData
object is sent..get('productId')
and do the graphql request to add it to a cartrenderServerComponentsResponse()
, and that uses the server state that was previously sent up to re-RSC and return the RSC response. Also new server state is sent down by a header (this is what happens in the official server components demo but I'm not sure all the situations why this would change? Maybe explicitly changed in the call to renderServerComponentsResponse
?)The interesting thing here is even with JS disabled, those values would all still get sent in the form submit request. Maybe a separate hidden input field could tell the server that JS is disabled. Then the server would do it's normal things, but on the call to renderServerComponentsResponse
it would instead just send a 301 redirect to the redirect path (or the same location). So the browser would refresh completely when you click add to cart, but it would still work.
Sounds dope @blittle!!
I was also thinking that maybe we don't even need a renderServerComponentsResponse
in user code by default. Hydrogen knows it's coming from a <Form>
or useMutation
call, so it can call that automatically. The user can always explicitly call it if they want to redirect to a different place that the original intent.
Here's how the React RSC demo handles it: https://github.com/reactjs/server-components-demo/blob/main/src/NoteEditor.client.js
renderToReadableStream
using the provided server state paramuseMutation
and passes it touseRefresh()
along with the key of the serverState which should be updated (in this case, the current page pathname + search). We already have auseRefresh
function, but we need to update it to support clearing a given cache value manually.We should push on this and support rendering bespoke RSC endpoints from an API function using a nice affordance.
One result of this could be a new
useMutation
hook, just like the RSC demo has in the NoteEditor file.Where
useMutation
abstracts a number of responsibilities:redirectTo
intended server statekey
withuseRefresh
useNavigate()
to navigate to that new key/serverState.Originally posted by @jplhomer in https://github.com/Shopify/hydrogen/issues/881#issuecomment-1064423802