class Cat extends React.Component {
render() {
const mouse = this.props.mouse;
return (
<img src="/cat.jpg" style={{ position: 'absolute', left: mouse.x, top: mouse.y }} />
);
}
}
class Mouse extends React.Component {
constructor(props) {
super(props);
this.handleMouseMove = this.handleMouseMove.bind(this);
this.state = { x: 0, y: 0 };
}
handleMouseMove(event) {
this.setState({
x: event.clientX,
y: event.clientY
});
}
render() {
return (
<div style={{ height: '100vh' }} onMouseMove={this.handleMouseMove}>
{/*
Instead of providing a static representation of what <Mouse> renders,
use the `render` prop to dynamically determine what to render.
*/}
{this.props.render(this.state)}
</div>
);
}
}
class MouseTracker extends React.Component {
render() {
return (
<div>
<h1>Move the mouse around!</h1>
<Mouse render={mouse => (
<Cat mouse={mouse} />
)}/>
</div>
);
}
}
// If you really want a HOC for some reason, you can easily
// create one using a regular component with a render prop!
function withMouse(Component) {
return class extends React.Component {
render() {
return (
<Mouse render={mouse => (
<Component {...this.props} mouse={mouse} />
)}/>
);
}
}
}
<DataProvider render={data => (
<h1>Hello {data.target}</h1>
)}/>
class Cat extends React.Component {
render() {
const mouse = this.props.mouse;
return (
<img src="/cat.jpg" style={{ position: 'absolute', left: mouse.x, top: mouse.y }} />
);
}
}
class MouseWithCat extends React.Component {
constructor(props) {
super(props);
this.handleMouseMove = this.handleMouseMove.bind(this);
this.state = { x: 0, y: 0 };
}
handleMouseMove(event) {
this.setState({
x: event.clientX,
y: event.clientY
});
}
render() {
return (
<div style={{ height: '100vh' }} onMouseMove={this.handleMouseMove}>
{/*
We could just swap out the <p> for a <Cat> here ... but then
we would need to create a separate <MouseWithSomethingElse>
component every time we need to use it, so <MouseWithCat>
isn't really reusable yet.
*/}
<Cat mouse={this.state} />
</div>
);
}
}
class MouseTracker extends React.Component {
render() {
return (
<div>
<h1>Move the mouse around!</h1>
<MouseWithCat />
</div>
);
}
}
// The <Mouse> component encapsulates the behavior we need...
class Mouse extends React.Component {
constructor(props) {
super(props);
this.handleMouseMove = this.handleMouseMove.bind(this);
this.state = { x: 0, y: 0 };
}
handleMouseMove(event) {
this.setState({
x: event.clientX,
y: event.clientY
});
}
render() {
return (
<div style={{ height: '100vh' }} onMouseMove={this.handleMouseMove}>
{/* ...but how do we render something other than a <p>? */}
<p>The current mouse position is ({this.state.x}, {this.state.y})</p>
</div>
);
}
}
class MouseTracker extends React.Component {
render() {
return (
<>
<h1>Move the mouse around!</h1>
<Mouse />
</>
);
}
}
<Mouse children={mouse => (
<p>The mouse position is {mouse.x}, {mouse.y}</p>
)}/>
<Mouse>
{mouse => (
<p>The mouse position is {mouse.x}, {mouse.y}</p>
)}
</Mouse>
class MouseTracker extends React.Component {
constructor(props) {
super(props);
this.handleMouseMove = this.handleMouseMove.bind(this);
this.state = { x: 0, y: 0 };
}
handleMouseMove(event) {
this.setState({
x: event.clientX,
y: event.clientY
});
}
render() {
return (
<div style={{ height: '100vh' }} onMouseMove={this.handleMouseMove}>
<h1>Move the mouse around!</h1>
<p>The current mouse position is ({this.state.x}, {this.state.y})</p>
</div>
);
}
}
Mouse.propTypes = {
children: PropTypes.func.isRequired
};
class Mouse extends React.PureComponent {
// Same implementation as above...
}
class MouseTracker extends React.Component {
render() {
return (
<div>
<h1>Move the mouse around!</h1>
{/*
This is bad! The value of the `render` prop will
be different on each render.
*/}
<Mouse render={mouse => (
<Cat mouse={mouse} />
)}/>
</div>
);
}
}
Recommend
React Render Props Use Render Props for Cross-Cutting Concerns
React Hooks FAQ Performance Optimizations How to read an often-changing value from useCallback?
React Hooks FAQ Performance Optimizations How to avoid passing callbacks down?
React Hooks FAQ Performance Optimizations Are Hooks slow because of creating functions in render?
React Hooks FAQ Performance Optimizations How to create expensive objects lazily?
React Hooks FAQ Performance Optimizations How to memoize calculations?
React Hooks FAQ Performance Optimizations How do I implement shouldComponentUpdate?
React Hooks FAQ Performance Optimizations What can I do if my effect dependencies change too often?
React Hooks FAQ From Classes to Hooks How can I measure a DOM node?
React Hooks FAQ From Classes to Hooks Is there something like forceUpdate?
React Hooks FAQ From Classes to Hooks How do I implement getDerivedStateFromProps?
React Hooks FAQ From Classes to Hooks Why am I seeing stale props or state inside my function?
React Hooks FAQ From Classes to Hooks How to get the previous props or state?
React Hooks FAQ From Classes to Hooks Should I use one or many state variables?
React Hooks FAQ From Classes to Hooks Is there something like instance variables?
React Hooks FAQ Adoption Strategy How to test components that use Hooks?
React Forms Controlled Input Null Value
React Forms Handling Multiple Inputs
React Forms The file input Tag
React Forms Controlled Components
Thinking in React Start With A Mock
React Typechecking With PropTypes Function Components
React Typechecking With PropTypes Default Prop Values
React Typechecking With PropTypes Requiring Single Child
React Typechecking With PropTypes PropTypes
React Typechecking With PropTypes
React Lifting State Up Lifting State Up
React Lifting State Up Writing Conversion Functions
React Lifting State Up Adding a Second Input
ReactDOM Reference createPortal()
ReactDOM Reference findDOMNode()
ReactDOM Reference unmountComponentAtNode()
React Release Channels Next Channel Using the Next Channel for Integration Testing
React Uncontrolled Components The file input Tag
React Uncontrolled Components Default Values
React CDN Links Why the crossorigin Attribute?
React Forwarding Refs Displaying a custom name in DevTools
React Forwarding Refs Forwarding refs in higher-order components
React Forwarding Refs Forwarding refs to DOM components
React Using the Effect Hook Tips for Using Effects Tip: Optimizing Performance by Skipping Effects