Here's a little intro to the course material. I hope you enjoy the course!
The goal of this course is to give you the concepts and ideas you need to make components as simple and flexible as possible so you and your team will have an easier time building an amazing UI.
In this lesson, we’ll write a simple toggle component which will serve as the foundation for the rest of the course. Kent walks through how to create a simple toggle with React
setState. He shows us how to extend the functionality of the toggle by safely adding an
onToggle prop that gets called after state is updated.
Compound components give more rendering control to the user. The functionality of the component stays intact while how it looks and the order of the children can be changed at will. We get this functionality by using the special
React.Children.map function to map over the children given to our
<Toggle/> component. We map over the children to pass the on state as a prop to its children. We move the visual pieces of the component out into function components and add them as static properties to
Our current compound component implementation is great, but it's limited in that users cannot render the structure they need. Let's allow the user to have more flexibility by using React context to share the implicit state to our child
<Toggle/> components. We will walk through using React's official context API with
React.createContext and use the given
Consumer components to share state implicitly between our compound components giving our users the flexibility they need out of our component.
If someone uses one of our compound components outside the
<ToggleContext.Provider />, they will experience a confusing error. We could provide a default value for our context, but in our situation that doesn't make sense. Instead let's build a simple function component which does validation of our
contextValue that comes from the
<ToggleContext.Consumer />. That way we can provide a more helpful error message.
Due to the way that React Context Providers work, our current implementation re-renders all our compound component consumers with every render of the
<Toggle /> which could lead to unnecessary re-renders. Let's fix that by ensuring that the
value prop we pass to the
<ToggleContext.Provider /> is only changed when the state changes.
In this lesson, we'll take a step back and re-examine the problem of sharing Component logic by iterating our way to arrive at a new pattern called render props. A render prop is a function that renders JSX based on state and helper arguments. This pattern is the most flexible way to share component logic while giving complete UI flexibility. It's a remarkably simple and powerful pattern.
When you're using prop collections, sometimes you can run into trouble with exposing implementation details of your prop collections. In this lesson, we'll see how we can abstract that away by simply creating a function called a prop getter that will compose the user's props with our prop collection.
Often with reusable components, the logic needs to be adjusted to handle various use cases. Rather than filling our component event handlers with
if statements and loading our
state with one-off properties, we can expose our
state directly to users of our reusable component in a way that's flexible and simple with a state reducer.
Users of our component can make custom modifications to the state whenever it changes, but in more complex components they may only want to change the state updates for certain types of changes. Let's add a
type property to our
changes object so people providing a state reducer have more insight into the source of the changes and can reduce the changes based on that information.
While the state reducer pattern gives users total control over how the state is updated internally to a component, it doesn't allow them to update state arbitrarily. Let's implement the control props pattern (found in built-in components like
<input /> through the
value prop) to give users complete control over the state of our component.
In our simple situation, having an
onToggleChange handler is sufficient because the
on state is the only state we have, but in a more complex component, there could be many items of state. We could make an prop callback for each of those items of state, but that could drastically increase the complexity and repetition of our component. Instead, let's make an
onStateChange that's called when any state changes.
onStateChange handler is great, but it's limited in capacity because we don't know why certain state is changing. By adding
stateChangeTypes to our component, it allows consumers of our component to have more insight into how to respond to certain changes.
The prop drilling problem can be frustrating for data that changes over time and is needed throughout the application. Luckily for us, we can use React's
createContext API to make state (like
on) and state updater functions (like
toggle) available anywhere in the tree. In this lesson let's see how to side-step the prop drilling problem with a custom context provider and consumer.
Sometimes you have some boilerplate for components that would be nice to abstract away slightly with a simple helper function. In this lesson we'll learn how to create a "Higher Order Component" which is a component factory function. We'll use it to give a given component a prop for our context value.