Monday, June 8, 2020

React Nested Routes

In creating my Recipe Box final project, I added features that quickly bulked up my Redux store with lots of extra state. One feature was a categories dropdown menu allowing the user to choose which category of recipes (i.e., "main dish" or "salad") they wanted to view; this resulted in a category variable in the Redux store along with a changeCategory action. Another feature was a dropdown menu allowing the user to choose whose recipes they wanted to view; again, this resulted in a selectedUser variable in the Redux store along with a changeSelectedUser action. The pattern was clear; anytime I wanted to add another way to filter recipes, I'd have to keep track of that information in the Redux state ... or would I?

As I was reviewing my code with an instructor, he suggested incorporating nested routes into my code and that idea immediately clicked - of course that's how I should be keeping track of the category, the selected user, etc. All of that information should be encoded in the route itself, not stored in Redux!

Inside of index.js, my App component iss wrapped in Router. Inside of App, there are only a few top-level paths inside of the Switch component available for when a user is logged in: "/manage-recipes" (for a user to delete their own recipes or notes), "/logout", "/search" (for searching the recipe database), and "/". I intentionally did not specify that last path to be an exact one because I wanted it to be triggered by both the root route "/" and the recipes route "/recipes". When the "/" path is matched, it triggers a rendering of the RecipesContainer component.

In order to achieve nested routes, RecipesContainer then has its own Switch component. We'll examine one of its Routes, "/recipes/users/:id". When that path is matched exactly, the RecipeCards component is rendered with router props and is passed an assortment of other props -- one of which is the recipes belonging to that selected user (i.e., the user whose id matches the path variable :id).



When RecipeCards is rendered, it only renders a RecipeCard for each of the recipes indicated here. In this way, the user can view any other user's recipes, the URL is more descriptive/restful than when it was simply "/recipes", and I am able to clean unnecessary information out of the Redux store. All in all, a win!