Server Components
ReScript allows you to create server components as described in React 19.
Server Functions
To mark a file exposing functions as Server Functions,
you can use the @@directive("'use server'")
tag.
Warning: It is recommended to use an interface file here, to ensure only the functions you want to expose are exposed.
RES// src/actions/MyActions.resi
let helloWorld: unit => Promise<string>
myHelper
will remain unexported with this change.
Server Components
Server components can be async.
// src/pages/Index.res
let data = [1, 2, 3]
let getData = () => Promise.resolve(data)
@react.component
let make = async () => {
// fetch some data from somewhere
let data = await getData()
<html>
<body>
<h1> {React.string("Hello from server component")} </h1>
<ul>
{data->Array.map(id => <li> {React.int(id)} </li>)->React.array}
</ul>
</body>
</html>
}
// Export as default
let default = make
A server function can be inlined in a server component and passed as prop to a client component.
module ClientComp = {
@react.component @module("some-module")
external make: (~submit: int => promise<bool>) => React.element =
"SomeClientComp"
}
let data = [1, 2, 3]
let getData = () => Promise.resolve(data)
@react.component
let make = async () => {
let data = await getData()
let addData =
@directive("'use server'")
async (id: int) => {
// add to data store
data->Array.push(id)
true
}
<html>
<body>
<h1> {React.string("Hello from server component")} </h1>
<ul>
{data->Array.map(id => <li> {React.int(id)} </li>)->React.array}
</ul>
<ClientComp submit={addData} />
</body>
</html>
}
Note that when decorating the function with @directive("'use server'")
, we use a single @
, where to annotate an entire file we use @@directive("'use server'")
.
Client Components
Client components should use the @@directive("'use client'")
attribute.