showing 56 lessons...
In this lesson we'll create a Higher Order Component (HOC) that takes care of the
key property that React looks for when using
map to create elements from a list. This HOC will allow us to wrap any component and it will take care of placing the
key prop on the component for us based on the property name that we specify.
In this lesson we'll take a stateful React component and look at how we can refactor our
setState calls to use an updater function and then leverage Ramda's
evolve function to make our updater function a reusable utility that isn't tied to the React API.
In this lesson, we'll refactor a React component to use Ramda lenses to update our component state. We'll create a lens to focus on the property we want to target and use
over to apply the existing state value to a utility function and we'll get back a new state that will be reflected in our rendered UI.
Function composition allows us to build up powerful functions from smaller, more focused functions. In this lesson we'll demystify how function composition works by building our own
In this lesson we'll see how Ramda's
pathOr functions can be used to safely access a deeply nested property from an object while avoiding the dreaded checks for
undefined at each new property in the desired path.
Using the map method of an array is a great way to create new data from an existing array in an immutable way and without writing any loops. The problem is that you need to call it on an existing array instance. In the lesson we'll see how to build our own reusable
map utility function using manual currying and then we'll replace it with Ramda's
In this lesson, we'll use
Promise.all to get an array that contains the resolved values from multiple promises. Then we'll see how we can use Ramda to convert that array of values into a single object using
fromPairs. Then we'll refactor to use
In this lesson, we'll look at how we can use Ramda's
constructN functions to take methods of an object and turn them into reusable utility functions that are curried and accept their object as the last argument. We'll convert a dot-chained string of jQuery methods and create a composed function that can be applied to multiple elements.
Sorting an array of objects by multiple fields can be tricky. Even worse, the code can be tough to follow and making changes in the future is complicated by conditional logic in the sorting function. In this lesson we'll see how to simplify this using Ramda's
sortWith along with
descending. We'll sort an array of objects by multiple fields and the code will be readable and dead simple to change.
Promise chains can be a powerful way to handle a series of transformations to the results of an async call. In some cases, additional promises are required along the way. In cases where there are no new promises, function composition can reduce the number of dot chained
thens you need. In this lesson, we'll look at how to take a promise chain, and reduce it down with function composition.
Naming things is hard and arguments in generic utility functions are no exception. Making functions "tacit" or "point free" removes the need for the extra parameter names and can make your code cleaner and more succinct. In this lesson, we'll create a normal, "pointed" function and then use ramda's
useWith function to refactor our way to point-free bliss.
Functional composition is a great way to write declarative code that reads well. But sometimes, you need to get insight into what's happening at different steps in your composition. This is where
tap comes in. With tap, we can run code that generates side-effects, like logging to the console, and our data will continue to be passed along, untouched.
In this lesson, we'll grab arrays of values from other arrays, resulting in a nested array. From there, we'll look at multiple ways to flatten the array structure using composition with
unnest and then refactoring to use
flatMap. Finally, we'll add Ramda's
uniq function to remove duplicate values.
Handling your logic with composable functions makes your code declarative, leading to code that's easy to read and easy to test. Breaking that up to wrap some risky function in a
try/catch block introduces imperative code and makes it harder to maintain that declarative approach. With Ramda's
tryCatch function, you can handle errors right in the middle of a composition and leave your code clean and functional. We'll also see how you can use
propOr to avoid common "cannot find X of undefined" errors.
In this lesson we'll take some existing code and refactor it using some functions from the Ramda library, most notably,
converge. When we're done, we'll have taken a function with a couple of local variables and parameter references and converted it into more streamlined "point-free" or "tacit" functions.
We’ll fire up json-server so we can run our application against a server. We’ll take advantage of the fetch polyfill provided by create-react-app and leverage the componentDidMount lifecycle event to load our initial todo list. We’ll also add an error message to our UI in the case that the server is unavailable.
Using pushState and passing route data via context allows our application to respond to route changes made from Link components, but using the back and forward buttons in the browser doesn’t update the application state as we would expect. In this lesson, we’ll add event handling to our Router component to handle history popState events so routing behavior is maintained for the back and forward buttons.
We’ll create a Router component that will wrap our application and manage all URL related state. We’ll see how we can use React’s built in context mechanism to pass data and functions between components without having to pass props all the way down through the component tree.
We’ll add a handler to the form so we can take new input and use it to update the application state. We’ll append new items to the list with the AddTodo function and replace the todos list in state. We’ll also clear out our form so it can accept new todos.
We want to be able to show only items in a certain status so in this lesson, we’ll add a flag to indicate which items to show, and create a function to filter the todos based on that value. We’ll take advantage of route based state to control the filtering behavior.
In this lesson we’ll see how to pass an item’s id value in an event handler and get the state to reflect our change. We’ll also create a helper function that allows us to use partial function application to clean up the event handler code and make it more “functional”
We’ll build small, focused functions to select an object from a list, apply updates to an object and replace an item in a list, avoid mutations to those objects along the way by returning new items that reflect our changes. We’ll verify this behavior by following a test driven approach using Jest.
We’ll make the input field a “controlled component” by reacting to each change of the input and capturing it in the component state. Following this model gives us assurance that the UI is always a representation of the current application state.
React gives us a mechanism called PropTypes to ensure that the property values passed into components are of the correct type. By ensuring the correct data is passed to our components, we can avoid potential bugs and more confidently share components with a team or as open source libraries.
We’ll refactor our existing code, making the todo form a separate component. We’ll pass values from the App container into the new component via props. We’ll look at the differences between state and props in React and see how state can be passed down to other components as props.
We’ll define a simple state object in the constructor of the App Component class. Once the state has been defined, we’ll replace the static elements in our rendered output with values from the component’s state. We’ll move from static items to an array, seeing how we can use functions like map to render our UI.
fromPairs functions, along with the crucial
We don't always control the data we need in our applications, and that means we often find ourselves massaging and transforming our data. In this lesson, we'll learn how to transform objects in a declarative way using ramda's evolve function.
In this lesson we'll take an array of objects and map it to a new array where each object is a subset of the original. We'll look at multiple ways to accomplish this, refactoring our code into a simple and easy to read function using Ramda's
Most of the functions offered by the ramda library are curried by default. Functions you've created or that you've pulled in from another library may not be curried. Ramda's
curryN functions allow you to take a non-curried function and use it as a curried functions. In the case where you have a manually curried function and you want to just call it like a normal function, you can use
uncurryN to get back a function that accepts all of the arguments at once.
When you want to build your logic with small, composable functions you need a functional way to handle conditional logic. You could wrap ternary expressions and if/else statements in functions, handling all of the concerns around data mutation yourself, or you could leverage the conditional functions supplied by Ramda. In this lesson, we'll cover several of Ramda's conditional functions:
In this lesson, we'll use
next to create a universal React application with no configuration. We'll create page components that will render on the server if accessed directly, but function as you would expect in the client. We'll use the routing capabilities included with
next to create links between the components using
pushState and we'll incorporate our own React component. Finally, we'll deploy the application to
now with a simple command in the terminal.
Sometimes you need to filter an array of objects or perform other conditional logic based on a combination of factors. Ramda's
where function gives you a concise way to declaratively map individual predicates to object properties, that when combined, cover the various facets of your conditions. In this lesson, we'll look at how this powerful function can be used for scenarios requiring a complex predicate function.