Actions are nothing new, but they’re making a comeback in the world of JavaScript frontends.
At the React conference livestreamed from Las Vegas earlier this month, the React compiler and React 19 were the focus of attention. But buried in the presentations was talk of React Actions. Then last week, Astro announced its own support for actions, which Astro front-end developer Ben Holmes said on Twitter are similar to React Actions.
“This is how you define an RPC endpoint in Astro,” Holmes says. It takes the basics of a server action and adds error handling and input validation.”
Andrew Clark, a software engineer at Vercel and a core contributor to React, pointed out at the React conference that these actions have been around for a while.
“Actions are a first-class pattern for asynchronously updating data in your application in response to user input,” says Clark. “Actions as a general pattern weren’t invented by React; they’ve been part of the web platform for decades. In fact, HTML form actions were first introduced on the web back in the 1900s.”
Ouch. Yes, he said it was introduced by cowboys in the 1900s, the Wild West. For you historians, that was before JavaScript was created.
HTML form actions were a way to add interactivity to web pages. In traditional HTML forms, developers specified a server endpoint by passing a URL to the action property, Clark explained. When a user submitted the form, the data was sent to the server, and the server responded with a new HTML page.
“Submit a form, load a page, submit a form, load a page — it’s pretty simple, right? The great thing about this model is that you can build just about anything,” he said.
However, since JavaScript came online, actions are not used much anymore.
“Today, web developers can go their entire careers without ever using these APIs,” he says. “What happened was that the introduction of JavaScript — and we all love JavaScript — made it possible to build client-focused web apps that provided much richer, more interactive experiences than apps that were strictly server-only.”
User expectations have also changed: users want immediate feedback on their app interactions, and they don’t want to wait for a completely new HTML document every time, he says. Users want apps to remember their current state so that they don’t lose their scroll position or text input every time they perform an action.
“In other words, users expect more than can be achieved without at least some client-side interaction,” he says. “Client-side event handlers have several advantages: they can be used to implement rich, immediate feedback on user input, and client and server behavior can be composed together.”
But a JavaScript-only approach also has drawbacks, such as difficulty managing local state. Asynchronicity is also difficult to achieve and often leads to bugs, he said. And because event handlers rely on JavaScript, the UI isn’t interactive until the code is loaded and executed, which is slower than raw HTML and leads to lost interaction, he added. Because the app is interactive as soon as the HTML is rendered, it’s tempting to go back to plain HTML actions.
“Let’s not forget why we moved away from actions in the first place,” he says. “Actions provide little to no immediate feedback on user input. You’re essentially limited to what the standard browser controls offer. And because it’s an entirely different programming model, it’s very hard to sprinkle in additional client interaction.”
React exists to solve just those kinds of mysteries, Clark said.
So… wait. why Does React add an action?
This month, React Actions migrated to React from the Canary channel, where it had been present since last summer.
“You may have heard of it in the context of the server actions feature available in server component frameworks like Next.js, but actions are not limited to server component frameworks,” Clark said.
He says React Actions are an evolution of two existing APIs. The first is React Transitions, which are used to update state without blocking user input. Actions build on Transitions by adding support for asynchronous functions. The second is the HTML Forms API.
“Using React actions is very similar to using HTML form actions, but instead of passing a URL to the action property, you can now pass a function,” he says. “In the most basic example, you just pass a function to the action property and the action will run when the user submits the form. Using an action function instead of a URL allows you to define the action’s behavior directly within your component.”
“We’re seeing a resurgence of action-inspired APIs within the JavaScript community, thanks to the Remix and React frameworks,” Clark said. Actions have been reintroduced as a pattern for communication between servers and clients, he added.
“These days it seems like almost every JavaScript web framework has its own interpretation of the action pattern,” he said. “And there’s good reason for that. We think actions are a great way to structure applications and fit perfectly into the React programming model.”
He pointed out that this raises the question: if an action-based API already exists in the React framework, why build it into React?
The React team believes that even more can be done by integrating Actions into React without compromising the composability of Read, with features like:
- Streaming SSR
- Selective hydration
- Suspense and Transitions
“There’s nothing special about action functions; they’re regular functions. Just like any other function, you can compose them, write abstractions about them, define actions on the client, or if you use a server component framework, you can define actions on the server with the use server directive and access the data layer directly,” he said. “You can have any number of actions per page, per component, whatever, and you can swap actions out at runtime.”
He added that this level of “maximum configurability” was achieved because the React team “integrated Actions into every layer of React, from the client runtime to the streaming SSR renderer to the server component data formats, all working together to provide a seamless experience.”
“Our goal is to provide core primitives that meta-frameworks like Remix, Next and Redwood can build on top of in the same way that they currently build features like Streaming and Suspense,” he said.
Where React Actions Shine
React actions are a lot like HTML actions, but they are also similar to event handlers: When sendingor Click Unclick“That’s what we’re doing,” Clark said.
“Despite the superficial similarities, actions have some important features that set them apart from regular event handlers,” he continues. “One such feature is support for progressive enhancement: form actions in React are interactive before hydration occurs. Believe it or not, this works for all actions, not just those defined on the server.”
If the user interacts with a client action before hydration is complete, React queues the action and plays it as soon as it’s streamed. If the user interacts with a server action, the action can immediately trigger normal browser navigation, without hydration or JavaScript.
Actions can also handle asynchronous logic, he said.
“React Actions have built-in support for UX patterns like optimistic UI and error handling,” he says. “Actions make these complex UX patterns incredibly simple by deeply integrating with React features like suspense and transitions. Actions are easily configurable, have unified client and server APIs, are interactive even before hydration, and allow you to implement advanced UX with just a few lines of code.”
YOUTUBE.COM/THENEWSTACK
Technology is evolving quickly, so don’t miss an episode. Subscribe to our YouTube channel to stream all our podcasts, interviews, demos, and more.
subscribe