Some New Tools: React and Redux
I must admit that I was not excited about starting React. I am someone who really likes to understand exactly what is happening at each moment my code is executing, and so "vanilla JS" really appealed to me. Call me crazy, but I really liked manually updating the DOM to reflect exactly the changes I wanted to see. While other folks seemed mesmerized by "React-magic", I felt a little uncomfortable with not having hard-coded all of the DOM changes myself.
Of course, as soon as I started feeling comfortable with React, Redux came into the mix! It was a little tricky to wrap my head around Redux at first, but like anything you just need to "feel out the contours and wait for your eyes to adjust" (an approximate quote from one of Flatiron's founders, and one that I have on a sticky note next to my computer!). Redux is a "state-management tool" that places all of our application's data in a single state ("the store"), which is just a plain JS object. To change our state, we need to create an action that holds information for how to update the state. Reducer functions take in a previous state and an action and return an updated state that results from applying the action to the previous state.
How does our React app connect to the Redux store? With a connect function that itself calls a particular function (usually mapStateToProps and mapDispatchToProps) whenever there is a change in the state. Whatever that function returns will get passed down to the "connected" component as props.
The purpose of Redux is to maintain a single source of truth for your application on the front end, as opposed to having different data structures in all of your JS classes that keep track of various information. While I was able to see this to a small degree in my own project, I imagine that a larger-scale project would really benefit from such predictable state management.
My Recipe Box
So, how did I incorporate these tools into my final project? My Recipe Box allows the user to create recipe cards with their favorite recipes from around the web, categorize the recipes for easy access, record any notes they'd like to remember for the next time they make the recipe, and see all their friends' recipes as well!
My main presentational component is RecipesContainer, which is responsible for displaying a set of recipe cards by rendering the RecipeCards component. RecipeCards, in turn, does some filtering of the recipes and then for each recipe, renders a recipe card. Finally, the RecipeCard component is responsible for displaying an actual recipe card, along with the user's notes about the recipe, a link to the recipe on the web, and a button for adding a recipe note. Of course, there are other components as well: a NavBar for navigation, a RecipeForm for adding a new recipe to your box, etc. Not to mention components related to user authentication, which was a challenge I had been avoiding but I'm glad I finally tackled!
Where does Redux come into play? When my front end sends an API request to, say, load all of the recipes from the database, those recipes get stored in the Redux store (i.e., the global state). The store keeps track of other information as well: all of the users, all of the recipe notes, the current user, whose recipes you are currently viewing, which category of recipes you are currently viewing, etc.
There were definitely some decisions involved in terms of which React components to connect to the Redux store, and I'm sure this is something that will change as I go back and refactor my code. For now, I chose to map most of my state and dispatch functions to props in my parent App component and then only connect to the store for more specific needs further down the chain. For example, RecipeCard connects to the store to grab all of the notes and the function for adding a new note (triggered by an "add note" button on a recipe card).
Overall, I learned a TON through this project and am excited to continue refining it so that I can release it to the world (or at least a small circle of friends)! Feel free to check out my repo here, and thank you again for continuing to join me on this journey!