DEV Community

Cover image for Composing React Hooks
brandon flowers
brandon flowers

Posted on

Composing React Hooks

As a leader, working with several bootcamp developers entering their second or third years as a professional javascript developers, we have a certain responsibility to guide them and introduce computer science concepts that they may have missed in their compressed education.

There is a natural interest to refine their craft by diving into Functional Programming. After a solid year or two of Javascript programming, they would have mastered enough of the fundamentals to be open to learning more.

They may get turned on to FP after reading a blog post or through co-workers. The first steps in learning FP would be to read a book and soak up a few videos on the basic principles. Once you have the concepts, then you can begin experimenting with them.

To the gain of the benefits of FP, you do not need a library right away. Many FP practices, like writing more testable, pure functions that when given an input always return the same output, can be applied in your daily coding without importing an another library.

Adding a library like react-hook-compose or ramda will give you extra functionality when you are ready for it. They do require extra brain power so I would not recommend approaching them until after you have absorbed at least the basics of FP.

What is composition?

Have you ever realized that after writing within the same React file, your code has swelled to hundreds of lines and its becoming unwieldy to manage? This becomes even more pronounced when you try to share this code with a fellow developer who shrieks at the size of your commit with appropriate emoji.

We want to refactor large files into smaller smaller so that they are easier to review and test.

Ramda

I had invested several years in learning the ImmutableJS library and feel that I know it well enough that I wanted to experiment with a new FP library. In my mind, ImmutableJS and Ramda are comparable libraries. There is some drama about ImmutableJS being unmaintained but I have never had an issue with it and sometimes a library can reach a certain maturity without needing more work.

My first impression of Ramda is that the documentation already feels more like Clojure which I've studied in the past. It mentions terms like or unary or arity which are probably new language to javascript developers unless you have already learned other FP focussed languages like Haskell, Clojure, or Elm. Like Clojure, Ramda offers the javascript a new world of functionality, providing more tools to safely transform data without worrying about mutation.

The Ramda library provides a compose function which allows you to take smaller files and bring them together through incremental steps.

const Poster = ({ id, coverUrl, title }) => {
  return (
    <ListItem key={id}>
      <Image url={coverUrl} a11y={title} width="100" />
    </ListItem>
  );
};

const makePosters = map(Poster);
const getPoster = pick(["id", "coverUrl", "title"]);
const getPosters = map(getPoster);
const TitleList = compose(makePosters, getPosters);

const Posters = ({ tvSeriesDataset }) => (
  <Column>
    <SubHeadline size="large">TV Series</SubHeadline>
    <List customClass="list">{TitleList(tvSeriesDataset)}</List>
  </Column>
);
Enter fullscreen mode Exit fullscreen mode

I've prepared a Ramda codesandbox exploring how to compose several react functions. For instance, we can write a list component in one file and a list item component in another file. As the author, this can become subjective when is a file too small? In my case, I decided to write them as separate functions to be exported and re-used by other components, but I left them in one file because the line count was already under 100.

Along with compose, this codesandbox also features various ways to transform the data at each step of the composition. I started this experiment by simply googling "codesandbox ramda" and leveraged some code from other authors giving them credit within the readme.

react-hooks-compose

This library is almost self explanatory. It does what you would expect it to do. Similar to compose in Redux, you can take a presentational component and apply several hooks to it.

What is the motivation to use compose? Through compose, we can write hooks external to our presentation and re-use them within other components. In this experiment, I take 3 hooks: useState, useQuery, and useMutation and combine them with a presentation component. Each part is a separate file.

With composeHooks can add hooks to our presentational component following this pattern:

const ViewComponentWithHooks = composeHooks(({ myQuery, myMutation}) => ({
  useCaptureInput: () => useCaptureInput(),
  useQuery: () => useQuery(myQuery),
  useMutation: () => useMutation(myMutation)
}))(ViewComponent);
Enter fullscreen mode Exit fullscreen mode

I had some fun creating this react-hooks-compose codesandbox which displays some of my favourite recent TV series. Most of these series were recommended by friends.

Conclusion

Over the last year, I have watched a team of mainly bootcamp developers grow to a point where I feel like they have become peers and can sagely criticize the DRYness of my own programming. We are in the process of introducing FP at Loblaws Digital, beginning with the fundamentals and, through these experiments, I'm attempting to convince them (and myself) that should introduce Ramda into our codebase.

It's not enough for me to mention ImmutableJS or Ramda in a meeting, I want my team to follow my example and experiment with them. I hope they see this post as motivation to create their own codesandbox so that I in turn can learn from them.

Oldest comments (0)