Render props is a React pattern where a component receives a function prop that returns JSX for part of its output. The component supplies state or other values to that function, which decides what to render. section 6.2.4
A button that chooses its icon
A Button component tracks whether it is pressed, then calls getIcon(pressed). LockButton supplies a function that returns a lock or unlock Icon. This keeps the button reusable while allowing callers to control part of its content. section 6.2.4
Listing 6.7 A push button with an icon function
import { useState } from "react";
function Icon({ type }) { #1
return <img src={`/images/${type}.png`} width="16" alt="" />;
}
function Button({ label, getIcon }) {
const [pressed, setPressed] = useState(false);
return (
<button onClick={() => setPressed((p) => !p)}>
{getIcon(pressed)} #2
{label}
</button>
);
}
function LockButton() {
const getIcon = (pressed) => #3
pressed ? <Icon type="lock" /> : <Icon type="unlock" />; #3
return <Button label="Lock" getIcon={getIcon} />;
}
function App() {
return <LockButton />;
}
Inspect the complete push-button example, including state, the getIcon function, and the conditional lock icons. section 6.2.4
Prefer the simpler alternative when the rendering function only solves a local component problem:
- Pass a component such as ButtonIcon instead, and give it pressed as a prop. section 6.2.4
- Expect render props in older React codebases, generic components, or the non-hook React Context API. section 6.2
- Use functional components and useContext when possible rather than relying on the non-hook Context API. section 6.2.4
