Functional Programming
+ React = ❤️

Sebastian Herrmann

Software Developer at

@HerrHerrmann

Overview

  1. What is Functional Programming?
  2. JavaScript, the predestined FP language?
  3. Some benefits of FP
  4. Examples
  5. Learning Resources

What is Functional Programming (FP)?

This is FP, right?

import * as _ from 'lodash';

const activeUsernames = _(users)
  .filter({ isActive: true })
  .map('username')
  .sort()
  .value();

FP actually covers
many concepts.

  • immutability / purity
  • side effects
  • composition
  • partial application
  • currying
  • monads
  • lambda
  • identity
  • more: http://git.io/fp-jargons

Some FP concepts

JavaScript, the predestined FP language?

Arrow Functions

const isMature = age => age > 17;

const getAge = user => user.profile.age;

Functions as
first-class citizens

import { map } from 'lodash/fp';

const getName = user => user.name;
const getNames = map(getName);

partial application

const userNames = getNames(users);

Immutability

// ❌ mutability
const user = { name: 'Sarah' };
user.name = 'Buffy';
users.push(user);

// ✅ immutability
const user = { name: 'Sarah' };
const changedUser = { ...user, name: 'Buffy' };
const usersWithSarah = [ ...users, changedUser ];

Purity

// ❌ impure function
const getStateImpure = () => window.appState.name;

// ✅ pure function
const getState = currentWin => currentWin.appState.name;

// ✅ via lodash/fp
const getState = get('appState.name');

Basic functionality:

For React:

FP libraries

Benefits
of FP

1. Composition instead of chaining

1. Composition instead of chaining

import * as _ from 'lodash';

const devNames = _(users)
    .filter(isDeveloper)
    .map(getName)
    .value();

1. Composition instead of chaining

import { compose, filter, map, toUpper } from 'lodash/fp';

const getDevNames = compose(
    map(getName),
    filter(isDeveloper),
);

const devNames = getDevNames(users);

const getDevNamesUpper = compose(
    toUpper,
    getDevNames,
);

2. Higher-Order Functions

const multiplyByTwo = multiply(2);
map(multiplyByTwo, [1, 2, 3, 4]);
// => [2, 4, 6, 8]
const UserListPageWithData = withData(
  {
    users: api.loadUsers
  },
  UserListPage
);
// => UserListPage called with prop "users"

3. More solution,
less boilerplate

const getManagers =
    users => users.filter(user => user.isManager);
const getNamesOfManagers =
    users => getManagers(users).map(user => user.name);
// VS

const getManagers = filter(get('isManager'));
const getNamesOfManagers = compose(map(get('name')), getManagers);
// ^ pointfree functions!

4. More fun!

  • plan ahead, then write down your solution
  • powerful and standardized concepts at your disposal
  • more common understanding in your team(s)!

Concrete Examples

ReadMoreText

import { compose } from 'lodash/fp';
import { mapProps, withState } from 'recompose';
import { withAppContext } from '../../hoc/withAppContext';

// "Plain" stateless component
const ReadMoreText = (/*...*/) => {/*...*/};

// Component with state and context
export default compose(
    withAppContext,
    withState('expanded', 'setExpanded', false),
    mapProps(sanitizeText),
)(ReadMoreText);

MeetingOverviewPage

export default compose(
    withAppContext,
    withData({
        resolve: {
            summaries: api.meetingSummaries.fetchSummaries,
        },
    }),
    Component => props => (
        <Component {...props}
            summaries={map(createSummaryFromDto, props.summaries)}
        />
    ),
    withLocalStorage('meetings-overview-page-view'),
    withStore(undefined, mapDispatchToProps)
)(MeetingOverviewPage);
const CommentCountWithLoader = withData({
    resolve: {
        commentCountResponse: 
            ({ objective }) => batchRequest(/* ... */)
    },
    pendingComponent: PendingCommentCount,
    errorComponent: CommentCountError
})(CommentCount);

export default ifVisible({
    pendingComponent: InvisibleCommentCount
})(CommentCountWithLoader);

CommentCount

Some nice awesome resources

It's not all in
or all out.

Use FP as much as you like!

(But don't throw consistency overboard.)

Thank you. 🦇💖

Questions? Comments? Opinions?

Slides: bit.ly/fp-react

Costume by SHOXXX (www.shoxxxboxxx.com)

Functional Programming + React = ❤️

By Sebastian Herrmann

Functional Programming + React = ❤️

I'll highlight how we're using FP in the frontend in combination with JavaScript and React to build readable and reusable functions and components. (Presented at BerlinJS in October 2018.)

  • 1,712