![Create React App Officially Deprecated Amid React 19 Compatibility Issues](https://cdn.sanity.io/images/cgdhsj6q/production/04fa08cf844d798abc0e1a6391c129363cc7e2ab-1024x1024.webp?w=400&fit=max&auto=format)
Security News
Create React App Officially Deprecated Amid React 19 Compatibility Issues
Create React App is officially deprecated due to React 19 issues and lack of maintenance—developers should switch to Vite or other modern alternatives.
react-async-actions
Advanced tools
A simple way to handle asynchronous dependencies in React components in apps which use a global state container (e.g. Redux/Mobx/Flux), on client and server.
A simple way to handle asynchronous action dependencies in React components, in apps which use a global state container (e.g. Redux/Mobx/Flux), on client and server.
This library attempts to be as non-obtrusive as possible, providing a simple helper function for server-rendering, to allow the server to wait for all async actions to resolve before calling renderToString
, and a decorator to use on components which depend on actions.
You might want to use this library if your app:
In React, it's very common for components to depend on some data from async actions before they can render.
Just to clarify, an action here is a fairly generic construct, not to be confused with a Redux action, which is just an object. It's more comparible to a MobX action - i.e. some function that sometimes fetches some data, and then sets some state, which React then uses to render component(s).
Actions can be asynchronous, OR synchronous. It could be a Redux action (creator), a MobX action, or any other action which sets state in a global state container.
On the client this can be done fairly easily because of how React.render
works. The actions simply get fired off when the component mounts
, state is changed somewhere, and the app can keep re-rendering as state changes.
However on the server the rendering scenario is completely different. The server needs to render only once to a string
, then send that markup to the client as soon as possible.
So when a component needs to wait for some data from an async action, out of the box ReactDOM.renderToString
will render the whole app to a html string, firing off any actions you might have in componentWillMount
, then when the actions complete and modify the state, there's nothing to cause another re-render. Usually this can be solved by either:
route
on the server before rendering, which can be hard to maintain.This library attempts to solve this problem in a fairly simple way. By listing your action dependencies for each component explicitly, and returning promises
from any async actions, we can watch and wait for those promises
to resolve on the server (only promises are supported at the moment).
As i mentioned above - the actions simply get fired off on componentDidMount
. It's up to you to handle any loading states - no props are passed down to your component.
We call ReactDOM.renderToStaticMarkup
to reliably work out which actions need to fire. Because it actually renders the app - it runs componentWillMount
on the right components.
When the actions have been resolved and the state has been set, you can simply call ReactDOM.renderToString
and send the resulting markup back to the client.
In most situations it would only take 1 render pass to resolve all promises in your app. If you know how many passes it should take then you can set that via the maxPasses
property. So a common case would be maxPasses: 1
Each components' actions get fired only once, although it may take multiple render passes to fire off all actions if there are chains of async dependencies.
An async dependency chain is described by the following scenario:
Component A
Component B
when data is availableComponent B
Component A
's action has resolved.Component A
's, then its own.This would take 2/3 passes to guarantee all promises have been resolved.
A
and fires off its actions.A
and B
, skipping A
's actions (as they have already been fired), and fires off B
's actions.maxPasses
has not been set) renders A
and B
to check no other components with async dependencies have been rendered.How many passes your app needs to render is completely down to design. It's best to avoid these chains of async dependencies where possible, as it increases loading time on both client server. This could be done by defining all action dependencies at the Route Component
level for example.
npm install react-async-actions --save
UserComponent.js
import { connect } from 'react-redux';
import { asyncActions } from 'react-async-actions';
const mapStateToProps = (state) => ({
id: state.user.id,
name: state.user.name
});
const mapDispatchToProps = { getUserName };
const actionsToFire = (props) => [
props.getUserName(props.id)
];
@connect(mapStateToProps, mapDispatchToProps)
@asyncActions(actionsToFire)
class User extends Component {
render() {
// Need this.props.name here
}
}
server.js
import { fireAsyncActions } from 'react-async-actions';
import { Provider } from 'react-redux';
import store from './store';
const element = (
<Provider store={store}>
<App />
</Provider>
);
const options = {
maxPasses: 1
};
fireAsyncActions(element, options)
.then(() => {
// Promises will be resolved at this point, store will be up to date
// Now can do one final render to generate the full markup from the initialised state
const markup = renderToString(element);
// ...
});
UserComponent.js
import { observer, inject } from 'mobx-react';
import { asyncActions } from 'react-async-actions';
const mapStateToProps = (stores, ownProps) => ({
id: stores.user.id,
name: stores.user.name,
getUserName: stores.user.getUserName
});
const actionsToFire = (props) => [
props.getUserName(props.id)
];
@inject(mapStateToProps)
@asyncActions(actionsToFire)
@observer
class User extends Component {
// Need this.props.name here
}
server.js
import { fireAsyncActions } from 'react-async-actions';
import { Provider } from 'mobx-react';
import stores from './stores';
const element = (
<Provider {...stores}>
<App />
</Provider>
);
const options = {
maxPasses: 1
};
fireAsyncActions(element, options)
.then(() => {
// Promises will be resolved at this point, store will be up to date
// Now can do one final render to generate the full markup from the initialised state
const markup = renderToString(element);
// ...
});
Component decorator, takes in a function with a props
parameter.
default: Inifinity
MIT
FAQs
A simple way to handle asynchronous dependencies in React components in apps which use a global state container (e.g. Redux/Mobx/Flux), on client and server.
The npm package react-async-actions receives a total of 2 weekly downloads. As such, react-async-actions popularity was classified as not popular.
We found that react-async-actions demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Create React App is officially deprecated due to React 19 issues and lack of maintenance—developers should switch to Vite or other modern alternatives.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.