Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Docs Rewrite] Rewrite the existing "Basics/Advanced" tutorial sequence #3855

Closed
markerikson opened this issue Aug 14, 2020 · 4 comments
Closed
Assignees
Labels

Comments

@markerikson
Copy link
Contributor

markerikson commented Aug 14, 2020

Overview

The existing Redux "Basics/Advanced" tutorial sequence desperately needs to be rewritten. While it's been useful for many people, the target audience of the Redux docs has changed considerably since Dan first put it together. At the time, Dan said:

So hard to write the new docs. Many different audiences to cater to.
Should make sense to: Flux beginners, FP people, FP people who don't get Flux, Flux people who don't get FP, normal JS people too
Flux people: "is this proper Flux?" FP people: "is this that weird thing called Flux?" Normal people: "why not Backbone"

Clearly, the audience today is very different.

The existing tutorial teaches Redux using a "bottom-up" approach, explaining how each piece works individually, and building up towards putting them together into something useful. The new "Redux Essentials" tutorial that I just wrote teaches Redux "top-down", explaining "how to use it the right way", but not covering how it works. Both approaches are needed.

Flaws with the Tutorial

  • The audience has changed completely. No one remembers what "Flux" is, no one's coming from Backbone, and a lot of people are being thrown into Redux in a bootcamp. (In fact, the first page of the tutorial said "If you've ever built a Flux app, you'll feel right at home" until I finally removed that just recently.)
  • The tutorial has built up a lot of cruft: asides, "don't do it this way" interjections, caveats, etc, that are very distracting
  • The emphasis on the "container/presentational" pattern for React usage, along with teaching connect as the main React-Redux API
  • The "Middleware" page spends too much time talking about why middleware are written in their current form, instead of how to use them or write them correctly.
  • There's very little sense of flow or sequencing between pages. They sorta claim to be building a "todo" app and a "Reddit" app, but it's just some code snippets in isolation, nothing keeping them in sync with a real repo, etc.
  • No runnable sandboxes
  • While doing everything by hand makes sense for this tutorial, it still shows patterns like the typical const ADD_TODO = "ADD_TODO", having separate folders for /actions and /reducers, etc. We now recommend against those approaches, so we need to stop teaching them.

Goals

My main goals here are:

  • Drop all outdated references ("Flux", "containers", etc)
  • Show simpler patterns (inline action types like {type: "todos/addTodo"} vs const ADD_TODO = "ADD_TODO", single-file Redux logic)
  • CodeSandbox examples
  • Show React-Redux hooks as the default
  • Improve explanation flow

I'll need to figure out how to balance teaching the individual concepts, with having a coherent set of examples and explanations.

Existing Redux Tutorial Sequence Notes

Previous Personal Notes

Feedback

Introduction

  • "Getting Started": remove basic example?
  • "Motivation / Core Concepts / Three Principles":
    • content isn't bad, but should these get moved somewhere else?
      -"Motivation" is a bit dated ("models", the "time to give up?" link)

Basics

  • URL currently /basics - should be /tutorials/something

Actions

  • No background for why these matter at all
  • Everyone's favorite const ADD_TODO = 'ADD_TODO'
  • "Actions are payloads that send data to the store"
    • Confusing phrasing
    • Haven't even talked about stores yet!
  • "Actions must have a type property that indicates the type of action being performed"
    • Should say something about "readable name that describes what happened in the app"
  • "Types should be defined as string constants and moved into a separate module"
    • delete
  • "Note on Boilerplate"
    • Remove / re-think
  • "Structure of an action is up to you"
    • Links to FSA page, but we ought to emphasize payload more
  • "Good idea to pass as little data in the action as possible"
    • Good to say "pass index instead of the whole todo", but rephrase this somehow
  • Actions are jumping straight into doing "todo app"-related stuff, with no context for what we're building, why, what features, etc
  • "Action creators"
    • This is almost definitely being introduced too early
    • Comparison to "traditional Flux"
    • Use of "binding action creators"? Also, we're talking about dispatch and none of that's been mentioned yet
    • "Portable and easy to test"? Delete
    • "Action creators can be async and have side effects, read this later, but don't skip ahead"

Reducers

  • "Reducers specify how app state changes in response to actions sent to the store"
    • We still haven't defined what a store is
    • "Actions describe what happened" is good
  • "Designing the state shape"
    • should this concept come before the "actions" part?
    • "Minimal representation of app state as an object" is good
    • "Todo app", but we still never even said what we were building!
    • "Keep all state in a single tree": bleh
    • "Note on relationships":
      • too complex for this level of a tutorial!
      • Didn't define "normalized", links to normalizr instead of our own docs page
  • "Handling Actions"
    • "Pure" and "side effects" are never defined
    • Clear example of initial state is good
    • Remove "easy"
    • Use of Object.assign({}, state, arg): ew!
    • "Object spread proposal" should change
    • Object.assign() warning (ES6? really?)
    • Note about "switches aren't boilerplate, dispatching actions is": remove this
  • "Handling More Actions"
    • Shows a bunch of array spreading and stuff, without explaining what it's doing
    • References to immutability-helper, updeep, and Immutable.js
  • "Splitting Reducers"
    • "Our code is rather verbose": well, yeah, when you write it that way!
    • Good example of "reducer composition"
    • Explanations around combineReducers / imports / reducer naming are a bit confusing
    • Remove the "Note for ES6 Savvy Users"

Store

  • "Store is the object that brings them together"
    • Okay, but it'd be nice to know that ahead of time
  • "Store responsibilities": good
  • "Easy to create a store if you have a reducer": drop "easy"
  • Showing updating a store by itself: good
  • "You can write tests for reducers and action creators, because they're pure functions": should drop this

Data Flow

  • Consider moving this earlier in the sequence?
  • "If you're not convinced, read 'The Case for Flux'":
    • should probably remove this, or add it as a reference later instead.
  • Reducer example
    • references todoApp without defining it
    • At least call this todoAppReducer or something
  • combineReducers example
    • Do we want this here, or in the "Reducers" page?
    • Useful info to have
  • Should really include the "how Redux integrates with a UI" steps from my own slides
  • "Note for advanced users: check out the Async Flow page"
    • should go away
    • especially the phrase "async actions"

Usage with React

  • Delete link to deku lib
  • Remove UMD mentions for now
  • "Presentational and Container Components"
    • Delete this entirely
  • "Designing Component Hierarchy"
    • "Design Brief"?
  • "Designing Presentational Components"
    • Good arguments here, but this is all going to change
  • "Designing Container/Other Components"
    • Ditto
    • Might be worth mentioning something about "if you want to separate your components so that some of them are aware of Redux, and others just display data from props, you can use connect"
    • Also, really this is overkill anyway - why do we need components whose only job is to be connected and then pass down more data?
  • "Implementing Presentational Components"
    • Drop "functional stateless" phrasing
    • Drop "convert to classes"
    • Use our new Docusaurus file name headers for code blocks
    • Probably drop use of PropTypes
  • "Implementing Container Components"
    • Yep, goes away
    • Thought: show difference between having TodoList pass down click handlers, and letting Todo dispatch its own actions?
  • This page, more than any other, will need to be rewritten from scratch

Advanced

This section should not at all be called "advanced". This is pretty key info, and the only real distinction here is that it's stuff that goes beyond using Redux synchronously by itself. Consider renaming it to something else.

Async Actions

  • I hate the phrase "async actions". Stop using it.
  • Intro points out that the todo app is synchronous and that this section talks about how async fits into the Redux flow, so at least it's got that part right
  • "Actions"
    • Actually a good explanation of the whole "three-phase actions" approach
    • No one actually dispatches the same action type with an error flag, even despite FSA. Drop that.
    • Drop the link to redux-actions
  • "Synchronous Action Creators"
    • all the constants go away, use action.payload, etc
    • receivePosts() converts json.data.children.map(). Good idea, or bad idea?
    • Skips error handling deliberately
  • "Designing the State Shape"
    • rethink "fetching" fields
  • "Designing the State Shape"
    • Should consider how to handle loading state here
    • Change example titles :)
    • Actually talk about normalization here? Probably need a better explanation of what it is in the first place
  • "Handling Actions"
    • Drop use of Object.assign
    • Does show an example of the "list/item reducer" pattern, which is useful to know
    • Can drop the explanations of ES6 syntax here - assume that as given
  • "Async Action Creators"
    • worth showing how middleware work first?
    • drop polyfills discussion
    • I don't understand the point of invalidateSubreddit
    • If we're going to break down thunks, should probably do so as text, not comments embedded in a block. (Should be able to reuse some of the explanation from the "Essentials" tutorial?)
    • Needs more of an explanation of "store enhancers"?
    • prefer use of async/await ?

Async Flow

  • This page is basically useless. At a minimum, this info ought to be somewhere before all that stuff about thunks and loading spinners and everything else.
  • Needs an expanded version of the data flow diagram
  • Does mention the "sync data flow" coming into play
  • Desperately missing coherency for the example app being built, plus complete source code

Middleware

  • The intro is pretty good
    • I do like "provides an extension point between dispatching an action and the moment it reaches the reducer", plus example use cases
  • Need to drop the entire "how did we get to this syntax?" approach, and instead focus on "here's how to write it", with a pointer to the "why" elsewhere
  • Needs much better explanation of how to set up and use applyMiddleware
  • Example middleware aren't bad
  • Change references of store to storeAPI

Usage with React Router

  • This whole page probably ought to go away

Example: Reddit API

  • Drop this whole page, replace with a CodeSandbox of whatever we build

Next Steps

  • Needs to talk about Redux Toolkit and the "Essentials" tutorial
@markerikson markerikson self-assigned this Aug 14, 2020
@MilosRasic
Copy link

Everything looks awesome, just have some feedback on the action naming part.

  • I don't think teaching that inline action names is a good idea. Sure, it makes tutorials simpler and reduces the boilerplate shock effect, but I've seen a lot of newbies and even intermediate devs stick to what they've seen in tutorials as best practice and reject everything else. For example, back when Redux started, I'd suggest if..else or function lookup tables for some reducers and they'd be like "Nooo, never do that, Dan Abramov only uses switch. It's the best practice!".

  • ADD_TODO or todos/addTodo sounds too imperative. The most common mistake I see these days is imperative set/clear/reset/toggle/update/delete/add style actions which don't describe what happened and instead describe how we want to update the store. Something like TODO_ITEM_ADDED or todos/itemAdded would better underline the fact that actions describe what happened.

  • Maybe suggest redux-toolkit or a similar library-less way of having generic factories for three-phase thunks. It is in advanced section after all. Instead of suggesting

{ type: 'FETCH_POSTS_REQUEST' }
{ type: 'FETCH_POSTS_FAILURE', error: 'Oops' }
{ type: 'FETCH_POSTS_SUCCESS', response: { ... } }

could have an example of a simple thunk creator function that's passed FETCH_POSTS and implicitly generates the above three action types.

@markerikson
Copy link
Contributor Author

@MilosRasic yeah, I'm inclined to go with 'todos/todoAdded' as well.

The point of the inline action names is to remove the extra line of code needed for the old classic const ADD_TODO = "ADD_TODO" pattern. I'm going to have to find a way to emphasize in these docs that "this is how it works underneath, but this isn't how we recommend using it - use RTK instead".

Similarly, the purpose of this tutorial is to show the mechanics and how you would write this code "by hand", so that you later understand what RTK's abstractions do for you. In fact, I think the best way to finish this tutorial would be to migrate all the code we write over to RTK to show how much nicer it is.

@markerikson
Copy link
Contributor Author

markerikson commented Sep 19, 2020

Basics Tutorial Rewrite Plans

Initial Thoughts

Here's my initial thoughts on how to tackle this:

  • A mostly clean-slate rewrite, but possibly cherry-picking some bits from the existing content if they still make sense
  • Start with the same concepts overview as the "Essentials" tutorial?
  • Walk through the counter-vanilla example, but with an object instead of a single number
  • Build up a todo app, but keep expanding it over the course of the explanation
    • drop the Reddit example app entirely?
    • Lots of Codesandboxes, everywhere. Probably also an example app repo.
    • Refactor the existing "TodoMVC" example as a starting point? (file/folder structure and conventions, etc)
    • Add an additional filtering option just so it's not only that one little "completed" enum? Maybe "tags" for the todos, so that it shows some nested data updates (ie, "show all completed todos with tags 'chores' or 'reading' ")
    • Probably not worth splitting it into four separate examples ("barebones", "basic", "standard", "real world") like I'd suggested before. The "Essentials" tutorial covers "Real World".
    • Drop the use of React Router. This doesn't belong in the tutorial itself, but rather under "Real World Usage".
  • Almost definitely drop the "Basic/Advancd" split
  • Naming: call it "Redux Basics"? "Redux Core"?

Outline

Part 1: Redux Overview

  • Copy-paste the first half of "Essentials" Part 1 (intro, "what is Redux")
  • Port Vuex "Getting Started" counter example to Redux.

Part 2: Redux Terms and Data Flow

  • Basically second half of "Essentials" material?
  • Replaces the old "Data Flow" page
    • Move this earlier in the sequence to clarify what the moving pieces are
  • Set up "Todo+" app (project description, repo, CodeSandbox)

Part 3: Actions and Reducers

  • Cleaned-up "Actions" content from existing "Actions" page
    • Drop "Action Creators" for now
  • Cleaned-up content from "Reducers" page
    • Talk about use of conditional logic in reducers
    • Need something on immutability and pure functions here
  • Emphasize that none of this requires the Redux library at all
  • Show writing this logic in "slice"-type files
  • Example code: the usual Todo app logic

Part 4: Store

  • Cleaned-up content from "Store" page
  • Add "mini-store" implementation sample and description
  • Add very short description of extending a store via enhancers and middleware
    • Focus is on syntax, not "how is this implemented"
  • Example code: shows store setup, dispatching actions, reading state
    • Show Redux DevTools extension setup here?

Part 5: UI

  • Short recap of subscribe -> getState -> update UI cycle
  • "Usage with React" content, entirely rewritten
    • Drop all "container/presentational" concepts
    • Teach React-Redux hooks as default
  • Example code: show usage of React-Redux hooks in Todo app components

Part 6: Async Logic and Data Flow

  • Explain use of middleware for side effects
  • Show implementation of redux-thunk and store setup
  • Cherry-pick concepts from old "Async Actions" and "Async Flow" pages, but rethought to match "Todo+" example app
    • Do we want to show something regarding normalization here if we're not doing the Reddit app any more?
    • We haven't introduced action creators yet - show writing a (dispatch, getState) => {} func inline and pass directly to dispatch, no dispatch(fetchData())
  • Example code: data fetching and loading state in app

Part 7: Standard Redux Patterns

  • Introduce action creators and selectors as tools for defining logic in one place (question can these be moved earlier?)
  • Show an example of normalization
  • Show an example of reading data by ID in components
  • Example code: make todo app handle multiple lists, with normalized state

Part 8: Modern Redux

  • Migrate app code to RTK and show how its abstractions map to everything we learned earlier, but the code is a lot simpler to write

Part 9: Next Steps

  • Point to "Essentials" tutorial and "Real World Usage" sections for further reading

@markerikson
Copy link
Contributor Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants