Redux & Thunk: Let’s Handle it!
Introduction
React is a popular and rewarding javascript framework to learn. It’s really good at turning your vanilla javascript into an easy to work with abstraction. This makes it easy to follow the DRY(DO.NOT.REPEAT.YOURSELF) principle, which for one thing, takes a lot of redundant code out of your application. Since it was my first front-end framework, I was impressed with its modular programming with components. This makes debugging a dream, plus you organize and separate concerns like a pro!
Once you grasp the framework, it’s straightforward to build larger and more complex projects with nuanced component structures. Yet React.js on its own can be very limiting. Sooner or later, you’ll end up hitting a wall. This points you towards additional libraries to solve those more “trickier” problems. In my experience, this was my tendency to over implement State (react’s own version of local storage). You can also think of State as an object that holds some information that may change over the component’s lifetime.
It’s a powerful tool in React.js, perfect for dealing with use cases such as buttons and their onClick functions. Yet when we want to pass down larger amounts of information and hold it in State, you’ll begin to see it slow down. This can cause many problems, such as a page not rendering or updating information on a refresh of your SPA(Single Page Application). Spend time debugging these problems is a great opportunity to learn React.js. You’ll find that ultimately you are limited. This is where Redux and Thunk come into play.
Redux Store your Personal Cloud
Ever download a movie on your phone, or grab a file from your dropbox? How about upload a document to your google drive. It’s pretty convenient and ends up making you more productive. Let’s apply this concept to your component hierarchy. How awesome would that be?
Imagine having your own dropbox or google drive built specifically for your own application. It holds whatever you want it to. No matter where you are in your component hierarchy, you pull data from thin air. No passing props or functions are required. This is the global state or, in Redux terms, the Store.
All that information is centralized and keeps a single source of truth. The potential is seemingly limitless here; You have an on-demand State that works anywhere. This global state updates whenever changes are made. No need to pass a function down to props or worry about a sluggish state. All you need to do is “listen” or “Subscribe” to this global state or Store, and you can access the information. Strangely, it resembles “Props” and behaves a lot like it.
You want to think of Store as an “immutable tree” for your entire application. You can read from it by subscribing to it, and you can only write to it/update by calling a “dispatch function.” You want to keep this in mind as you build out your application. “Actions” and “Reducers” should follow this rule. We will talk more about this later. They do not mutate ‘current state,’ so you need to use a spread operator when updating the ‘…’ syntax you may have seen. Think of them as additional components to your global state. Remember, you never delete the current state; update it!
In general, regarding Store, be frugal. Only subscribe to the Store in components that actually need them. The same goes for writing or updating. Less is more, so make sure you trim the fat.
Minimize Server Trips with Thunk & Middleware
Unless you’re build something that consistently needs to talk to your database(chat app for a smartphone), it’s best to minimize fetch requests. Utilizing Redux’s Store. Allows us to have that super-sweet on-demand global access to data without this cost. As your application can now utilizes more CRUD(create.read.update.destroy) actions for robust user features. Simultaneously, Redux’s Actions and Reducers will automatically update this information on the front and back-end. Super handy and worth your time as a React.js developer. Think about it in terms of grocery shopping. It’s more efficient to go once a week than every day.
Actions: Global functions at your disposal
Actions are specialized functions that can be imported into your component hierarchy by subscribing to them. You’ll often use Actions along aside Reducers to maintain the current state. Actions produce a specialized object with a type(imagine a label for your data) and a payload(your data) passed to the Reducer. A common use case would be making initial fetch quests from the database and then passing this data to the Reducer.
Actions aren’t only for fetch requests. I’ve made Actions for use cases like passing a target id of a user or an array of target usernames. You can get pretty creative as long as you follow the correct syntax here.
Reducers: The Switchboard Operators
Reducers are in charge of holding what your global state is and sending it to the components subscribed to it. I like to think of those “old-timey”-switchboard-operators for telephones. A Reducer function listens to a piece of your global state as well as an Actions type or “label.” It executes the code you’ve written. This code manipulates the current state and sends it outbound through a Root Reducer.
Reducers are specialized functions as well, with unique syntax that handles current state and action types. The function interacts with an attribute of the global state object, manipulates it, and then passes them to the Root Reducer. A common Redux import is combined Reducer, which allows you to send multiple attributes of your global state to all of your subscribed components. That can be helpful in many use cases on the component side of this workflow.
Subscribe a Component
To access your Store, you need to subscribe. To do this, you’ll need to import connect from react-redux. It’s a higher-order component and functions much like withRouter on the export of your component. You’ll need to write a mapStatetoProps function, which has some special syntax. This function aids in listening to your Root Reducer and looking at what’s inside it. It allows you to listen to your global store via “this.props”.
That function is passed into your imported connect higher-order function as an argument. You can also subscribe to actions in the same way with a few more steps. This allows you to deploy any global functions you created.
You’ll first import the Action/global function, then run a componentDidMount on this Action. You’ll also need to create the mapDispatchtoProps function, which is also considered an argument in your connect higher-order component.
Conclusion
At first, you have to write a bit of code to set up Redux and Thunk. It can be intimidating and frustrating at first, but the payoff is well worth it. As it cuts down trips to your server, it allows you to deploy custom global functions(this makes code DRY) and makes for readable and organized code for your application. Please see the links below, which will further explain Redux & Thunk.
Links:
Redux: https://redux.js.org/introduction/getting-started
Thunk & Middleware: https://github.com/reduxjs/redux-thunk