This repository serves as an online course for learning React. It’s here to help those who want to learn more about React and frontend in order to develop a SPA.
Introduction
At STRV, we believe that the best way of learning is by working on a real project. So, we’ve come up with a simple e-commerce app concept using the Commerce Layer API.
Please take note that by learning React, you will not become a frontend developer. There are many other areas you should be able to handle. Stay tuned for Frontend Nights
, where we are going to focus on everything except React. :)
Goal
The goal of this course is to give you a fundamental understanding of how to build a production-ready React web app.
The presenters demonstrated the best practices in building React applications — experience they gained by working on numerous projects.
Source
This online course was created by utilizing material from React Nights, the free offline course with a focus on React created by STRV.
Prerequisites
This course requires at least junior-level knowledge of programming, and relies on fundamental knowledge of React. Reading and understanding this amazing official documentation should be enough to get you started.
General frontend knowledge is beneficial, but not necessary. For more details, you can check the video and presentation from the first lecture
Table of Contents
Course Structure
React Nights 2019 encompasses 8 weeks of studying, 16 lectures and 8 homework assignments. The STRV Frontend Team contributed to this repository throughout the entire course.
STRV also had a dedicated team of mentors helping our students do all of the homework. The team then reviewed the homework as well, of course. :)
We are highly opinionated when it comes to development. There are many great approaches to writing apps; this repository shows you a process that is very close to what we do in the real world.
Our goal was to reveal some patterns incrementally. Some of the code was written in a way that required it to be refactored later. Therefore please don’t think of this repository as a recipe on how to build a React app. It’s more of a showcase of different topics all compiled into a single project.
Lectures
Each lecture is about 1 hour long. There are 2 lectures per week, followed by 1 homework assignment. You can follow commit history to see each lesson.
You can find recordings of all lectures, as well as links to every presentation, a Pull Request representing the introduction to the lecture, a link to the homework solutions and, finally, some additional resources (also listed in the presentations).
Week 1
00. Introduction
Introduction to the React Nights course. Please note that the course was designed to require a lot of self-studying during homework assignments. If you are planning to take this 16-hours course, we highly recommend you find a mentor who will review your Pull Requests.
Of course, you don't need to wait the entire week before continuing on to the next lesson. But we do recommend dedicating some extra time to studying the shared resources.
If you have any recommendations regarding improvements to this knowledge base, feel free to submit a PR.
Video | Presentation
01. Project Setup
As a project starter, we choose create-react-app. (Other great options could be Next.js or Gatsby.) Effective learning requires high-quality code, so we implement Prettier
and ESLint
and enforce it with a pre-commit hook
from a combination of husky
with lint-staged
. And of course, as STRV developers, we use STRV's favorite configurations from code-quality-tools.
Note that we are not covering stylelint
in this lesson, since it's a part of next week’s lesson - Styling in React. Another decision that should be made from the very beginning isTypeScript from Week 7. But to make the learning curve a bit easier, we decided to add that later. If you are brave enough, feel free to start using it right away.
Before we start to implement features, let’s get the API communication ready. And before any implementation, you should get familiar with whichever API you are going to use.
For our demo, we choose CommerceLayer API. We first read its API Reference and see we need to implement authentication to be able to get any resources. To do that, we need to create an account in CommerceLayer and get a token from API.
For a demonstration of correct implementation, we fetch List of Products
.
That’s all for now. Let's write a simple README about what we did, and how this project can be used.
Video | Presentation | Pull Request
Homework #1
This homework assignment was implemented during the lecture; see its Pull Request above.
Week 2
02. Project Architecture & React Router
The plan for this lecture is to implement Product Detail
. For routing, we use react-router. But before we start writing code, let's think about how we will structure the whole project. At STRV, we are fans of grouping by features or routes. This kind of decision should have already been made in lecture 01. Project Setup. So now, we need to refactor our code a little bit.
We will use another API endpoint, so now’s probably a good time to implement a simple http API client
. We will use native fetch for simplicity, but otherwise we highly recommend ky (tiny & elegant HTTP client based on window.fetch
) or rest-hooks.
Now everything is set and ready. Let's go for the Product Detail
!
Video | Presentation | Pull Request
03. Styling in React
We have a List of Products and Product Detail. Before we move further, let's implement some decent styles, so that the app is more pleasant to work with.
At STRV, we are big fans of CSS-in-JS - namely styled-components
. A brief introduction to history, benefits, and usage of styled-components. A showcase of styled-system
and @rebass/grid
We also set up the first styleguide. Styles live in the styled.js
file, next to the component. The only exception are global styles and variables files.
With CSS comes huge responsibility. A friendly check put into pre-commit hook by stylelint
is what you need.
And when building a real project, you should definitely check out the Storybook.
Commit
Homework #2
- Set up React Router
- Think about and implement the rest of the project architecture
- Fetch and display Product Detail
- Add styles for Product Detail
Pull Request
Additional Resources #2
Week 3
04. Global State Management
Now is a great time to implement Cart
, as well as the possibility to add products to it. We choose to demonstrate this functionality with Redux, which is one of the most widespread libraries in the React ecosystem. In this lesson, we start with gaining an understanding regarding the state management problem, we explore a number of concepts crucial for implementing the robust state management solution, and we get to build it into our project using Redux best practices.
Video | Presentation | Pull Request
05. Context API & Redux Middlewares
Redux comes with great middlewares. Let's briefly check what it’s all about. We will leverage this knowledge in the 10. Async Effects & Error Reporting lecture.
Besides that, it's also our duty to showcase a Context API
, which is more than suitable for many use cases. But without any contribution to the project.
Video | Presentation
Homework #3
-
Add to Cart
feature on Product Detail page
-
Remove from Cart
feature on Cart page
- Implement redux-devtools and use it with extension
- Extract
Button
component to make it reusable
- Add
Layout
to Product Detail page
- Update API for getting a list and a single product to return response in the same format
-
onAddToCart
function expects only productId as an argument. Calling event.preventDefault()
is done internally now to avoid leaking implementation details to outside components
- Remove pseudo-caching logic in ProductList component
Pull Request
Additional Resources #3
-
https://overreacted.io/writing-resilient-components/#principle-4-keep-the-local-state-isolated
-
Immutability examples
Working with objects
const user = {
id: 1,
firstName: 'John',
lastName: 'Doe',
}
Add property
user.age = 30 // wrong
const newUser = { ...user, age: 30 } // right
Remove property
delete user.age // wrong
const { age, ...newUser } = user // right
Update property
user.firstName = 'Jane' // wrong
const newUser = { ...user, firstName: 'Jane' } // right
Working with arrays
Add item
users.push(user) // wrong
const newUsers = [...users, user] // right
Remove item
const users.pop() // wrong
const newUsers = users.filter(u => u.id !== user.id) // right
Update item
users[0].firstName = 'Jane' // wrong
const newUsers = users.map(u => {
if (u.id === user.id) {
return {
...user,
firstName: 'Jane',
}
}
return u
}) // right
Week 4
Proper e-commerce should have a user profile, where our users can change their information or see their past orders. Let's implement a Sign Up
page with Formik and do a client-side validation with yup
Video | Presentation | Pull Request
07. Authentication & Routing in Depth
Sign in, authentication, private routes, redirecting. With this lesson, our app is almost ready.
Video | Presentation | Pull Request
Homework #4
- Create the login page with a
login form
- Connect login form to API
- Get customer information and store it in Redux
- Determine in
PrivateRoute
whether a user is authenticated
- Show/hide
MyProfile
link according to the authenticated state
- Add
log out
functionality
Pull Request
Additional Resources #4
Week 5
Our app is almost ready. Now is the time to properly tune it! Of course, in the real world, we should start following "advanced" patterns right away. But for learning purposes, we believe that this is the easiest way how to understand it.
08. Functional Programming
React is functional, so let's learn how to make our app functional as well. This is more of a theoretical lecture, with great examples in the Observable notebook.
Video | Observable notebook
09. HOCs, Render Props, Hooks
During the previous lesson, we saw many code repetitions. Let's make it more DRY!
In this lesson we are doing a minor refactor from redux to hooks. On first sight, it looks good and awesome, but it will backfire us in ### Week 7. This was done on purpose; it allows us to demonstrate that every decision in your codebase matters and requires a lot of thinking.
Video | Presentation | Pull Request
Homework #5
We’ve now done a major refactor to display how Hooks can save us a lot of typing.
Pull Request
Week 6
10. Async Effects & Error Reporting
So far we were following a happy path of development, meaning that everything should be working as expected. But in the real world, that’s never the case. From time to time, the API server is down, internet connection is weak or there is an unexpected error in our code.
Video | Presentation | Pull Request
11. Testing in React
Testing is very important in the development of any software. Let's take a look at how it works in the React world. Pull Request comes with a lot of practical examples.
Video | Presentation | Pull Request
Homework #6
- Move logic to chosen async solution (default: redux-thunks, advanced: redux-sagas, redux-observables)
- Handle refresh tokens
- Notify a user about errors from
server/network
and success
(product added to cart/deleted from cart/logged in)
- To mock server responses
401/500
you can use https://www.charlesproxy.com/
- If you find this homework too easy, please refer to
Up for the challenge?
slide for problem inspiration
Pull Request
Week 7
12. TypeScript
TypeScript is really trendy these days. We love it at STRV. Hopefully, you will love it too!
In this lesson, we start with the basics of static typing and move on to more advanced topics, such as derived types and type guards. The aim is to bring the power of TypeScript into our application and see how we can type components, reducers and API calls.
Video | Presentation | Pull Request
13. Server-side Rendering vs. Static Export
Since we are going to production soon, let's think about how our app should work there.Since we are going to production soon, let's think about how our app should work once it’s live.
Because of widely dynamic content, it does make sense to do a SSR. We choose Next.js.
This introduces a major refactor. We could probably choose razzle
, which has a react-router under the hood. But still, it usually makes sense to make this kind of decision at the very beginning of the project.
Video | Presentation | Pull Request
Homework #7
- TypeScript
- Move from create-react-app to Next.js
- This is a huge refactor.
- It refers to proper project setup. Meaning you should know what you are building from the very beginning; otherwise, you can choose incorrectly and then spend extra time with an unneeded refactor.
- Convert your codebase into SSR using STRV branch as reference
- Remove
react-scripts
- Add
next
and related libraries (@zeit/next-css
, @zeit/next-typescript
, express
, isomorphic-fetch
, next-redux-wrapper
, @types/next
)
- Adjusts scripts section of your
package.json
to work with next instead of react-scripts
, check the one defined in the project for reference.
- Replace
useApi
hook usage on Products List and Products Details with getInitialProps
, you could either set the data in redux or show it right away as the hook did.
- If you’re feeling like a ninja, implement the loading status in case you decide to go with the redux approach.
Pull Request
Week 8
14. Optimizing React Apps
Our app seems to be working fine. Let's talk about optimization and bringing users the best user experience possible.
Video | Presentation
15. Deployment
Finally, it's time to deploy our production-ready app!
Again: in the real world, (continuous) deployment could be set up in earlier stages of a project’s lifetime.
Video | Presentation
Homework #8
Optimize and deploy!
Used technologies
- Project Starters
- Code Quality Tools
- Formatting - EditorConfig, Prettier
- Linting - ESLint, stylelint
- Static Type Checking - TypeScript
- Enforced with pre-commit and pre-push hooks from husky in combination with lint-staged
- React
- Styling
- styled-components
- styled-system
- State Management
- Forms
- Tests
- Jest
- react-testing-library
- Cypress
Credits
Big kudos to the whole Open Source community for making it possible to create this type of course! ❤️
Of course, thanks to the STRV Frontend Team for participating in the course and helping with the preparation. And finally a huge thanks to our brave students, who took the course and provided us with feedback!