Flat Preloader Icon

Render Props

Render props is a pattern in React that allows you to share code between components using a prop whose value is a function. This function receives props from the parent component and returns a React element, enabling more flexible and reusable component designs.

Basics of Render Props

A render prop is a function prop that a component uses to know what to render.
				
					// MouseTracker.js
import React from 'react';

class MouseTracker extends React.Component {
  constructor(props) {
    super(props);
    this.state = { x: 0, y: 0 };
    this.handleMouseMove = this.handleMouseMove.bind(this);
  }

  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 <MouseTracker> renders,
          use the `render` prop to dynamically determine what to render.
        */}
        {this.props.render(this.state)}
      </div>
    );
  }
}

export default MouseTracker;

				
			
In the above example, the MouseTracker component takes a render prop, which is a function. This function is called inside the render method of MouseTracker, allowing it to determine what to render based on the current state.

Usage

				
					// App.js
import React from 'react';
import MouseTracker from './MouseTracker';

function App() {
  return (
    <div>
      <h1>Move the mouse around!</h1>
      <MouseTracker render={({ x, y }) => (
        <h2>The mouse position is ({x}, {y})</h2>
      )}/>
    </div>
  );
}

export default App;

				
			

Advantages of Render Props

  • Code Reusability: Render props allow you to reuse component logic in a flexible way.
  • Separation of Concerns: They help separate the logic from the view, making the code more maintainable.
  • Flexibility: You can define what to render dynamically based on the state or props passed to the render prop function.

Common Patterns with Render Props

Higher-Order Components (HOCs)
Render props can often be an alternative to HOCs. While HOCs wrap a component to enhance its behavior, render props allow you to achieve similar outcomes by passing a function.

Example Comparison (HOCs)
HOC
				
					function withMouse(Component) {
  return class extends React.Component {
    constructor(props) {
      super(props);
      this.state = { x: 0, y: 0 };
      this.handleMouseMove = this.handleMouseMove.bind(this);
    }

    handleMouseMove(event) {
      this.setState({
        x: event.clientX,
        y: event.clientY
      });
    }

    render() {
      return (
        <div style={{ height: '100vh' }} onMouseMove={this.handleMouseMove}>
          <Component {...this.props} mouse={this.state} />
        </div>
      );
    }
  }
}

				
			

Render Prop

				
					<MouseTracker render={mouse => (
  <MyComponent mouse={mouse} />
)}/>

				
			
Controlled Components
Render props can also help with creating controlled components, where you manage state outside the component.
				
					class ControlledInput extends React.Component {
  render() {
    return (
      <input
        type="text"
        value={this.props.value}
        onChange={this.props.onChange}
      />
    );
  }
}

function App() {
  const [value, setValue] = React.useState('');

  return (
    <ControlledInput
      value={value}
      onChange={e => setValue(e.target.value)}
    />
  );
}

				
			

Conclusion

Render props offer a powerful pattern for sharing code between React components, enhancing reusability, and keeping your codebase clean and maintainable. They provide an alternative to HOCs and allow you to build more flexible and dynamic components.