Skip to content

Instantly share code, notes, and snippets.

@ivanbtrujillo
Created February 9, 2018 15:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ivanbtrujillo/2c4aca4cbd5101d7a64aa25a830a0da9 to your computer and use it in GitHub Desktop.
Save ivanbtrujillo/2c4aca4cbd5101d7a64aa25a830a0da9 to your computer and use it in GitHub Desktop.
Render Props VS HOC
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Compare HOC and Render Props</title>
</head>
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@16.0.0/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.0.0/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script type="text/babel">
const rootElement = document.getElementById('root');
// A simple presentational component
const Animal = ({ image, mouse }) => (
<img
src={image === 'cat' ? 'http://www.pngmart.com/files/1/Cat-PNG-Photos.png' : 'http://www.macanesentrenamientocanino.com/wp-content/uploads/2015/01/Akita-Inu.png'}
style={{ position: 'absolute', height: '100px', left: mouse.x, top: mouse.y }}
/>
)
// This is our component Mouse and it uses Render Props.
// Render Prop is a function that receives the state of the component.
// This function can be used from the parent component to get the state of Mouse component and
// pass to another component.
class Mouse extends React.Component{
state= {
x: 0,
y:0
}
handleMouseMove = ({clientX, clientY }) => this.setState({x: clientX, y: clientY})
render(){
const { x,y } = this.state;
return (
<div style={{ background: 'white', height: '100vh'}} onMouseMove={this.handleMouseMove} >
{this.props.render(this.state)}
</div>
)
}
}
// EXAMPLE OF USE RENDER PROPS
// Here we use the Mouse component and as we said, we have a render prop. This render prop is a function that emits the state of the
// Mouse component. This allow us to pass down that state to the Animal component.
// Look at {this.props.render(this.state)} in Mouse component. Here is were we inject the state into the render prop
class AppRenderProps extends React.Component {
state = {
image: 'cat'
}
toggleImage = () => {
const { image } = this.state;
this.setState({image: image === 'cat' ? 'dog' : 'cat'});
}
render(){
const { image } = this.state;
return (
<div>
<h1> Mueve el raton!</h1>
<button onClick={this.toggleImage}>Usar {image === 'cat' ? 'dog' : 'cat'} </button>
<Mouse render={ mouseState => <Animal mouse={mouseState} image={image} /> } />
</div>
)
}
}
// USING COMPONENT WITH RENDER PROPS AS A HOC
// We can use Render Props as a HOC. We just need to create a function that receives a component.
// That component will be the component that will be rendered in the render prop
const withMouse = (Component) => {
return class extends React.Component {
state = {
image: 'cat'
}
toggleImage = () => {
const { image } = this.state;
this.setState({image: image === 'cat' ? 'dog' : 'cat'});
}
render() {
const { image } = this.state;
return (
<div>
<h1> Mueve el raton!</h1>
<button onClick={this.toggleImage}>Usar {image === 'cat' ? 'dog' : 'cat'} </button>
<Mouse render={mouse => (
<Component {...this.props} mouse={mouse} image={image} />
)}/>
</div>
);
}
}
}
// HIGHER ORDER COMPONENT
// Here we overload the Animal presentational component with the Mouse component using the HOC with mouse.
// This give us the AppHOC, the final component
const AppHOC = withMouse(Animal);
// ReactDOM.render(<AppHOC />, rootElement); // --> Created using HOC
ReactDOM.render(<AppRenderProps />, rootElement); // --> Created using Render props
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment