Santa React patterns giveaway — 2nd week

Danijel Vincijanovic
COBE
Published in
5 min readDec 21, 2018

--

It’s that time of the year when everyone is sharing love and gif(t)s with their closest ones. Such a pitty that I can only send you a browser cookie and not a real one; instead, I will share four React patterns that I would like you to take home and start using at the beginning of the next year.

New year, new pledges and new React patterns; every week until New Year’s Eve, I will reveal one React pattern that every React developer should know.

If you came across a problem (read challenge) while writing React components and if I faced the same problem as you, then it’s very likely that we’ve solved it in a similar way. Thus, we have a common software problem that we can solve using the same pattern. We can give it a name, describe it and share with other developers so that they can speed up their development process by using an already proven pattern; and this is what we call design patterns.

Last week we brought the Render Props pattern to you, in case you’ve missed it, check it out here.

This week we’ll explore a pattern called Higher Order Component!

Prerequisite: Higher Order Function

Before diving into the Higher Order Component pattern, we should be familiar with a concept from functional programminghigher order functions.

How can we know that some function is a higher order function?
If it accepts a function as an argument OR returns another function, then it’s a higher order function. You might, already, be familiar with some examples, such as .map ,.filter or .reduce

In React, we use .map quite often for rendering a list.

const randomGifts = ['cookie', 'chocolate', 'lollipop']const gifts = randomGifts.map(function (gift) {
return <li>Santa gives you a {gift}</li>)
}

In the example above, the .map function accepts a function as an argument (often referred as a callback). This function will be called for each item in the gifts array. As a result, we’ll have a new array gifts with results of each callback call.

[
<li>Santa gives you a cookie</li>,
<li>Santa gives you a chocolate</li>,
<li>Santa gives you a lollipop</li>
]

If, for some reason, we don’t like the lollipop, then we can use the .filter function and filter out unwanted gifts.

const gifts = ['cookie', 'chocolate', 'lollipop']const filteredGifts = gifts.filter(gift => gift !== 'lollipop')console.log(filteredGifts) // ['cookie', 'chocolate']

Functions used in examples above are higher order functions because they accept a function as an argument. Another way, in which a function can be a higher order function is when it returns another function.

function ride(transport) {
return function(speed) {
console.log('Riders on the', transport, speed)
}
}

Using the arrow function syntax, we can make this even shorter:

const ride = transport => speed => 
console.log('Riders on the', transport, speed)

Let’s see an example of using the function above.

const rideReindeer = ride('reindeer')
const rideStorm = ride('storm')
rideReindeer('100km/h') // Riders on the reindeer 100km/h
rideStorm('9999km/h') // Riders on the storm 9999km/h

Now, when we know what is a higher order function, let’s move on to the higher order component.

Higher Order Component

In the React world, a function that accepts a Component as an argument and returns a Component, is a higher order component. This way, we can wrap our components with properties and methods and use them however we want.

const decorateBox = BoxComponent => props =>
<BoxComponent style={{
backgroundColor: 'red',
border: '1px solid green dashed'
}} {...props}/>
const CardBox = props => <div {...props}>{props.children}</div>
const DecoratedBox = decorateBox(CardBox)
<DecoratedBox>I'm a decorated box</DecoratedBox>

Instead of using the classical inheritance, React embraces the composition. Through the composition we can avoid the code duplication (Don’t Repeat Yourself) and make our components more flexible and reusable. A higher order component can return a stateful component upon which we can hook on to the lifecycle methods. For example, we can perform an HTTP request in the componentDidMount and pass a retrieved data to the component.

const prepareGiftBox = CardBox =>
class WithGifts extends React.Component {
state = {
gifts: [],
wrapped: true
}

unwrap = () => {
this.setState({wrapped: false})
}

componentDidMount() {
fetch('https://api.xmas.com/gifts')
.then(gifts => this.setState({gifts})
}

render() {
return (
<CardBox
{...this.props}
gifts={this.state.gifts}
unwrap={this.unwrap}
/>
)
}
}

Some of the most popular React packages that are using a higher order component pattern are react-router and Redux. A component wrapped with the withRouter function from the react-router package will get access to the history, location and match objects. Because of the function’s composition, we’re not restricted to just one higher order component function per component; we can compose multiple functions. Each function in the composition chain will take output from the previous one.

const composedFn = x => f(g(h(x)))// h(x) is called first and result is passed to the g function
// g(h(x)) is called next and result is passed to the f function
// f(g(h(x))) is called next and result is saved into the composedFn

Therefore, if you’re using react-router and Redux you can inject router objects in a component and, in the same time, connect it to the store.

import { withRouter } from 'react-router'
import { connect } from 'react-redux'
const WrappedComponent = withRouter(connect(...)(MyComponent))

Next time, when you see that someone is struggling to keep his code DRY, show him how to use a higher order component and teach him one of the main principles in the functional programming — function composition.

The journey for more knowledge:

  1. Higher order component — The Ultimate Guide
  2. Functional programming paradigms in modern JavaScript: Function Composition
  3. React Higher-Order Components (Official doc)

That’s all folks! Until next week and a new pattern reveal!

Danijel is a web developer at COBE. In his spare time, like every other geeky kid, he likes to create pens on Codepen and develop tiny Node apps while listening to RHCP in the background thread. Apart from his JavaScript warrior dreams, he likes to lift weights, eat a lot of chicken and watch crime/thriller movies till the late hours.

--

--