Skip to content

Instantly share code, notes, and snippets.

@AllGistsEqual
Created January 10, 2021 23:12
Show Gist options
  • Select an option

  • Save AllGistsEqual/40a26c4600d4272a6081359a6866c173 to your computer and use it in GitHub Desktop.

Select an option

Save AllGistsEqual/40a26c4600d4272a6081359a6866c173 to your computer and use it in GitHub Desktop.

SERIES: React Native (Step by Step) - React Redux with Typescript

In our last session, we've set up a new and clean React Native Project with Typescript and Linting Support. Today we will add React Redux to the mix, a predictable state container that will allow us to manage global state in one centralised place.

As always, you will find the finished code linked on GitHub at the end of the article.

Redux: WHY

To get started, I’m assuming that you have basic knowledge of React Native and Redux. If you need a small refresher on Redux, I've got just the article for you! As we continue with the setup from our last session, we are still working with Expo to manage our React Native Build and bundling.

Now, I know that there’s currently a great hype to remove Redux and other dependencies from all projects but I’m still a firm believer in the ideas behind Redux and especially with the newest version of React Navigation (5.x at the time of writing), they improved the integration of Redux in the Navigator and we’ll make good use of that in later sessions when we add React Navigation into the mix.

Redux Toolkit, WHY

In the past, I had decided to not work with Redux Toolkit. I used to prefer the hands-on way to do it as Redux is not scary and definitely not complicated. I couldn't argue against the boilerplate argument there but then again it's not that bad and you do not spend THAT much time writing redux code in my experience.

That was "past me". "Present-day me" gave the toolset another go, made some prototypes with it, used it on a larger project and is now chuckling when thinking of "past me" vehemently NOT wanting to use it. You still write the same logic, you still write the same code more or less but you do write substantially of it and the files are more compact and way easier to read.

Getting started

Install the packages from NPM for your production dependencies and additionally the react-redux types (which are missing from the react-redux package) for development.

https://gist.github.com/7dac7437ed70db5201e22b3b22b63427

The first thing we have to do is creating a store to house all our precious data. Create a new index.ts under src/redux/ and let's start coding.

We need to configure a store with the handy function of the toolkit, add our rootReducer (where we gather all out reducers in one centralised place) and export the store we created.

https://gist.github.com/1406026e320a1b15b559e6b83b194a7a

Before we move on to write the missing rootReducer, let's first recreate THE tutorial reducer everyone is using... but with less code, thanks to Redux Toolkit. I'm throwing this under src/redux/demo because I will delete it later but for now, let's make a counter.ts file.

Thanks to the toolkit, we can let them do the heavy lifting of creating all the code for actions, reducers, types and such. The redux-toolkit comes with multiple ways to go about this (including createAction and createReducer) but by far the easiest way to do this is using createSlice, which will be enough for most regular cases excluding maybe async stuff.

https://gist.github.com/3bfaffa3f2ff223c0b9fc052ad82e42f

What we have done here is giving a name to our reducer (counter), defining its initial state and writing our two needed reducers to increase and decrease the state of our counter by the payload we send with the dispatch.

The createSlice function returns an object including (but not limited to) the actions and reducer we need to export to use them throughout our app. With this in place, we can now finally add the missing rootReducer where we register all our reducers.

https://gist.github.com/c7db970dcad0742abd299cebcbd57acb

Not unlike regular redux, we bunch up all our reducers into our state by using a combineReducers function and handing it an object with all our reducers and their desired names.

With this in place, we have a functional but useless redux store. Everything is typed so far because most types can be inferred by their usage and both redux and the toolkit come with all functions properly typed. Congratulations.

To add some functionality to our app, we have to create a component to consume the stored state and dispatch actions to change the state. In the past we would have wrapped our new component in the connect() HOC to gain access to the store and being able to dispatch actions but thanks to React Hooks, we can now simply rely on useSelector() and useDispatch() to interact with redux via react-redux.

Create a new component file Counter.tsx under src/components/demo (again, we will get rid of this demo code at a later step in our series) and get the basic stuff in

https://gist.github.com/2d230d1169a4488097d9b5e5e4f5e982

To use the new hooks with typescript, we need to touch out redux store again so let's move back to the src/redux/index.ts for a moment.

We will create an alias for both useDispatch and useSelector, add typing to them and then export those aliases so that we do not need to do this every time we want to use them. I chose to name them useReduxDispatch and useReduxSelector respectively to make them distinguishable but you can use any name you want.

https://gist.github.com/bb79dcbda873a2e193d9a6c886853a25

We've added line 12 - 14 where we define our AppDispatch type and create our typed aliases. With those in place, let's finish up the Counter.tsx file.

We import the new useReduxDispatch and useReduxSelector and use them to dispatch actions on button click and update the counter with the newest counter state.

https://gist.github.com/1d80dbaebd23aae7d8df91a32bf1f27c

Now everything is in place. Head back to the App.tsx we haven't touched since the last tutorial and add our new Counter component and as usual, our Provider component to wrap our app and provide access to our store.

https://gist.github.com/6c4f26884e6b3651cacdab8684d9574b

That's it. If you run the app with npm start and click the buttons, the counter should go up and down.

Make sure to run npm run fix to take care of any minor code style errors and make sure we did everything according to our linting and rules and it's a wrap.

Conclusion

We've continued with our React Native Typescript project from last time and added a fully functioning and fully typed Redux Store in about 30 lines of redux code (imports excluded) and a few lines of tsx. That said, I should maybe rewrite my original redux article and the updated version will be a lot shorter...

Small side note, if you want to test your redux config with ease, use the web browser version from the Expo Web Interface and open your dev tools. With the right extensions installed (react + redux) you can look at all components and the store/state with an easy to use interface.

It ain't much and it ain't pretty but it works and it is typed and scaleable.

In our next sessions, we will have a look at how to make our redux store persistent, some basic solutions for navigation and project file structure.

Here is the promised link to the (Pre-)Release tag on Github.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment