I attempted to use Redux with Typescript quite some time ago and ran into some issues with some other packages I was using (namely redux-persist). It seems that package is becoming ransomware, despite there being a large community of users behind it. With that community of users, there are some how-tos of how to implement TypeScript, but I thought I would take the time to consolidate all of the information that I’ve found and put it in one spot in hopes to potentially help another developer in the future.
Welcome 🤙
This is something that I’ve struggled with for a while. I attempted to use Redux with Typescript quite some time ago and ran into some issues with some other packages I was using (namely redux-persist). It seems that package is becoming ransomware, despite there being a large community of users behind it. With that community of users, there are some how-tos of how to implement TypeScript, but I thought I would take the time to consolidate all of the information that I’ve found and put it in one spot in hopes to potentially help another developer in the future.
Additionally, I’ll outline some of the practices that I put in place when utilizing Redux (such as the structure and organization that I use).
Structure 🏗
As per the redux documentation, there is a recommended structure. However, their proposed structure is all actions in an actions folder, all reducers in a reducers folder, and all constants in a constants folder.
Instead, I prefer to keep mine organized by their container.
What are Action Types / Constants?
Action types are constants that contain the string value that identifies the type of action uniquely in the application.
For example, if we have a site that hosts a form, we can come up with a couple of basic actions that might occur on that form such as setting our loading state as well as the action of updating a field value. With that, we would see something like the following:
What are actions?
Actions what we are doing prior to manipulating our state’s values. Be it that we are running a simple function and passing a payload or object to our reducer, or if we are performing an HTTP call and passing that response onward to our reducer, this is where that happens.
Personally, I like to handle the HTTP calls outside of the actions as that allows me to also set a loading state pre-fetch and on reception. Thus, managing a better user experience.
Here are two examples of actions given the constants above.
What are reducers?
Reducers are normal functions used to manage a whole application’s state. They use the name of the action to be generated along with the action data.
Based on the action data, the state object can be manipulated using different switch cases.
One thing to keep in mind about the reducer is that it uses action.type
and based on the type the switch statement identifies, triggers an action. If there are no matching conditions, then the default section will be triggered.
Here is an example of a reducer given the actions and constants we have above.
Putting it all together 🧩
When creating a project, I tend to create a store folder where I will have two files,
- combineReducers.tsx
- configureStore.tsx
combineReducers
is where we combine our reducers into one single reducer, and where we will additionally set up the persistence, blacklist keys, and export our RootState for the application. When setting up persistence we can specify how we want our persistence to be implemented (usually via AsyncStorage). You can read more about persistence here. It’s a simple tool that allows us to persist and rehydrate our redux state.
configureStore
is where we will be putting our initial states together, setting up any middleware we have, preloading our store with the combined initial states, persisting our store, and then exporting it to be used in our provider.
combineReducers
ConfigureStore
@types
Something else worth noting is that we need to declare the type for our app’s root state. To do this, let’s create an @types folder within src. From there, we just need to do the following:
Closing 🙌
That is basically all you need in order to get started with Redux, Redux-Persist, and TypeScript. I’ve gone ahead and created two applications, one with TypeScript, and one without, that both have Redux and Redux-Persist included. You can check both of those out following the links below:
If you have any questions at all, feel free to reach out on Instagram or Twitter.
Cheers ✌️