reduxjs/redux

Rewrite "Redux Essentials" tutorial to be TS-first and show RTK 2.0 usage

markerikson opened this issue · 16 comments

The "Essentials" tutorial currently uses only plain JS for all of the examples and content.

If you want to learn how to use Redux with TS, we have two separate pages:

  • "TS Quick Start", which just gives quick examples of inferring types from the store, defining typed hooks, declaring slice state and action types, and using the hooks
  • The longer "TS Usage" guide page, which is a laundry list of various use cases

Unfortunately neither of those have any larger context for how TS gets used in practice.

I want the "Essentials" tutorial to cover TS usage. However, some of the suggested approaches are impractical:

  • If we rewrite the entire tutorial to be TS-first/only, then it adds an extra barrier to learning for anyone who doesn't know TS yet. Since we do have a lot of folks still being pushed into Redux fairly early on, this is likely to be a significant number of people who would now have to decipher TS on top of Redux basics
  • The next obvious approach is "use a TS/JS language toggle". We already do this in the RTK docs for the examples, and we did just add that same capability to the Redux core docs. However... the tutorial is way more than just some example snippet blocks. It's an entire app repo with a commit history. In addition, there's a ton of explanations of "here's what this code is doing", and the point of this is to explain how to use TS for as much of the actual app code as possible. If we were to make all the code toggleable, then we'd somehow have to start toggling large chunks of explanation, too. Technically feasible, but this would be extremely hard to write coherently.

I think the best approach is to add a "Redux Essentials, Part 9: Redux and TypeScript" page that would cover the TS material as a capstone to the tutorial sequence. I'm picturing a page that would run through some of the key code sections and API examples from the earlier pages in the tutorial, and explain how you'd write that same code from scratch with TS.

There was also a great suggestion on Twitter here at https://twitter.com/MikeLunarLandis/status/1551777390447079425 :

I can see prefacing the JS docs with a "We'll cover the TS-specific stuff at the end" note. Then, where it's important in the JS docs for TS folks to know about, say, inference adapters, add a "TS" badge that references the relevant section at the end.

I think that strikes a good balance between showing meaningful examples of TS usage, and not having to maintain multiple copies or weird back-and-forths in the main tutorial sequence.

Hey, it is an interesting task. I am taking a stab at it. :)

@zvolcsey Hiya! Appreciate the offer of help. Normally I'd go ahead and coach you through contributing to a docs page, but this particular page is one that I do intend to work on myself in the near future, so probably best if we save that one for me to tackle.

Just to check, any of the other open docs issues sound like something you'd like to help with?

Thanks for the answer. I got it. I'll look for other open issues. :)

Alternately: it would still be really neat to have full-blown tutorials that let you toggle between JS and TS.

As noted above, this would be non-trivial. Really, the biggest issue would be around trying to write the content in a coherent way that makes sense no matter which version you have toggled on.

But, there is at least a good example of this now. The Vue docs do this with "Options API" vs "Composition API", and the display mechanism is "just" toggling some CSS classes:

Maybe it's worth taking a stab at this.

The other issue is that the sandboxes would probably need to be TS, but that would be an issue for people reading along in JS mode.

FWIW, I've settled on actually rewriting the tutorial to be TS-first. Don't have an ETA on when, though.

Also figure out how to add a good 1 action : n reducers example:

https://twitter.com/MichaelWealcome/status/1670763631338766337

I hope to actually start working on this in the next couple weeks!

My first task will be to modernize the existing "Essentials" and "Fundamentals" example apps to use Vite instead of the current CRA4. This will both speed up build times and resolve the previously reported issues with Webpack 4 and Node/OpenSSL errors. I've got the setup changes figured out, and tomorrow I should be able to get the repo histories rewritten to have those changes in place.

After that, I'll start trying to plan out changes to the actual "Essentials" tutorial. My biggest question is around changes to content:

  • The existing tutorial only shows extraReducers as a way to handle createAsyncThunk. I'd like to have some feature in the app that justifies having multiple slices handle the same action, to show that's possible and a reason to use extraReducers. (Maybe some kind of auth system, and have all slices handle a logout action?)
    • Related to this, I do plan to keep the existing "async thunks" section, and I'll probably keep the thunk declared separately as-is. But, I would say "FYI you can declare thunks inside" and have a details section showing how to do that.
  • I'd also like to have a reason to show off the listener middleware for side effects.

As always, the trick is to both come up with example features in the app that justify using those features, and have it make sense in the context of the app and the source code.

I'd appreciate suggestions for potential features to the example app that would justify these!

(@EskiMojo14 just suggested maybe using the listener middleware to add a toast feature, which could work!)

Pleased to report I've started the TS conversion effort!

My first goal is to convert the entire tutorial-steps commit history from JS to TS. The only code changes I'm going to make are adding TS types, tweaking formatting where necessary, and converting the routing from React-Router v5 to v6.

Once I've got the entire commit sequence converted to TS, I'll step back and start figuring out what additional code changes I want to make (new features, etc).

WIP is available at:

(As a side note, at some point I apparently ran across https://timothycurchod.com/writings/redux-essentials-app-in-typescript , which does a similar conversion. @timofeysie , thanks for taking the time to do that conversion and put up that post! I'm going to do my own conversion independently, partly because I want to refresh my memory of what all I did in the original code. It'll be interesting to see how close we end up!)

Was able to come up with a decent motivation for both "1 action -> many reducers" (auth logout clearing auth and posts slices), and listeners (toast on "post added").

Put together first draft impls for both of those here:

While not directly related, it might be worth coming up with a better tagline and basic description than "predictable state container". A learner was confused and had no idea what that meant.

Maybe ought to copy-paste the "Redux helps you manage "global" state" paragraph from the "Essentials" tutorial into the "Getting Started" page, and also come up with a better 1-liner from the home page.

It's pretty hard to distill Redux down into a tagline. The shortest I can come up with is "A clear and consistent way to keep track of app state and ensure that different parts of an app have access to the most up-to-date data for building scalable and maintainable applications." That could be re-worded a bit to avoid saying app three times I suppose.

Maybe something like "A library for predictable global state management in JS apps" ?