Skip to content

Support react@canary release #101

@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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions