Skip to content

Add support to a more values at client_prop #227

Open
@pedrobslisboa

Description

@pedrobslisboa

Description

Improve the client_props and start the movement to align the behavior of SRR RSC to what React expects.

Why

The react expect that response of the RSC, which evolves actions response and props response to the client, to be composable.

let props = {
    bar: {
     element: <div/>
  },
  foo: "Hey",
  baz: [<div/>, "Yah!"]
}

But our type nowadays is:

and client_prop =
  (* TODO: Do we need to add more types here? *)
  | Json : Yojson.Basic.t -> client_prop
  | Element : element -> client_prop
  | Promise : 'a Js.Promise.t * ('a -> Yojson.Basic.t) -> client_prop

As we can see, Json does not support any other client_prop inside it, similar to Promise that does not support it. They always handle a Yojson.Basic.t.

So we cannot have: React.Promise(promise, (response) => React.Element(response)).
How would we have such response:

// Server content that needs to be serialized
let props = {
    bar: {
     element: <div> {React.String("I'm a nested element :3")} </div>
  },
  foo: [<div> {React.String("Hey")} </div>, "Yah!"],
  baz: <div> {React.String("Who is Lola?")} </div>
}

//Let's see it as client prop
{
  "bar":  React.???(["element", React.Element(<div> {React.String("I'm a nested element :3")} </div> )])
  "foo":  React.???([React.Element(<div> {React.String("Hey")} </div>, React.Json(`String("Yah!")))])
  "baz": React.Promise(React.Element(<div> {React.String("Who is Lola?")} </div>)) // This is not valid nowaday
)

We need to support those React.??? and we need to make Promise to accept client_prop instead only Yojson type.
For example (not the final code):

and client_prop =
  | List : client_prop list -> rsc_value
  | Assoc : (string * client_prop) list -> rsc_value
  | Json : Yojson.Basic.t -> client_prop
  | Element : element -> client_prop
  | Promise : 'a Js.Promise.t * ('a -> client_prop) -> client_prop

Then we can handle all those types recursively, and the final return must always be either a Yojson.Basic.t or a React.element.

{
  "bar":  React.Assoc(["element", React.Element(<div> {React.String("I'm a nested element :3")} </div> )])
  "foo":  React.List([React.Element(<div> {React.String("Hey")} </div>, React.Json(`String("Yah!")))])
  "baz": React.Promise(React.Element(<div> {React.String("Who is Lola?")} </div>))
)

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions