Thinking in React with Higher Order and Functional Components
Successful React development involves being able to 'think in React'. We'll look at breaking down UI's into components and their relationships.
Get the project source code below, and follow along with the lesson material.
Download Project Source CodeTo set up the project on your local machine, please follow the directions provided in the README.md
file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.
This lesson preview is part of the Beginner's Guide to Real World React course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.
Get unlimited access to Beginner's Guide to Real World React, plus 70+ \newline books, guides and courses with the \newline Pro subscription.
[00:00 - 01:37] Welcome to Module 6, Thinking in React. Now way back in the early modules of this course we looked at the relationship between components in React. No matter what the size, structure or complexity of the React project you're dealing with, when it comes to the components there are broadly two roles that a component will have. They will either be a parent or a child. So looking at parent and child component relationships, most components are either a parent or a child and this isn't a one to one relationship. Just like real life , parents can have parents and children can themselves have children. The important thing to remember about this relationship is how we move information between them. It's a core part of the React approach but one many begin in struggle with. He's our early modules diagram that highlights this information flow. You can see that a parent component passes data or information down to a child via props whilst a child component sends data and information back up to a parent via some sort of event. For example a parent component which deals with calling an API to retrieve a list of users might pass a loading flag is loading, a value for the total number of users found, total user count and a function next page to a child component which deals with displaying some paging elements in a nicely formatted way. The child component has a style set of page elements and a button for the user to click to move on to the next page. Now the child component in this case is purely presentational. That is it contains minimal or zero logic or state and is more concerned with accepting a range of prop values and displaying them in some formatted way. In this scenario the parent component passes the data, our total user count next page and is loading down into the child component via the props object.
[01:38 - 02:05] In the child component we'd access them via a call to props like this. Props. totaluser count of props.is loading. That's fine but what happens when the child component wants the change to the next page of results. The logic involved in fetching new results and organising the return data is handled by the parent component not the child component because the child component is purely presentational. At this point you might be thinking well couldn't we just move the button that triggers the next page into the parent component?
[02:06 - 02:43] Well this is an option but the button makes more sense in the context of the whole paging component. The parent component in this example is possibly doing a number of other things and contains a number of other related presentational components such as a data table or a search bar. So what's the solution? Well we leave the button where it is in the presentational child component but we attach the props.next page function that we passed down from the parent to the button's on click event. What happens now is that when the user clicks the next page button or the button's on click event is triggered this calls whatever function is attached to this event which in our case is the past in next page function.
[02:44 - 03:40] The next page function will be called and since it lives in the parent component it will be handled there. The parent component will likely fetch more results from the API and then pass these new results down to the child component which will re-render and complete react component lifecycle once more. This is a fairly simple yet common example of data flow around your app and between components. Things can get very complicated and a little ugly if you have many layers of children and that you need to get data from a parent component higher in the chain to a much lower child component. This practice is called prop drilling and involves each child component in the chain having to grab a prop from its parent and pass it down to the next child. In a later module we'll be looking at more complex data and state management using the user user hook and the reduck state management pattern. These concepts can avoid scenarios like prop drilling and reduce dependency of unrelated components on each other for the sake of passing props down the line.
[03:41 - 04:00] Component types in the wild. Just about anything that you come across in React project it returns some sort of JSX can be thought of as a component. However not all components are created equal. There are a number of different component types that you may come across whilst building projects as part of your job contributing to open source projects or reading about in blog articles.
[04:01 - 04:35] Let's take a look through some of the more common ones to see what they used for and what they look like and how you can identify them. Now as a side note keep in mind that because React is both very unappininated and based on JavaScript which is itself a very loosely typed language there can be a lot of overlap between styles of components. For example a class based component can also be a presentational component. The name and convention of a style or type of component can be a bit of a mixture of its role, its output and how it's constructed. Nothing set in stone but can help to audio project in the building blocks that components represent.
[04:36 - 05:20] So class based components. A class based component is really any component based on an ES6 class. They typically look like this, extending React's component class. You might remember the look of this style of component construction from our earlier modules where we built out some of our class based components and refracted them. This component will accept some props such as first name and last name. It does some string manipulation to turn it into a single name properly in state and renders a paragraph element pulling in the name and age values from state. There used to be more compelling reasons to favor class based components over functional ones. You had access to react lifecycle methods, local state and initialization through the constructor function. However since the introduction of hooks most people prefer.
[05:21 - 05:57] However since the introduction of hooks most people prefer to deal entirely with functional components and use hooks to deal with state and data synchronization. Class based components often have a file name that ends in .js rather than JSX. Function based components. Function based components are more simple in their implementation over class based ones. They look more like a standard JavaScript function and often just return a block of JSX. They can also be found with a .jsx file name. As you mentioned to both since the introduction of hooks function components can now perform the same state interactions and lifecycle logic that their class based counterparts could previously.
[05:58 - 06:05] If we were to rewrite the previous class based example it would look like this. It's important to note that both this example and the previous class based one are functionally equivalent.
[06:06 - 06:15] They are both pure functions that is given the same input they will return the same output. It's one of react only hard and fast rules.
[06:16 - 06:53] Presentational components. Presentational components are components that deal almost exclusively in formatting and presentation of information with zero or bare minimal logic or stateful processing. They represent the base building blocks that your UI is composed of . Consider the very first example in this lesson of a page in component which accepts some data from a parent component and deals with just displaying it. This page in component might look like this. Whilst containing some logic it is minimal and purely used to work out how many pages to display. The component is still primarily presentational and it isn't concerned with external data fetching, complex logic, state updates or lifecycle handling.
[06:54 - 07:08] Another simple example might be a title component which displays a formatted header and subtitle like this. As well as using the alternative construction of the component by using a const and an anonymous arrow function you can see that this component is much more of a simple based.
[07:09 - 07:34] It accepts a title value, a subtitle value and returns a block of JSX that will format the input values consistently for our imaginary project. Container components Container components sometimes known as management or manager components are almost the opposite of presentational components. They contain very little presentational JSX markup passing that responsibility to child presentational components or other child management components.
[07:35 - 08:23] Instead they are concerned with app wide state updates fetching data to power child UI blocks, more complex logic and data synchronization tasks. This convention of breaking responsibilities into how things look with presentational components and how things work with container components is a great starting point if you are new to structuring your React projects and want to know how to split up your components and their responsibilities. It's worth noting that Dan Abramoff, one of the core contributors to React, wrote an article on presentation on container components back in 2015 that is still useful today, although with the introduction of hooks is thinking and approach has changed. This is a beauty of the flexibility of React, you can approach your projects problem solving however you wish. Austin Malerba has also written a more up to date approach that moves Dan 's thinking onto a new approach to component design available on free code camp.
[08:24 - 09:15] Higher order components Higher order components are a much more complex offering but you will come across them in real life projects and it's worth identifying them here and seeing how they tick. All higher order components are, like all components, still just JavaScript functions and JavaScript already has this idea of a higher order function. This is a function that accepts functions as an argument and returns another function. They allow for a greater abstraction of actions not just values. A good example of a JavaScript higher order function would be the built in array functions for each or map. Back to higher order components in React, these are an advanced React technique of creating a function that takes a component and returns a new component. We will be using a number of higher order components in later modules without even thinking about this concept such as React Redux for managing global state. Redux's connect function is a higher order component but we will discover this in an upcoming module.
[09:16 - 09:37] There's a really good example of higher order component on the official React docs that goes a bit deeper into the example for a use case. However for the best concept we will discuss a simple example from the CSS tricks website to illustrate this point. This with uppercase component receives a wrapped component as an argument and it then returns a new component where we convert the children to an uppercase string using two uppercase.
[09:38 - 09:55] To use this we could create a component that receives some props and renders its children elements like this. Next we'd wrap this title component in the higher order component we created and save it in a variable like this. Then we can render this in another part of our app like this.
[09:56 - 10:06] The uppercase title component renders the result of the higher order component with uppercase that was passed to our title component transforming the string. This is a page title here to with uppercase variation.