What is react-side-effect?
The react-side-effect package is a utility for creating higher-order components that handle side effects in React applications. It allows you to manage side effects in a declarative way, ensuring that they are handled consistently and predictably.
What are react-side-effect's main functionalities?
Creating a Side Effect Component
This feature allows you to create a higher-order component that manages side effects. The `reducePropsToState` function combines all props into a single state object, and the `handleStateChangeOnClient` function handles the side effect on the client.
const withSideEffect = require('react-side-effect');
function reducePropsToState(propsList) {
// Combine all props into a single state object
return propsList.reduce((acc, props) => ({ ...acc, ...props }), {});
}
function handleStateChangeOnClient(state) {
// Handle the side effect on the client
console.log('State changed:', state);
}
const SideEffectComponent = withSideEffect(reducePropsToState, handleStateChangeOnClient)(MyComponent);
Using the Side Effect Component
Once you have created the side effect component, you can use it in your React application like any other component. The side effects will be managed according to the logic defined in the higher-order component.
<SideEffectComponent prop1="value1" prop2="value2" />
Other packages similar to react-side-effect
react-helmet
react-helmet is a package that manages changes to the document head, such as title and meta tags, in a declarative way. It is similar to react-side-effect in that it handles side effects, but it is specifically focused on managing the document head.
redux-saga
redux-saga is a middleware library for managing side effects in Redux applications. It uses generator functions to handle asynchronous actions and side effects. While it is more complex than react-side-effect, it provides powerful tools for managing side effects in a Redux-based application.
react-use
react-use is a collection of React hooks that includes hooks for managing side effects, such as useEffectOnce and useAsync. It provides a more granular approach to managing side effects compared to react-side-effect, which focuses on higher-order components.
React Side Effect
Create components whose prop changes map to a global side effect.
Installation
npm install --save react-side-effect
Use Cases
- Setting
document.style.overflow
or background color depending on current screen; - Firing Flux actions using declarative API depending on current screen;
- Some crazy stuff I haven't thought about.
How's That Different from componentDidUpdate
?
It gathers current props across the whole tree before passing them to side effect. For example, this allows you to create <BodyStyle style>
component like this:
return (
<BodyStyle style={{ backgroundColor: 'red' }}>
{this.state.something ? <SomeComponent /> : <OtherComponent />}
</BodyStyle>
);
return (
<BodyStyle style={{ backgroundColor: this.state.color }}>
<div>Choose color: <input valueLink={this.linkState('color')} /></div>
</BodyStyle>
);
and let the effect handler merge style
from different level of nesting with innermost winning:
var BodyStyle = createSideEffect(function handleChange(propsList) {
var style = {};
propsList.forEach(function (props) {
Object.assign(style, props.style);
});
for (var key in style) {
document.style[key] = style[key];
}
});
API
createSideEffect: (onChange: Array<Props> -> (), mixin: Object?) -> ReactComponent
Returns a component that, when mounting, unmounting or receiving new props, calls onChange
with props
of each mounted instance.
It's up to you to reduce
them, use innermost values, or whatever you fancy.
Component will have a static dispose()
method to clear the stack of mounted instances.
When rendering on server, you must call it after each request.
You can use optional second mixin
parameter to specify propTypes
, displayName
or statics
. It will be mixed into the generated component.
Usage
Here's how to implement React Document Title (both client and server side) using React Side Effect:
'use strict';
var React = require('react'),
createSideEffect = require('react-side-effect');
function extractTitle(propsList) {
var innermostProps = propsList[propsList.length - 1];
if (innermostProps) {
return innermostProps.title;
}
}
var _serverTitle = null;
var DocumentTitle = createSideEffect(function handleChange(propsList) {
var title = extractTitle(propsList);
if (typeof document !== 'undefined') {
document.title = title || '';
} else {
_serverTitle = title || null;
}
}, {
displayName: 'DocumentTitle',
propTypes: {
title: React.PropTypes.string.isRequired
},
statics: {
peek: function () {
return _serverTitle;
},
rewind: function () {
var title = _serverTitle;
this.dispose();
return title;
}
}
});
module.exports = DocumentTitle;