Last active
July 21, 2018 13:33
-
-
Save mweststrate/495259ef1875c45f327f2856d4b6ee01 to your computer and use it in GitHub Desktop.
React api difference
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Example component: render the current value of a stream. Support switching streams during the lifecycle of the component | |
// N.B. code is untested | |
// Old: | |
class RenderStream extends Component { | |
subscription | |
componentWillMount() { | |
this.subscribeToStream(this.props.stream) | |
} | |
componentWillReceiveProps(nextProps) { | |
if (this.props.stream !== nextProps.stream) { | |
this.subscription.dispose() | |
this.subscribeToStream(nextProps.stream) | |
} | |
} | |
render() { | |
return <div>Current value: {this.state.value}</div> | |
} | |
componentWillUnmount() { | |
this.subscription.dispose() | |
} | |
subscribeToStream(stream) { | |
// assumption: subscribe triggers immediately | |
this.subscription = this.props.stream.subscribe(value => { | |
this.setState({ value }) | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// New | |
class RenderStream extends Component { | |
subscription | |
currentStream // more state needed, see below | |
static getDerivedStateFromProps() { | |
// here I would like to set up subscription | |
// but can't attach a listener as there is no 'this' | |
} | |
render() { | |
// render is harder to reason about: | |
// - this.state.value might not yet be known | |
// (imagine it is an object, then the render func would become more complex to avoid NPE) | |
// - the subscription at this point might be from | |
// a different stream then which we received the value from | |
// | |
// to fix the latter, we could set up subscription as render side effect, | |
// but, yucky. | |
return <div>Current value: {this.state.value}</div> | |
} | |
componentDidMount() { | |
this.subscribeToStream(this.props.stream) | |
} | |
componentDidUpdate(prevProps) { | |
if (prevProps.stream !== this.props.stream) { | |
this.subscription.dispose() | |
this.subscribeToStream(this.props.stream) | |
} | |
} | |
subscribeToStream(stream) { | |
this.currentStream = this.props.stream | |
this.subscription = this.props.stream.subscribe(value => { | |
this.setState({ value }) | |
} | |
} | |
} |
Seems https://github.com/facebook/react/blob/master/packages/create-subscription/README.md can be used to address the above pattern
@JReinhold, thanks for pointing out, updated the gist
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
componentDidUpdate
has aprevProps
argument. Can't you use that and do the same thing as your oldcomponentWillReceiveProps
? Comparing the previous props with the current props, and update the subscription accordingly. Or am I missing something?What I'm proposing is: