Skip to content

Support react@canary release #101

Closed
Closed
@ellemedit

Description

@ellemedit

React have plans to add new valid element/node type, hooks and APIs as react canary released.
I summarized that required for upcoming react canary things. Can we support these?

New React hooks and APIs are:

  • use: (promise<'value> | context<'value>) => 'value
    • I would suggest new type valueContainer<'value> to express above as they defined value container in RFC.
    • TypeScript type binding
  • cache: 'value => 'value
    • next.js docs
    • TypeScript: export function cache<CachedFunction extends Function>(fn: CachedFunction): CachedFunction
  • useTransition (already bound, just ignore)
  • useDeferredValue (already bound, just ignore)
  • startTransition: ((. unit => unit) => unit)

New ReactDOM hooks and APIs are:

Client Action Function Support: string | (formData: FormData) => unit

  • <button formAction={(formData) => { ... }} />
  • <form action={(formData) => { ... }} />

Async component:

rescript input:

type user = {id: string, name: string}
let fetchUserById = async (userId) => {
  {
    id: userId,
    name: Js.Float.toStringWithRadix(Js.Math.random(), ~radix=16),
  }
}

@react.component
let make = async (~userId) => {
  let user = await fetchUserById(userId)
  <div> {React.string(user.name)} </div>
}

Async component JS output expectation:

import * as JsxRuntime from "react/jsx-runtime";
async function fetchUserById(userId) {
  return { id: userId, name: Math.random().toString(16) };
}
async function Playground(props) {
  var user = await fetchUserById(props.userId);
  return JsxRuntime.jsx("div", { children: user.name });
}
var make = Playground;
export { fetchUserById, make };

New valid node:

Promise node:

type user = {id: string, name: string}
let fetchUserById = async (userId) => {
  {
    id: userId,
    name: Js.Float.toStringWithRadix(Js.Math.random(), ~radix=16),
  }
}

let fetchUserNameById = async (userId) => {
  let user = await fetchUserById(userId)
  user.name
}

@react.component
let make = (~userId) => {
  let userName = fetchUserNameById(userId)
  <React.Suspense>
    {React.promise(userName)}
  </React.Suspense>
}

expect output:

import * as React from "react";
import * as JsxRuntime from "react/jsx-runtime";
async function fetchUserById(userId) {
  return { id: userId, name: Math.random().toString(16) };
}
async function fetchUserNameById(userId) {
  return (await fetchUserById(userId)).name;
}
function Playground(props) {
  var userName = fetchUserNameById(props.userId);
  return JsxRuntime.jsx(React.Suspense, { children: userName });
}
var make = Playground;
export { fetchUserById, fetchUserNameById, make };

React.Context node


thank you for reading this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions