Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 93 additions & 1 deletion src/content/reference/rsc/use-client.md
Original file line number Diff line number Diff line change
Expand Up @@ -376,4 +376,96 @@ These libraries may rely on component Hooks or client APIs. Third-party componen

If these libraries have been updated to be compatible with React Server Components, then they will already include `'use client'` markers of their own, allowing you to use them directly from your Server Components. If a library hasn't been updated, or if a component needs props like event handlers that can only be specified on the client, you may need to add your own Client Component file in between the third-party Client Component and your Server Component where you'd like to use it.

[TODO]: <> (Troubleshooting - need use-cases)
## Troubleshooting {/*troubleshooting*/}

### "Functions cannot be passed directly to Client Components" error {/*functions-cannot-be-passed-directly*/}

This error occurs when you try to pass a function from a Server Component to a Client Component.

```js
// Server Component
import ClientButton from './ClientButton';

export default function Page() {
function handleClick() {
console.log('clicked');
}
// This will error!
return <ClientButton onClick={handleClick} />;
}
```

Functions are not serializable, so they cannot be passed from server to client. To fix this, either move the function to the Client Component, or use a [Server Function](/reference/rsc/server-functions) with `'use server'`.

```js
// Solution 1: Move the handler to the Client Component
'use client';

export default function ClientButton() {
function handleClick() {
console.log('clicked');
}
return <button onClick={handleClick}>Click me</button>;
}
```

```js
// Solution 2: Use a Server Function
'use server';

export async function handleClick() {
console.log('clicked on server');
}
```

### Component uses hooks but doesn't have `'use client'` {/*component-uses-hooks-without-use-client*/}

If you're using hooks like `useState`, `useEffect`, or `useContext` in a component, you need to mark it as a Client Component.

```js
// This will error - hooks require 'use client'
import { useState } from 'react';

export default function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}
```

Add `'use client'` at the top of the file:

```js
'use client';

import { useState } from 'react';

export default function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}
```

### Third-party library doesn't work in Server Components {/*third-party-library-server-component*/}

Many third-party libraries were written before Server Components existed and may use client-only features. If you get an error when importing a library in a Server Component, create a wrapper Client Component:

```js
// components/ChartWrapper.js
'use client';

import { Chart } from 'third-party-chart-library';

export default function ChartWrapper(props) {
return <Chart {...props} />;
}
```

Then import the wrapper in your Server Component:

```js
// page.js (Server Component)
import ChartWrapper from './components/ChartWrapper';

export default function Page() {
return <ChartWrapper data={data} />;
}
94 changes: 94 additions & 0 deletions src/content/reference/rsc/use-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,3 +215,97 @@ export default async function incrementLike() {
```

To read a Server Function return value, you'll need to `await` the promise returned.

## Troubleshooting {/*troubleshooting*/}

### "Server Functions cannot be called during render" error {/*server-functions-cannot-be-called-during-render*/}

Server Functions should only be called in response to user actions (like form submissions or button clicks), not during component rendering.

```js
// This will error - calling during render
function BadComponent() {
const data = await serverFunction(); // Don't do this!
return <div>{data}</div>;
}

// Correct - call in response to user action
function GoodComponent() {
const [data, setData] = useState(null);

const handleClick = async () => {
const result = await serverFunction();
setData(result);
};

return <button onClick={handleClick}>Load Data</button>;
}
```

For data fetching during render, use a Server Component instead of a Server Function.

### "Arguments must be serializable" error {/*arguments-must-be-serializable*/}

Server Functions can only receive serializable arguments. You cannot pass functions, class instances, or React elements.

```js
// This will error - functions aren't serializable
async function saveData(callback) {
'use server';
// ...
}

// Correct - pass serializable data
async function saveData(userId, formData) {
'use server';
// ...
}
```

### Server Function not updating the UI {/*server-function-not-updating-ui*/}

If your Server Function runs but the UI doesn't update, make sure you're calling it inside a Transition when outside a form:

```js
import { useTransition } from 'react';

function MyComponent() {
const [isPending, startTransition] = useTransition();

const handleClick = () => {
// Wrap in startTransition for proper UI updates
startTransition(async () => {
await myServerFunction();
});
};

return <button onClick={handleClick} disabled={isPending}>Submit</button>;
}
```

### "use server" directive not working {/*use-server-directive-not-working*/}

The `'use server'` directive must be:
1. At the very beginning of the function body (not before the function)
2. Written with single or double quotes (not backticks)
3. Used only in async functions

```js
// Wrong - directive before function
'use server';
async function myFunction() {
// ...
}

// Correct - directive inside function body
async function myFunction() {
'use server';
// ...
}

// Also correct - at top of file to mark all exports
'use server';

export async function functionA() { /* ... */ }
export async function functionB() { /* ... */ }
```
Loading