# Who Am I?

## Kyle Shevlin

• Senior Software Engineer at Fastly
• Lover of JavaScript
• Hater of Semicolons (in my JavaScript)
• Twitter - @kyleshevlin

# What will we cover?

## Basic FP

• Functions as First-Class Citizens
• Higher Order Functions
• Currying & Partial Application
• Composition

# Functions as First Class Citizens

``````
function add (x, y) {
return x + y
}

console.log(sum) // 9

``````

"Functions as first class citizens" means you can pass function anywhere as if it's a variable.

# Higher Order Functions

A "higher order function" does one of the following:

• Takes a function as an argument
• Returns a function
``````
function emojiLogs (emoji) {
return function (...strs) {
console.log(`\${emoji} \${[...strs].join(' ')}`)
}
}

const catLog = emojiLog(😻)
const dogLog = emojiLog(🐶)
const logLog = emojiLog(🌲)

catLog('Krios', 'Tali')
// 😻 Krios Tali

dogLog('<- Why do I not have one of these yet?!')
// 🐶 <- Why do I not have one of these yet?!

logLog('Douglas Firs are real nice!')
// 🌲 Douglas Firs are real nice!``````

# Currying & Partial Application

Currying is the technique of refactoring a function that normally accepts multiple arguments into one that accepts them one at a time.

A curried function will continue to return a unary function for each argument until the final one is provided. Then, the function is evaluated.

The arguments provided to a curried function are said to be "partially applied" while the function awaits its final argument.

## The Canonical Example

``````
// add : Number -> Number -> Number
const add = x => y => x + y

const add2 = add(2) // The number 2 is partially applied

const add5 = add(5) // The number 5 is partially applied

const eight = add5(3) // 8

# Composition

If you remember high school math, composition is the act of passing the result of one function to another function.

This takes the form of `f(g(x))` where `f` and `g` are both functions. But nesting functions in JavaScript can be really ugly.

``````
const scream = str => str.toUpperCase()

const exclaim = str => `\${str}!`

const repeat = str => `\${str} \${str}`

const warnSteve = repeat(exclaim(scream('Steve, the world is coming to an end')))

console.log(warnSteve)
// STEVE, THE WORLD IS COMING TO AN END! STEVE, THE WORLD IS COMING TO AN END!``````

Instead of nesting functions, what if we used currying and partial application to create a function that would do the composition for us?

``````
// Pretend we imported `scream`, `exclaim`, and `repeat` from the previous slide

const compose = (...fns) => value =>
fns.reduceRight((accumulated, fn) => fn(accumulated), value)

const withGusto = compose(
repeat,
exclaim,
scream
)

const warnSteve = withGusto('Steve, the world is coming to an end')

console.log(warnSteve)
// STEVE, THE WORLD IS COMING TO AN END! STEVE, THE WORLD IS COMING TO AN END!``````

# Higher Order Components

## What is a HOC?

A higher order component is a function that takes a Component as one of its arguments and returns a new Component.

``````
// identityHoc : Component A -> Object -> Component B
const identityHoc = BaseComponent => props => <BaseComponent {...props} />

// User : Object -> Component
const User = ({ name, age }) =>
<div className='user'>
<h3 className='user-name'>{name}</h3>
<div>Age: {age}</div>
</div>

const AlsoUser = identityHoc(User)

React.render((
<div>
// Both these will render identically
<User name='Kyle' age='32' />
<AlsoUser name='Kyle' age='32' />
</div>
), document.getElementById('app'))``````

## Why Use HOCs?

• DRYs up code
• Separates logic and view concerns
• Are composable

# Recompose API

## withState

The withState higher order component allows you to add state to SFCs which get passed as props to the component.

``````
// withState(
//   stateName: string,
//   stateUpdaterName: string,
//   initialState: any | (props: Object) => any
// ): HigherOrderComponent

const withToggle = withState('isToggled', 'setToggle', false)``````

## withHandlers

The withHandlers higher order component allows you to add handler functions for updating state in SFCs. Also passed as  to SFCs which get passed as props to the component.

``````
// withHandlers(
//   handlerCreators: {
//     [handlerName: string]: (props: Object) => Function
//   }
// ): HigherOrderComponent

const withToggleHandlers = withHandlers({
show: ({ toggle }) => () => toggle(true),
hide: ({ toggle }) => () => toggle(false),
toggle: ({ toggle }) => () => toggle(x => !x)
})``````

### withReducer

The withReducer

higher order component allows you to use a Redux-like reducer to handle state.

``````
// withReducer<S, A>(
//   stateName: string,
//   dispatchName: string,
//   reducer: (state: S, action: A) => S,
//   initialState: S | (ownerProps: Object) => S
// ): HigherOrderComponent

const withToggleReducer = withReducer(
'isToggled',
'dispatch',
(state, action) => {
switch (action.type) {
case 'SHOW':
return true

case 'HIDE':
return false

case 'TOGGLE'
return !state

default:
return state
}
},
false
)``````

## lifecycle

The lifecycle higher order component allows you to add all the lifecycle methods (except for render) to a SFC.

``````
// lifecycle(
//   spec: Object,
// ): HigherOrderComponent

const withData = lifecycle({
componentDidMount () {
fetch('data.json')
.then(response => response.json())
.then(data => this.setState({ data })
}
})``````

## pure

The pure higher order component returns a `PureComponent` version of your SFC.

💥

Next slide.

## mapProps

The mapProps higher order component allows you to massage the ownerProps for the base component.

``````
// mapProps(
//  propsMapper: (ownerProps: Object) => Object,
// ): HigherOrderComponent

const alwaysSteve = mapProps({ name: 'steve' })
``````

## withProps

The withProps higher order component allows you to merge new props with the ownerProps of the base component.

``````
// withProps(
//  createProps: (ownerProps: Object) => Object | Object
// ): HigherOrderComponent

const mergeSteveAndKeepTheRest = withProps({ name: 'Steve' })``````

## renderComponent

The renderComponent higher order component allows you to... well, render a component. It's useful in conjunction with the next HOC.

``````
// renderComponent(
//   Component: ReactClass | ReactFunctionalComponent | string
// ): HigherOrderComponent

const User = ({ name }) => <span>{name}</span>

const hocUser = renderComponent(User)``````

## branch

The branch higher order component allows you to conditionally choose between higher order components. Really powerful when used with or

``````
// branch(
//   test: (props: Object) => boolean,
//   left: HigherOrderComponent,
//   right: ?HigherOrderComponent
// ): HigherOrderComponent

const Left = () => <span>Left</span>
const Right = () => <span>Right</span>

predicate,
renderComponent(Left),
renderComponent(Right) // This can be implicitly supplied by the base component
)
``````

# We'll do it live!

We'll make a higher order component that will show a spinner until our data has loaded that we can use on any similar component.

By Kyle Shevlin

# Learn You Recompose

Learn to use and abuse higher order components with the Recompose library.

• 354