Skip to content

Instantly share code, notes, and snippets.

@bvaughn
Last active March 19, 2018 10:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bvaughn/e7602e7751908fe3b1d0e66087d8b869 to your computer and use it in GitHub Desktop.
Save bvaughn/e7602e7751908fe3b1d0e66087d8b869 to your computer and use it in GitHub Desktop.
Allowing child components to request side effects in an async-way?
class Example extends React.Component {
// Store the has-been-requested flag in state, since side-effects are tied to a particular render.
// Since this value is managed by React, this will make sure it gets set/reset correctly.
state = {
sideEffectData: {
hasBeenRequested: false,
}
};
componentDidMount() {
this.maybeApplySideEffects();
}
componentDidUpdate(prevProps, prevState) {
this.maybeApplySideEffects();
}
render() {
return this.props.children(this.requestSideEffect);
}
requestSideEffect = () => {
if (this.state.sideEffectData.hasBeenRequested) {
console.warn('Side effect has been requested multiple times during a single render pass');
}
// This value does not impact render, so it's okay to mutate it.
// We'll check it during the commit phase to conditionally apply a side effect.
this.state.sideEffectData.hasBeenRequested = true;
}
maybeApplySideEffects() {
if (this.state.sideEffectData.hasBeenRequested) {
this.state.sideEffectData.hasBeenRequested = false;
// Process phase side-effects now.
// They're safe, since we're in the commit phase.
}
}
}
@bvaughn
Copy link
Author

bvaughn commented Mar 8, 2018

The above gist has (at least one) glaring problem: Side effects won't get applied if the callback is called outside of the render phase. 😄

@bvaughn
Copy link
Author

bvaughn commented Mar 8, 2018

This gist should be disregarded as a silly, late-night idea.

Another potential source of problem would be if a side effect is requested by a child that was rendered previously, after a new child has been rendered (but not yet committed).

@bvaughn
Copy link
Author

bvaughn commented Mar 8, 2018

As Sebastian points out, a child requesting a side-effect during render is a side-effect and so is not an async-safe practice by definition.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment