There’s three patterns in React that are meant to be used in case that you want to decouple generic logic, so, this can be shared with others as a library, gist or whatever you want.
Those patterns are Render Props, Function as Child and HOCs. Each of them has its own uses cases plus pros and cons.
I’m going to explain you those patterns and its use cases based on a simple example. We’re going to wrap request animation frame into a component using a different pattern.
The idea behind this pattern is that you’ve to build a Stateful Component that wraps logic, the result of the execution of this logic is shared by a callback.
This callback is a prop used by the component you build, and the prop is normally called render.
import React from 'react';import ReactDOM from 'react-dom';const styles = {fontFamily: 'sans-serif',textAlign: 'center',};class RequestAnimationFrame extends React.Component {state = {timeStamp: 0,};componentDidMount() {requestAnimationFrame(timeStamp =>this.setState({timeStamp,}));}render() {return this.props.render(this.state.timeStamp);}}const App = () => (<div style={styles}><RequestAnimationFrame render={timeStamp => <h1>{timeStamp}</h1>} /></div>);ReactDOM.render(<App />, document.getElementById('root'));
It’s pretty similar to Render props pattern, but it differs in the way that it renders.
With Function as Child you use the children prop that it’s present in every component you define to behave like a function, instead of using a callback passed as prop.
It shares all the pros/cons and use cases from render prop. So, the usage of one or another, really depends on what you like the most.
import React from 'react';import ReactDOM from 'react-dom';const styles = {fontFamily: 'sans-serif',textAlign: 'center',};class RequestAnimationFrame extends React.Component {state = {timeStamp: 0,};componentDidMount() {requestAnimationFrame(timeStamp =>this.setState({timeStamp,}));}render() {if (typeof this.props.children !== 'function') {throw 'Children should be a Function!';}return this.props.children(this.state.timeStamp);}}const App = () => (<div style={styles}><RequestAnimationFrame>{timeStamp => <h1>{timeStamp}</h1>}</RequestAnimationFrame></div>);ReactDOM.render(<App />, document.getElementById('root'));
The HOC pattern is the oldest pattern, it was intended to be a replace of mixins when React transition from having it’s own class model to use ES2015 classes.
The idea behind a HOC is completely similar to the idea of High Order Functions from Functional Programming paradigm.
In simple words, a HOF is a function that returns another function that enhances the ones you passes to it. In the case of HOC, it’s just a function that takes a Component and returns a new one with steroids.
import React from 'react';import ReactDOM from 'react-dom';const styles = {fontFamily: 'sans-serif',textAlign: 'center',};const withRequestAnimationFrame = _ => WrappedComponent => {class RequestAnimationFrame extends React.Component {state = {timeStamp: 0,};componentDidMount() {requestAnimationFrame(timeStamp =>this.setState({timeStamp,}));}render() {return (<WrappedComponent {...this.props} timeStamp={this.state.timeStamp} />);}}return RequestAnimationFrame;};const App = props => (<div style={styles}><h1>{props.timeStamp}</h1></div>);const EnhancedApp = withRequestAnimationFrame()(App);ReactDOM.render(<EnhancedApp />, document.getElementById('root'));
Subscribe for latest updates
Sign Up for our newsletter and get notified when we publish new articles for free!