How to Use clientAction in Remix for Client-Side Actions
In Remix, use
clientAction to define client-side functions that run in the browser and can be called from your components. It helps you handle user interactions without full page reloads by returning data directly to the client.Syntax
The clientAction function wraps an async function that runs on the client side. You import it from @remix-run/client and define your action logic inside. It returns a callable function you can use in your React components.
Basic syntax parts:
clientAction(async (args) => { ... }): Wraps your async function.- Inside the function, you can perform client-side logic like fetching or state updates.
- Call the returned function in event handlers to trigger the action.
typescript
import { clientAction } from '@remix-run/client'; const myAction = clientAction(async (input) => { // client-side logic here return `Hello, ${input}!`; });
Example
This example shows a button that calls a clientAction to greet the user without reloading the page. The action returns a greeting string that updates the UI.
typescript
import { useState } from 'react'; import { clientAction } from '@remix-run/client'; const greetUser = clientAction(async (name: string) => { return `Hello, ${name}!`; }); export default function Greeting() { const [message, setMessage] = useState(''); async function handleClick() { const result = await greetUser('Friend'); setMessage(result); } return ( <main> <button onClick={handleClick}>Greet</button> <p>{message}</p> </main> ); }
Output
A page with a button labeled 'Greet'. When clicked, the text below changes to 'Hello, Friend!'.
Common Pitfalls
Common mistakes when using clientAction include:
- Trying to use server-only APIs inside the client action (like database calls).
- Not awaiting the client action call, causing UI updates to fail.
- Using
clientActionfor heavy logic better suited for server actions.
Always remember clientAction runs in the browser, so keep it lightweight and client-safe.
typescript
/* Wrong: Using server-only API inside clientAction */ import { clientAction } from '@remix-run/client'; const badAction = clientAction(async () => { // This will fail because 'fetch' to internal API or DB is server-only const data = await fetch('/api/data'); return data.json(); }); /* Right: Use client-safe APIs or fetch external endpoints */ const goodAction = clientAction(async () => { const response = await fetch('https://api.publicapis.org/entries'); return response.json(); });
Quick Reference
Tips for using clientAction in Remix:
- Import from
@remix-run/client. - Wrap async client-side logic only.
- Call the returned function in event handlers with
await. - Do not use server-only APIs inside.
- Use for lightweight UI interactions and client data fetching.
Key Takeaways
Use
clientAction to run async client-side functions in Remix components.Always await the client action call to handle results properly.
Keep client actions lightweight and avoid server-only APIs inside them.
Call client actions in event handlers to update UI without page reloads.
Import
clientAction from @remix-run/client.