React Bootstrapping — Quick Start with Typescript, Linting, Redux & Router

Konrad Abe
6 min readFeb 1, 2021

--

Setting up a new project can be a daunting task. So many packets that need to work in concert and so many things to keep track of, that could go wrong or be incompatible in certain versions. Add typescript to the mix and you are in for a fun journey with untyped packages, missing return types and complex interfaces.

I’ve recently set up a new project base for one of our customers with a well planned and fully functional stack and I’m about to offer the finished project (minus some customer-specific features) as a starter template for you to save some time. Or maybe you have your own project running but want to see how to set up some packages in combination? Just lean back and enjoy the show.

SERIES: React Bootstrapping
1) => you are here <=
2) Deep Dive into Redux Messaging Patterns

All code is online on GitHub including separate commits per feature so either code along or copy what you need. This is a two-sessions tutorial, this week we will take care of the business logic and next week we will add styled-components, storybook and testing.

Kick-off

To start, we will use create-React-app to start with a fresh typescript template using the --template parameter.

create-react-app yourProjectName --template typescript

This gives us a preconfigured react app using typescript with all of the configs taken care of and webpack fully set up, loaders and all.

GitHub Commit (not worth looking as it’s just the boilerplate from create-react-app)

Check the controls

The next step in every project I work on is setting up eslint, prettier and the .editorcofig file.

If you run this command in your terminal, it will install all dependencies, plugins and presets needed for this setup.

npm i -S eslint eslint-config-airbnb eslint-config-prettier eslint-plugin-prettier eslint-plugin-react eslint-plugin-react-hooks @typescript-eslint/eslint-plugin @typescript-eslint/parser prettier

In this guide, I’ll keep it short and point you to my files, but I’ve recently written a longer article about linting in typescript projects so if you would like more information on this topic, head over to my other article about linting in react-native projects. Even though this article is for React Native / Expo, the linting is basically the same so I recommend to take a look at it if you want to know more.

To continue with our current step, go to this repository and copy the following files and put them into your project’s root:

Then head over to your package.json and add the following 2 lines in your scripts object.

"lint": "tsc --noEmit && eslint --ext .js,.jsx,.ts,.tsx ./ || true",
"fix": "tsc --noEmit && eslint --fix --ext .js,.jsx,.ts,.tsx ./ || true",

If you run npm run lint in your terminal, you will get the linting output and running npm run fix will try to fix and prettify all your files according to your linting rules.

GitHub Commit A Changes

GitHub Commit B Applied Linting

Keep track of your state

Next step on our fast-paced journey is adding redux, using the redux toolkit (rtk).

Again, grab the necessary packages from npm and we can continue.

npm i -S react-redux @reduxjs/toolkit react-router react-router-dom connected-react-router @types/react-redux @types/react-router @types/react-router-dom history@4.10.1

Mind the version number. At the time of writing (01/02/2021), using a v5 of history will break stuff because of incompatibilities. If you run into other issues, feel free to copy my package-lock.json to get the exact working setup I’m using.

With this in place, we need a file to export our store and another for our rootReducer where we register all the reducers we are going to write. We will add them under src/redux/.

Again, you can grab them including a demo file using the created react hooks from my repo.

What’s special about this? We are using the default react hooks for useSelector and useDispatch but we wrap them in our own variations including all the typing needed to satisfy typescript and export them again as useTypedDispatch and useTypedSelector. We don't have middleware yet so this line is commented out but I've left it there for when I write my middleware in the future.

If you look at the rootReducer, you can see how we hooked up the demo counter reducer and our route reducer. I’ve added a TODO marker to keep track of the fixed history package version here as a reminder to check for updates when going through my TODOs.

Last but not least, this is the counterReducer, small and readable thanks to Redux Toolkit.

Next stop is our router. In the past, it was seen as an anti-pattern to pair routing and state/redux but over the last few years, this has become a proven setup that allows us to control user navigations and state in a more fine-grained and state-checked manner. To make this work, we will ad React-router and connected-React-router for easy integration of both.

To check if Redux and Routing work, we will add a demo/counter example and set up some basic routing.

Create or copy the following files from my repostitory:

  • components/demo/Counter.tsx
  • routes/index.tsx

In the Counter component, you can see the typed redux hooks at work. It’s your well known basic counter example, just a bit shorter.

Our demo version of the routes is similarly simple but it should be enough for you to understand the general idea and expand on it. We’re creating a reusable NavBar Component here to simulate a real navigation and a couple of stand-in pseudo page components for home, hello and our counter page as well as a generic 404 for broken/unmatched URLs.

By adding the counter.tsx component to the project in one of the routes, we can see that routing and redux work. If you run npm run lint again, the linter and ts compiler won't flag any typescript issues either. Another hurdle taken.

If you check the redux tools in your browser, you can see that every navigation action triggers an action on our store and that our counter actions are clearly discernable by their [DEMO] prefix.

GitHub Commit (final)

Conclusion

We’ve covered a lot of ground today, skipping some of the finer details. As mentioned before, the idea is to allow for a quick setup. I will add more articles in the future, looking in-depth into some of those topics I have not covered yet in other articles.

Next week we will add Storybook and styled-components. Having a dynamic and interactive UI library as part of a project can be a real asset. Storybook has proven it’s worth for us many times over, allowing us to show UI elements on their own with adjustable attributes and toggles in an intuitive web UI. Your QA and Design/Concept teams will love it.

Some words about me:

If you want to see more of my work and progress, feel free to follow me and check out my other articles. If you clap feverishly for the articles you like most, it will be easier for me to decide which directions to pursue in following articles so use your ability to cast a vote for future content.

I’m also currently working on other series covering complex React Native Setups using Typescript and scalable apps with Redux, where I’ll go into details about how and why I do stuff the way I do as well as some articles on my experience in building games for web and mobile with React.

Here are some of my recent topics:
- Linting/Prettier with Typescript
- Redux + Toolkit with Typescript
- Spread & Rest Syntax in Javascript
- clean and simple Redux, explained
- Game Theory behind Incremental Games
- Custom and flexible UI Frames in React Native

And if you feel really supportive right now, you can always support me on patreon, thus allowing me to continue to write tutorials and offer support in the comments section.

--

--

Konrad Abe

I’m a Web / App Developer & father 👨‍👩‍👧 doing freelance and part-time agency work since 2003, 💻 building stuff on the side 🕹 and attending conferences 🎟