Michael Jackson on stepping away from HOCs, and using a render
Prop instead.
instead of “mixing in” or decorating a component to share behavior, just render a regular component with a function prop that it can use to share some state with you.
He start with this HOC:
import React from 'react'
import ReactDOM from 'react-dom'
const withMouse = (Component) => {
return class extends React.Component {
state = { x: 0, y: 0 }
handleMouseMove = (event) => {
this.setState({
x: event.clientX,
y: event.clientY
})
}
render() {
return (
<div style={{ height: '100%' }} onMouseMove={this.handleMouseMove}>
<Component {...this.props} mouse={this.state}/>
</div>
)
}
}
}
const App = React.createClass({
render() {
// Instead of maintaining our own state,
// we get the mouse position as a prop!
const { x, y } = this.props.mouse
return (
<div style={{ height: '100%' }}>
<h1>The mouse position is ({x}, {y})</h1>
</div>
)
}
})
// Just wrap your component in withMouse and
// it'll get the mouse prop!
const AppWithMouse = withMouse(App)
ReactDOM.render(<AppWithMouse/>, document.getElementById('app'))
… which can be rewritten like this:
import React from 'react'
import ReactDOM from 'react-dom'
import PropTypes from 'prop-types'
// Instead of using a HOC, we can share code using a
// regular component with a render prop!
class Mouse extends React.Component {
static propTypes = {
render: PropTypes.func.isRequired
}
state = { x: 0, y: 0 }
handleMouseMove = (event) => {
this.setState({
x: event.clientX,
y: event.clientY
})
}
render() {
return (
<div style={{ height: '100%' }} onMouseMove={this.handleMouseMove}>
{this.props.render(this.state)}
</div>
)
}
}
const App = React.createClass({
render() {
return (
<div style={{ height: '100%' }}>
<Mouse render={({ x, y }) => (
// The render prop gives us the state we need
// to render whatever we want here.
<h1>The mouse position is ({x}, {y})</h1>
)}/>
</div>
)
}
})
ReactDOM.render(<App/>, document.getElementById('app'))
Interesting approach I’d say 🙂
You can watch the video (embedded above) or read the post.
Sidenote: Talking about React Props: Validating Props easily with React PropTypes is worth a read if you’re not using them (yet).