Prerequisites

  • You'll want experience with React before going through this material. The lessons get progressively more advanced. Once you hit something you're unfamiliar with, that's your cue to go back and review the other parts of EpicReact.Dev.

NOTE: The EpicReact.dev videos were recorded with React version ^16.13 and all material in this repo has been updated to React version ^18. Differences are minor and any relevant differences are noted in the instructions.

System Requirements

  • [git][git] v2.13 or greater
  • [NodeJS][node] >=16
  • [npm][npm] v8.16.0 or greater

All of these must be available in your PATH. To verify things are set up properly, you can run this:

git --version
node --version
npm --version

If you have trouble with any of these, learn more about the PATH environment variable and how to fix it here for [windows][win-path] or [mac/linux][mac-path].

Demo

Hosted on https://bookshelf.lol

Setup

If you want to commit and push your work as you go, you'll want to fork first and then clone your fork rather than this repo directly.

After you've made sure to have the correct things (and versions) installed, you should be able to just run a few commands to get set up:

git clone https://github.com/kentcdodds/bookshelf.git
cd bookshelf
node setup

This may take a few minutes.

If you get any errors, please read through them and see if you can find out what the problem is. If you can't work it out on your own then please [file an issue][issue] and provide all the output from the commands you ran (even if it's a lot).

If you can't get the setup script to work, then just make sure you have the right versions of the requirements listed above, and run the following commands:

npm install
npm run validate

If you are still unable to fix issues and you know how to use Docker 🐳 you can setup the project with the following command:

docker-compose up

It's recommended you run everything locally in the same environment you work in every day, but if you're having issues getting things set up, you can also set this up using GitHub Codespaces (video demo) or Codesandbox.

Running the app

To get the app up and running (and really see if it worked), run:

npm start

This should start up your browser. If you're familiar, this is a standard react-scripts application.

You can also open the production deployment: bookshelf.lol.

Running the tests

npm test

This will start Jest in watch mode. Read the output and play around with it. The tests are there to help you reach the final version, however sometimes you can accomplish the task and the tests still fail if you implement things differently than I do in my solution, so don't look to them as a complete authority.

Working through the exercises

To get started, run:

node go

This will allow you to choose which exercise you want to work on. From there, open the INSTRUCTIONS.md file and follow the instructions.

If you'd like to work on an extra credit, but you want to skip the preceding steps, you can run node go again:

node go

This will let you choose the next exercise or you can choose which part of the exercise you'd like to work on. This will update your exercise files to the correct version for you to work on that extra credit.

Exercises

The exercises are in different branches. Each branch changes the INSTRUCTIONS.md file to contain instructions you need to complete the exercise.

The purpose of the exercise is not for you to work through all the material. It's intended to get your brain thinking about the right questions to ask me as I walk through the material.

Helpful Emoji 🐨 💰 💯 📝 🦉 📜 💣 💪 🏁 👨‍💼 🚨

Each exercise has comments in it to help you get through the exercise. These fun emoji characters are here to help you.

  • Kody the Koala 🐨 will tell you when there's something specific you should do version
  • Marty the Money Bag 💰 will give you specific tips (and sometimes code) along the way
  • Hannah the Hundred 💯 will give you extra challenges you can do if you finish the exercises early.
  • Nancy the Notepad 📝 will encourage you to take notes on what you're learning
  • Olivia the Owl 🦉 will give you useful tidbits/best practice notes and a link for elaboration and feedback.
  • Dominic the Document 📜 will give you links to useful documentation
  • Berry the Bomb 💣 will be hanging around anywhere you need to blow stuff up (delete code)
  • Matthew the Muscle 💪 will indicate that you're working with an exercise
  • Chuck the Checkered Flag 🏁 will indicate that you're working with a final
  • Peter the Product Manager 👨‍💼 helps us know what our users want
  • Alfred the Alert 🚨 will occasionally show up in the test failures with potential explanations for why the tests are failing.

Workflow

  • Checkout the exercise branch
  • Read through the INSTRUCTIONS.md
  • Start exercise
  • Go through every mentioned file and follow the instructions from the emoji
  • We all come back together
  • I go through the solution and answer questions
  • Move on to the next exercise.
  • Repeat.

App Data Model

  • User

    • id: string
    • username: string
  • List Item

    • id: string
    • bookId: string
    • ownerId: string
    • rating: number (-1 is no rating, otherwise it's 1-5)
    • notes: string
    • startDate: number (Date.now())
    • finishDate: number (Date.now())

For convenience, our friendly backend engineers also return a book object on each list item which is the book it's associated to. Thanks backend folks!

/me wishes we could use GraphQL

If your "database" gets out of whack, you can purge it via:

window.__bookshelf.purgeUsers()
window.__bookshelf.purgeListItems()
  • Book

    • id: string
    • title: string
    • author: string
    • coverImageUrl: string
    • pageCount: number
    • publisher: string
    • synopsis: string

Troubleshooting

Running "node go" does not list any branches

This means there was something wrong when you ran the setup.

If you made your own fork of bookshelf through GitHub, you may have only got the main branch -- that's the default option

Add a new upstream remote

git remote add upstream https://github.com/kentcdodds/bookshelf.git

You might get an error: remote upstream already exists. -- no problem!

Track all the branches from that original repository

git push origin --tags "refs/remotes/upstream/*:refs/heads/*"

Workshop Feedback

Each exercise has an Elaboration and Feedback link. Please fill that out after the exercise and instruction.

At the end of the workshop, please go to this URL to give overall feedback. Thank you!

Transcript

Kent C. Dodds: 0:00 I am so excited for this one. All of those workshops that you've been through in learning all of these concepts in total isolation, it's been beautiful. It's pretty little garden that is well kept in everything, but then you go to a real application and nothing is that way. Everything is complicated.

0:24 Real applications are not perfectly manicured. Real applications have complexity and they have some nuance to them that makes things a little bit more challenging. That's why I love that I have built this bookshelf app for you so that you can apply these things that you've been learning in a real application.

0:45 I'm excited. Let's jump in. Here is our bookshelf app. It's kentcdodds/bookshelf on GitHub. Lots of it is the same in the way that you get it set up. We still have the same requirements. We have the setup script that you run, but things are a little bit different.

1:02 For one, it does not ask for your email because the way that things are structured is quite a bit different. You'll notice this is a real app. We've got the src directory. We've got our index.js. We've got different screens. We have components.

1:17 I didn't want to mockup everything in the application with a bunch of exercise files and stuff. The way that this one works is we have a different branch for every part of the app that we're going to build. Here, let's go ahead and get on to the different branches.

1:35 You can run git checkout to check out the different branches, but I built something for you to make it a lot easier for you to get going with each one of these branches. Instead of checking out different branches and things, what you're going to do is you'll run node go.

1:52 Go is a script right here. You can dive into it if you're interested. What node go does is it says, "Hey, which exercise do you want to start working on?" Then, you can just navigate with your keyboard, your up and down arrows.

2:06 Here, we'll say, "OK, I want to work on that first exercise," so it will go to bootstrap and it checks out the branch and it gets everything set up for you so that you can start working on this exercise.

2:16 The way that things are structured here is also quite a bit different. We don't have an exercise directory and a final directory and a markdown file for things. We have a single markdown file that is updated for every one of these exercises, and it's an INSTRUCTIONS.md file.

2:35 Here, we're learning about rendering a React app. Every single time you go to a new exercise, you're going to want to open the instructions, because this is where it's going to have the background. It will have information on the exercise, and it will also, inside of that information it will tell you the files that you're going to working in, which is important. I'll show you here in just a second.

2:54 We also do have extra credit in here and it will tell you the files that are relevant for the extra credit. Toward the bottom, you have your elaboration feedback.

3:05 You are going to be working in the markdown file directory. There's nothing that renders that markdown file for you. You want to open up that markdown file. After you have read everything, you're ready to rock and roll, then you want to make sure that you start the server, so we have it going.

3:22 Sometimes you may actually have to restart the server, because Webpack is, "Whoa, whoa, where did these files come from?" Sometimes you may have to restart the server and...Sorry about that. There's not much we can do, but once, you're ready to rock and roll.

3:35 Then if you open up this src/index.js, I'll just paste that in there, you'll notice that there is something weird going on here where it has a couple of commented out things here. If you run the node go script, then it updates this file for you to say, export * from './index.exercise'.

3:56 Let's look at our file system and we'll see that we have the index.js, which is what we're looking at. Then an index.exercise.js, an index.final, and then index.extra1 and 2. This is the way that we structure things in this one. You'll find the final version of what you're supposed to do in the .final and then those extra credits there as well.

4:18 Everything is a .exercise.final throughout the workshop. For this one, we have one file that we're working in. In other exercises, you're going to have many files that you're going to be working in.

4:33 This is what makes this more realistic, because normally, you're not just making a change in a single file and then the world is your oyster. Normally, what ends up happening is you have to change in this file and then in this file.

4:48 Our instructions are going to show you exactly which file you're going to be working in. Then our friend Cody the Koala bear we'll be here to tell you what you're supposed to do. If you do get totally lost, then you can go to your index file and everything should work just fine.

5:04 That's the unique thing about this exercise, just to make it practical, so that it's like, "This is a real thing," but also, you can actually use it. You're pretty much going to be working in the index.exercise or in the .exercise version of all of the files, even for all of the extra credits. That's one thing that you want to keep in mind.

5:27 Another thing that you'll want to keep in mind is that this is a much huger, larger workshop than any of the others. In fact, when I give this workshop as a live workshop, I split it up into four parts. You can interleave this workshop into the other ones if you want to, however you want to structure that, but this one workshop should take you a very long time.

5:54 In addition, it's also intentionally a little ambiguous because I want you to struggle with this a little bit more, because it's a more real-world scenario. Keep that in mind as well. There's a lot more for you to do and some guesswork that you need to do.

6:09 I don't want you to bang your head against a wall trying to transform it into a door or anything, but I do want you to struggle just maybe a little bit as you go through all of these. It's way less handholding. There is way more material in each of these exercises.

6:27 I hope you look forward to that. It makes for a nice way to round things off from the totally isolated exercises that you've been doing in the other workshops and giving you a more realistic real-world experience in this actual application.

6:47 Enjoy this one. You're going to have a blast. If you get totally stuck, feel free to reach out to other folks in the Discord because you might need that and we're all here to help each other. Have fun, and I'll see you all the way on the other side of this workshop.