A higher-order component is a function that takes a component and returns a new component.
const EnhancedComponent = higherOrderComponent(WrappedComponent);
HOCs are common in third-party React libraries, such as Redux’s connect and Relay’s createFragmentContainer.
We want an abstraction that allows us to define this logic in a single place and share it across many components. This is where higher-order components excel.
Note that a HOC doesn’t modify the input component, nor does it use inheritance to copy its behavior. Rather, a HOC composes the original component by wrapping it in a container component. A HOC is a pure function with zero side-effects.
Tip: Resist the temptation to modify a component’s prototype (or otherwise mutate it) inside a HOC.
- Use when there’s an opportunity to package up a repeating pattern
- Make debugging easier by updating the displayName of the returned Component
- Pass through props unrelated to the HOC
- Overuse. Another pattern may be more appropriate.
- Mutate the original Component
- Use inside the render method
- refs aren’t passed through
- static methods must be copied over
- Most HOCs can be written with render props and vice versa!
Stateful vs Stateless Components
Container components will be high level components. Some basic characteristic of container components are:
- Concerned with how things work
- Usually do not include any HTML markup — aside from wrapping divs around other components
- Manage state — they are STATEFUL
- Provide data (by storing it in their state and passing it as prop) and tell their ‘children’ how to behave (by passing callback functions as props)
Children components of container components are usually presentational components:
- Concerned with presenting data — how things look
- Usually are STATELESS — but not always
- Most likely a ‘child’ of a container component
- Will make up the majority of your application
Example, in a ToDo List application:
- TaskContainer — a stateful, container component, responsible for storing application data, defining functions on how the application will behave and passing those functions down to child components.
- TaskForm — a stateful, presentational component, responsible for rendering form, gathering user input and does something with that input based on the props the parent container has passed down to it.
- TaskList — a stateless, presentational component, responsible for iterating through the data to be rendered.
- TaskItem — a stateful, presentational component, responsible for rendering tasks that have not yet been completed.
- CompletedTaskItem — a stateless, presentational component, responsible for rendering tasks that have been completed.