
Security News
Deno 2.2 Improves Dependency Management and Expands Node.js Compatibility
Deno 2.2 enhances Node.js compatibility, improves dependency management, adds OpenTelemetry support, and expands linting and task automation for developers.
@shopify/react-effect
Advanced tools
A component and set of utilities for performing effects within a universal React app
@shopify/react-effect
This package contains a component and set of utilities for performing multiple effects during one single pass of server rendering in a universal React application.
$ yarn add @shopify/react-effect
<Effect />
This package is largely built around a component, Effect
. To set up an action to be performed, use the perform
prop:
import {Effect} from '@shopify/react-effect';
export default function MyComponent() {
return <Effect perform={() => console.log('Doing something!')} />;
}
By default, this callback will run in two ways:
componentDidMount
extract
function documented belowThis callback can return anything, but returning a promise has a special effect: it will be waited for on the server when calling extract()
.
This component accepts three additional optional properties:
kind
: a symbol detailing the "category" of the effect. This will be used to optionally skip some categories when calling extract()
clientOnly
: will only call the effect in componentDidMount
, not when extracting on the serverserverOnly
: will only call the effect during extraction, not in componentDidMount
This component also accepts children which are rendered as-is.
extract()
You can call extract()
on a React tree in order to perform all of the effects within that tree. This function uses the react-tree-walker
package to perform the tree walk, which creates some implications for the return value of your perform
actions:
false
will prevent the rest of the tree from being processedThis function returns a promise that resolves when the tree has been fully processed.
import {renderToString} from 'react-dom/server';
import {extract} from '@shopify/react-effect/server';
async function app(ctx) {
const app = <App />;
await extract(app);
ctx.body = renderToString(app);
}
You may optionally pass a second argument to this function: an array of symbols representing the categories to include in your processing of the tree (matching the kind
prop on Extract
components).
import {renderToString} from 'react-dom/server';
import {EFFECT_ID as I18N_EFFECT_ID} from '@shopify/react-i18n';
import {extract} from '@shopify/react-effect/server';
async function app(ctx) {
const app = <App />;
// will only perform @shopify/react-i18n extraction
await extract(app, [I18N_EFFECT_ID]);
ctx.body = renderToString(app);
}
Usually, the Extract
component will do what you need, but you may occasionally need your own component to directly implement the "extractable" part. This can be the case when your component must do something in extract
that ends up calling setState
. In these cases, you can use two additional exports from this module, METHOD_NAME
and the Extractable
interface, to manually implement a method that will be called during extraction:
import {METHOD_NAME, Extractable} from '@shopify/react-effect';
export const EFFECT_ID = Symbol('MyComponentEffect');
class MyComponent extends React.Component implements Extractable {
[METHOD_NAME](include: boolean | symbol[]) {
// When implementing your own version of this, you should
// implement your own check for the effect "kind". The
// Effect component does this automatically.
if (
include === true ||
(Array.isArray(include) && include.includes(EFFECT_ID))
) {
this.setState({extracting: true});
}
}
}
A common mistake is initializing a provider entirely within your application component, and setting some details on this provider during the extraction. There is nothing implicitly wrong with this, but it will usually not have the effect you are after. When you call renderToString()
to actually generate your HTML, the app will be reinitialized, and all of the work you did in the extraction call will be lost. To avoid this, pass any "stateful" managers/ providers into your application:
class StatefulManager {}
const {Provider, Consumer} = React.createContext();
// bad
export default function App() {
return (
<Provider value={new StatefulManager()}>
<Consumer>
{manager => <Effect perform={() => (manager.value = true)} />}
</Consumer>
</Provider>
);
}
const app = <App />;
await extract(app);
// All your work is lost now, because the components are reinitialized
renderToString(app);
// good
export default function App({manager}) {
return (
<Provider value={manager}>
<Consumer>
{manager => <Effect perform={() => (manager.value = true)} />}
</Consumer>
</Provider>
);
}
const manager = new StatefulManager();
const app = <App manager={manager} />;
await extract(app);
// All your work is preserved, because you passed in the same manager
renderToString(app);
FAQs
A component and set of utilities for performing effects within a universal React app
The npm package @shopify/react-effect receives a total of 37,694 weekly downloads. As such, @shopify/react-effect popularity was classified as popular.
We found that @shopify/react-effect demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers 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
Deno 2.2 enhances Node.js compatibility, improves dependency management, adds OpenTelemetry support, and expands linting and task automation for developers.
Security News
React's CRA deprecation announcement sparked community criticism over framework recommendations, leading to quick updates acknowledging build tools like Vite as valid alternatives.
Security News
Ransomware payment rates hit an all-time low in 2024 as law enforcement crackdowns, stronger defenses, and shifting policies make attacks riskier and less profitable.