Skip to content

Instantly share code, notes, and snippets.

@dounan
Last active February 16, 2024 08:34
Show Gist options
  • Save dounan/00b0c93eeae2e509111faf547ea7f5e1 to your computer and use it in GitHub Desktop.
Save dounan/00b0c93eeae2e509111faf547ea7f5e1 to your computer and use it in GitHub Desktop.
HOC to HOF analogy
// Motivated by https://twitter.com/mjackson/status/885910553432018945
// There are two ways to apply higher-order logic to components.
// 1. Use a HOC
// 2. Use a generic component that takes a `render` callback.
// To illustrate how these work, we will use the the analogy that a
// component is just `view = fn(data)`. A HOC can then be simply seen as a
// HOF that returns another function (most likely with some partial
// application).
// Imagine you have a "component" that increments its value.
function incrementFn(val) {
return val + 1;
}
// How do you use your increment "component" to render an *array* of items?
// -----------------------------------------------------------------------------
// 1. Use a HOC
// Define a "HOC" that renders each item in a list with the wrapped "component".
// This HOC partially applies the `childFn` to `map`.
function mapHOF(childFn) {
return array => array.map(childFn);
}
// Let's wrap it with mapHOF
const incrementAllFn = mapHOF(incrementFn);
// Final solution:
render() {
return incrementAllFn([1, 2, 3]);
}
// -----------------------------------------------------------------------------
// 2. Use a "render" callback
// Define a generic component that renders an array with a callback.
function mapFn(array, renderFn) {
return array.map(renderFn);
}
// Final solution:
render() {
return mapFn([1, 2, 3], incrementFn);
}
// -----------------------------------------------------------------------------
// Both approaches have their own benefits. A big benenfit of using a HOC is
// that it hides the implementation details. In the example aboce, the user of
// the wrapped `incrementAllFn` doesn't have to know anything about `map`.
// However, a big downside of HOC is that in the React world, setting up a HOC
// is not trivial: extra component instance, pass through props, pass through
// refs, hoisting static methods.
// tl;dr - neither approach is strictly better, but remember that HOC is not the
// only answer.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment