Skip to content

Commit ab19f02

Browse files
committed
Add page on server components
1 parent e109191 commit ab19f02

File tree

2 files changed

+192
-1
lines changed

2 files changed

+192
-1
lines changed

data/sidebar_react_latest.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
"styling",
1717
"router",
1818
"lazy-components",
19-
"import-export-reactjs"
19+
"import-export-reactjs",
20+
"server-components"
2021
],
2122
"Hooks & State Management": [
2223
"hooks-overview",
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
---
2+
title: Server Components
3+
description: "Creating React components"
4+
canonical: "/docs/react/latest/server-components"
5+
---
6+
7+
# Server Components
8+
9+
ReScript allows you to create server components as described in [React 19](https://react.dev/reference/rsc/server-components).
10+
11+
## Server Functions
12+
13+
To mark a file exposing functions as [Server Functions](https://react.dev/reference/rsc/server-functions),
14+
you can use the `@@directive("'use server'")` tag.
15+
16+
<CodeTab labels={["ReScript", "JS Output"]}>
17+
18+
```res example
19+
// src/actions/MyActions.res
20+
@@directive("'use server'")
21+
22+
let myHelper = () => "Hello from the server!"
23+
24+
let helloWorld = async () => {
25+
let response = myHelper()
26+
response
27+
}
28+
```
29+
```js
30+
'use server'
31+
// Generated by ReScript, PLEASE EDIT WITH CARE
32+
33+
34+
function myHelper() {
35+
return "Hello from the server!";
36+
}
37+
38+
async function helloWorld() {
39+
return "Hello from the server!";
40+
}
41+
42+
export {
43+
myHelper,
44+
helloWorld,
45+
}
46+
```
47+
48+
</CodeTab>
49+
50+
**Warning:** It is recommended to use an interface file here, to ensure only the functions you want to expose are exposed.
51+
52+
```res
53+
// src/actions/MyActions.resi
54+
let helloWorld: unit => Promise<string>
55+
```
56+
57+
`myHelper` will remain unexported with this change.
58+
59+
## Server Components
60+
61+
[Server components](https://react.dev/reference/rsc/server-components) can be async.
62+
63+
<CodeTab labels={["ReScript", "JS Output"]}>
64+
65+
```res example
66+
// src/pages/Index.res
67+
@react.component
68+
let make = async () => {
69+
let data = await getData()
70+
<html>
71+
<body>
72+
<h1> {React.string("Hello from server component")} </h1>
73+
</body>
74+
</html>
75+
}
76+
77+
// Export as default
78+
let default = make
79+
```
80+
```js
81+
'use server'
82+
import * as JsxRuntime from "react/jsx-runtime";
83+
84+
async function make(param) {
85+
await moo();
86+
return JsxRuntime.jsx("html", {
87+
children: JsxRuntime.jsx("body", {
88+
children: JsxRuntime.jsx("h1", {
89+
children: "Hello from server component"
90+
})
91+
})
92+
});
93+
}
94+
95+
let Index = make;
96+
97+
let make$1 = Index;
98+
99+
let $$default = Index;
100+
101+
export {
102+
make$1 as make,
103+
$$default as default,
104+
}
105+
```
106+
107+
</CodeTab>
108+
109+
A server function can be inlined in a server component and passed as prop to a client component.
110+
111+
<CodeTab labels={["ReScript", "JS Output"]}>
112+
113+
```res
114+
@react.component
115+
let make = async () => {
116+
let data = await getData()
117+
118+
let addData =
119+
@directive("'use server'")
120+
async (name: string) => {
121+
// add to data store
122+
true
123+
}
124+
<html>
125+
<body>
126+
<h1> {React.string("Hello from server component")} </h1>
127+
<ClientComp submit={addData} />
128+
</body>
129+
</html>
130+
}
131+
```
132+
```js
133+
async function make(param) {
134+
await moo();
135+
let addData = async name => {
136+
'use server';
137+
return true;
138+
};
139+
return JsxRuntime.jsx("html", {
140+
children: JsxRuntime.jsxs("body", {
141+
children: [
142+
JsxRuntime.jsx("h1", {
143+
children: "Hello from server component"
144+
}),
145+
JsxRuntime.jsx(ClientComp, {
146+
submit: addData
147+
})
148+
]
149+
})
150+
});
151+
}
152+
```
153+
154+
</CodeTab>
155+
156+
**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'")`.
157+
158+
## Client Components
159+
160+
[Client components](https://react.dev/reference/rsc/use-client) should use the `@@directive("'use client'")` attribute.
161+
162+
<CodeTab labels={["ReScript", "JS Output"]}>
163+
164+
```res
165+
// src/components/ClientComp.res
166+
@@directive("'use client'")
167+
168+
@react.component
169+
let make = (~submit) => <button> {React.string("yow from client")} </button>
170+
```
171+
```js
172+
use client'
173+
// Generated by ReScript, PLEASE EDIT WITH CARE
174+
175+
import * as JsxRuntime from "react/jsx-runtime";
176+
177+
function ClientComp(props) {
178+
return JsxRuntime.jsx("button", {
179+
children: "yow from client"
180+
});
181+
}
182+
183+
let make = ClientComp;
184+
185+
export {
186+
make,
187+
}
188+
```
189+
190+
</CodeTab>

0 commit comments

Comments
 (0)