Go Functional! So the big idea is that although React itself is declarative, vast majority of code that goes into making an app is imperative. This can be fixed (if you think it needs fixing) by mixing in more functional patterns. Rendering data What is react? A JavaScript library for building user interfaces — reactjs.org Although React is for building data view (or user interfaces), it must mingle with data, in some form, at times. And when it does, almost always the data is with the the code. tightly coupled interface Wouldn’t it be great if we could just pack our views in a separate box and just sprinkle the data needed? as and when A box called “Comp” This code is from the talk “ ” by . If you haven’t seen it yet, I encourage you do so before continuing. Oh Composable World! Brian Lonsdorf @ 21:40 Oh Composable World! If you haven’t seen the video, here’s a brief explanation of the code you see: The function takes in a react component (as the argument ) and returns an object with methods and . Comp g fold contramap The method is the original component passed to Comp. This means that calling is just like calling or rendering . After all, the following expressions give values. fold fold Foo <Foo /> equivalent <Foo fizz="buzz" /> Foo({ fizz: "buzz" }) Comp(Foo).fold({ fizz: "buzz" }) The method is there to modify props. It takes in a function that takes in some value and returns another value. The returned value is then fed into the original react component for rendering as a prop. contramap f We can say that to the component. contramap transforms the input Modifying the output Modifying the output means to modify JSX. You may be thinking of a higher order component. But here’s the problem — HOCs don’t work with JSX. Concretely, . — React docs on a higher-order component is a function that takes a component and returns a new component Higher order components With the help of flow, if I create types for both Component and HOC, I get: type **Component** = Props => Element; type **HOC** = Component => Component; It isn’t immediately obvious, but the type signature for an HOC is pretty long: type **HOC** = (Props => Element) => (Props => Element); What we want is fairly simple: . Element => Element The map function This is what the function is used for. If deals with a component’s input (props) then deals with its output (JSX). The function takes some JSX and wraps the original component’s output in it. map contramap map f Safety First Before venturing any further, we need to make the code safe — . type safe Here are the basic flow types: The important thing to observe here is that the type is a mapping from type to type . Component Props Element Armed with types, we can now annotate our function’s return object. Please note that I am using to make the intent clear that type is an object with fixed keys and values. Comp Flow’ [$Exact](https://flow.org/en/docs/types/utilities/#toc-exact) utility type Box If we really think about it, we can see that the function is a mapping from type to type . Comp Component Box If you’re not a fan of arrow functions, you can rewrite the same thing as a declaration. I prefer the current system because I can my types from my code. IMO, that’s much cleaner. function decouple Writing using function declaration means we’d have to integrate the types into the function definition. Comp JSX Pipeline Right now, every object sits in isolation from the rest of the world. They can’t even connect with each. But if they could, we’d have an extensible JSX pipeline at our hands. Box The concat function Conceptually, the function two entities of the same type. We should also add a method to our type. concat merges concat Box With the help of our new friend, we can now join multiple es together. Box Nasty concat It works nicely but there’s a small hiccup. Everytime is called, it appends a new into the markup. And that’s . concat <div /> nasty An array equivalent would look something like: [1].concat([2]) === [1, [2]] But we know that’s not how works on arrays. It works like: concat [1].concat([2]) === [1, 2] This means that array’s method is : concat associative [1].concat([2].concat(3)) === [1].concat([2]).concat(3) === [1, 2, 3] But our is not associative: concat Nice concat The easy way out is to wrap the result of concat in an array, since arrays already have a nice and friendly method, and also because React 16 added support for . But doing so means rewriting the function. Besides, it’s already been covered in “ ” by . concat rendering an array of JSX elements Comp Deconstructing the React Component Jack Hsu Instead, we will use the . If you’re feeling adventurous, you can use the . [<Fragment />](https://reactjs.org/blog/2017/11/28/react-v16.2.0-fragment-support.html#what-are-fragments) component updated syntax for fragments With such a minor update to the code, we’ve solved two problems: We no longer need a separate to wrap other JSX elements <div /> Our is now associative. concat Huzzah! Conclusion With the final addition of a method, we can take a step back to admire the beauty of our code. concat But why? Without going any further than this, it’s best if we talk about the merits of our current system. In the article “React Higher Order Components in depth”, has outlined numerous use cases for HOCs and split them up in two classes of implementation — and . We’ll look at each of them and see what we can do about them. Fran Guijarro Props Proxy Inheritance Inversion Props Proxy This is the more conventional usage of an HOC and it allows: Props manipulation State abstraction Accessing the instance via Refs Wrapping the with other elements WrappedComponent and **State abstraction**I’ll have you know that there’s yet another that deals with this specific usage of HOCs. It’s called and you can read more about it in my other article “ ”. Props manipulation pattern Render Props Exploring Render Props Let’s look at some sample code that uses a HOC to implement both usages: Before we can make the code , we need to convert it to the render props pattern. functional We can now functional-ise the code. First, we pack and in separate es. Since is a class, we also need a function to convert ES6 classes into functions. Luckily, . <Num /> <Foo /> Box Num Brian Lonsdorf got us covered And now, we define our in terms of es. <App /> Box And that’s it. Two HOC uses down, a few more to go. Typically, this is how we use refs in HOCs: Accessing the instance via Refs Which is, under the hood, just a nested component: And the functional equivalent is: Okay. This one is pretty obvious. We just wrap one component in another. This is exactly what the function does: Wrapping the **WrappedComponent** with other elements map Inheritance Inversion We have covered the entirety of what an HOC can do by acting like a . If you thought that was interesting, just check out — it’s bound to confuse you. An HOC that returns a new component that extends . component pass through how to implement II WrappedComponent This is the one thing that we can’t do with with es. We cannot have inheritance amongst functions and functions are a major participant in our functional pattern. And this makes me sad 😔 Box The End … for now. I hope you found this bit interesting and possibly even helpful. Now we can explore data flow in our functional react pattern. But that’s an affair for another time. The code for this post is . on repl.it If you want more, here’s a list for you: https://www.youtube.com/watch?v=SfWR3dKnFIo https://www.youtube.com/watch?v=JZSoPZUoR58 https://creaturephil.github.io/posts/exploring-oh-composable-world/ Addendum: Class components So far, we’ve only looked at functions and ignored class components. Let’s invite them to the party as well. Since can only handle functions, we will need a helper function that converts classes to functions. Comp That’s all we needed to do. Seeing how simple of our helper is, can you make a guess at its type? Made your guess? Ready for the answer? classToFn Addendum: Adding stricter types Once you’re done with this article, I suggest you take a look at to better explore the landscape of type safety that comes with this kind of setup. this article