-
-
Notifications
You must be signed in to change notification settings - Fork 15.3k
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] Create the "Quick Start" page #3675
Conversation
Deploy preview for redux-docs ready! Built with commit 6428359 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good overall! Think this'll really help, and I'll try to review again as progress is made
|
||
**TODO** figure out what else to put here, or if this should be dropped | ||
|
||
</Note> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally I don't think this section is needed in a quick start, since it's specifically for getting something quickly rather than overviewing the whole API, which I think the rest of the docs introduce well enough
docs/introduction/QuickStart.mdx
Outdated
```diff | ||
import React from "react"; | ||
import ReactDOM from "react-dom"; | ||
+import {configureStore} from "@reduxjs/toolkit"; |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
|
||
const rootElement = document.getElementById("root"); | ||
ReactDOM.render(<App />, rootElement); | ||
``` |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My intent is to have the first step simply be () => "Hello Redux"
+ const helloText = useSelector(state => state)
, and get that to show up on screen instead of the initial text in <App>
. That gives them some immediate success in seeing something visible change on the page. Then, once they've seen the initial connection sequence, we can move on to filling out actual app logic.
Co-Authored-By: Nick McCurdy <nick@nickmccurdy.com>
Finished the "Setup and Installation" part of the page. I'm feeling very split on the content so far. I think what I've got here is decent, but at the same time I'm worried it's too low-level / introductory, and taking too long to get to anything "useful" and "real". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking great so far 😄
- Basic familiarity with HTML & CSS, and the DOM. | ||
- Basic knowledge of JavaScript and programming. | ||
- Familiarity with ES6 syntax and features. | ||
- Basic knowledge of React, including components, props, and state. | ||
- Node.js and `npm` installed globally. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we link to external resources here? In case the end user doesn't know these pre-reqs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, I'm just trying to get a list in place for now.
It's _possible_ that we could move the store into a separate file, import that store into the `App.js` file, and call `store.getState()`. But, as the | ||
app gets bigger, we'd have to import the store into _every_ file. That's not a good idea. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure how useful this information is to a beginner? Just comes off as more information than needed IMO
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mmm... yes and no. My thought was to justify why React-Redux's API is needed at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess I'm just worried about this "Quick Start" page having more content than it needs, since in my mind the goal of this page is to provide as minimal information as possibly needed to get started with Redux + React.
If you feel like this content fits that goal then we should definitely keep it 😃
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've seen a lot of beginners try to use vanilla Redux in React apps and they get very confused with how to handle the store. I agree with Mark here that it's important for us to explain why React Redux is helpful right away.
Of course, if we have a guide for non-React users in the future, this wouldn't be necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this stays, it'd be good to explain why "That's not a good idea." - it will get messy? hard to manage? but there's an easier way?
The last step for the initial setup is to update our `<App>` component to read the state value from the Redux store. | ||
|
||
We've already seen that the React-Redux `<Provider>` component makes the store available to any components inside. To go along with that, React-Redux | ||
includes a React hook called `useSelector`, which React function components can call to retrieve the state values from the store. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should link to the React hooks API docs here. Might also be worth mentioning that React hooks is a pre-req for this page, since the end user could be new to the React hooks API as well.
@@ -2,6 +2,7 @@ module.exports = { | |||
docs: { | |||
Introduction: [ | |||
'introduction/getting-started', | |||
'introduction/quick-start', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The placement of this page is a bit awkward. Are we assuming that the end users are going to directly navigate to the "Quick Start" page rather than reading the "Getting Started" page first? Since both of these pages start out with the same information, and have a lot of duplicate information.
Also a bit strange that we go over installation in this page, but then the next page the user might navigate to is the "Installation" page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, agree that there's overlap, and that needs to be sorted out. For now, my focus is on the actual content of this page.
"@docusaurus/core": "2.0.0-alpha.40", | ||
"@docusaurus/preset-classic": "2.0.0-alpha.40", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Outta curiosity, is there a specific reason that these are getting version bumps in this PR? Might be better to branch out these version bumps to a separate PR.
I think you should get the users to have some simple working code and get them interested/excited about it before going into a bunch of explanations and prerequisites and stuff. 1. Create a Create React App app:npx create-react-app redux-counter-example 2. Install
|
@DylanVann In general, I agree - less is more. However, instead of "paste the all this code into index.js", I think it would be better to break it into chunks. We'll be creating a simple counter application. First, make import React from "react"
import { render } from "react-dom"
import {
Provider
useSelector,
useDispatch,
createAction as createEvent,
configureStore as createStore,
createReducer,
} from "@reduxjs/toolkit-react" Next, create two events - one for incrementing, one for decrementing. const onIncrementClicked = createEvent("incrementClicked")
const onDecrementClicked = createEvent("decrementClicked") Then we'll create a reducer. const counterReducer = createReducer(0, builder =>
builder
.addCase(onIncrementClicked, state => state + 1)
.addCase(onDecrementClicked, state => state - 1),
) ...etc. Then at the very end, have the full |
|
||
#### Key Concept: "Reducers" | ||
|
||
A **_reducer_** is a function that know how to calculate a new state value when asked. A Redux store requires a single reducer function |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A **_reducer_** is a function that know how to calculate a new state value when asked. A Redux store requires a single reducer function | |
A **_reducer_** is a function that knows how to calculate a new state value when asked. A Redux store requires a single reducer function |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"A reducer is a function that calculates a new state value."
|
||
- Reducers must always return a state value, never `undefined` | ||
- Reducers can only decide what the next state value should be by looking at the `state` and `action` arguments | ||
- Reducers are not allowed to make changes to the `state` argument, or anything else. They can only create the new state value by making copies of the originals, and updating the copies. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might be confusing to Redux Toolkit users (and we recommend it to beginners), as mutations are supported via Immer and are recommended in the docs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah this is a good point. Later on, it would be good to show "here's the hard way (ignoring that immer is installed)" and "here's the easy way because of immer".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, this is still my number one concern with trying to explain use of RTK in general, and especially in this page.
It's _possible_ that we could move the store into a separate file, import that store into the `App.js` file, and call `store.getState()`. But, as the | ||
app gets bigger, we'd have to import the store into _every_ file. That's not a good idea. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've seen a lot of beginners try to use vanilla Redux in React apps and they get very confused with how to handle the store. I agree with Mark here that it's important for us to explain why React Redux is helpful right away.
Of course, if we have a guide for non-React users in the future, this wouldn't be necessary.
``` | ||
|
||
We import the `useSelector` function from React-Redux, and then create a function called `selectHelloText`. It receives whatever state is in the Redux | ||
store as an argument. For now, we'll just return that entire state value. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've seen beginners frequently return the entire state when they don't need to in mapStateToProps
, causing unnecessary rerenders and defeating the purpose of this API. I understand that there's just one value in the store in this case, but I think we should at least note that only the state the component needs should be returned, as Redux optimizes rerenders based on the result. Also would help to mention that selectors getting the same data should be extracted into functions so they can be shared across components or even other selectors.
Sorry I fucked up that last review, those comments are supposed to be part of my suggested changes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left a few comments on the quick start page. I think at a high level, it might be better to show a working React example and "refactor it" to use Redux & RTK. I think it'd be more useful if the React app had at least a small bit of state that could be extracted out into Redux.
And since this is a Quick Start, maybe just show the full working React + Redux example right up top, ready to copy-paste, and leave the explanation for afterward.
|
||
It helps you write applications that behave consistently and can run in different environments (client, server, and native). | ||
It also helps you to write code that is testable, and enables you to better understand when, where, why, and how the data in your | ||
application has changed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know the "predictable state container" is the official descriptor but to a newcomer I don't think it means much. I think I'd jump right to the big why:
Redux helps you to write code that is testable, and helps you to understand when, where, why, and how the data in your application has changed.
|
||
### How does Redux work with a UI? | ||
|
||
Redux, by itself, is a plain JavaScript library. You can use Redux together with React, or with any other UI view library. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get the impression that the vast majority of people use Redux with React, and the second sentence makes it clear that it works with other libraries. I'd make the title "How does Redux work with React?" to align with most people's expectations and make it feel like they're in the right place.
|
||
Redux, by itself, is a plain JavaScript library. You can use Redux together with React, or with any other UI view library. | ||
|
||
To help make this possible, there are additional bindings libraries that connect together a Redux store and your UI components. Each different |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This "To help make this possible..." sentence could be cut - this guide isn't going to cover other bindings libraries (I think?). The next sentence makes it clear enough imo.
[CodeSandbox.io](https://codesandbox.io) is an online IDE that lets you create entire web applications in your browser, without needing to | ||
install anything locally. | ||
|
||
Create a new React project sandbox by browsing to the [CodeSandbox "Create Sandbox" page](https://codesandbox.io/s/) and selecting the official React template. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Link directly to https://codesandbox.io/s/new for a new React app so we can skip the "browsing" instructions.
|
||
Create a new React project sandbox by browsing to the [CodeSandbox "Create Sandbox" page](https://codesandbox.io/s/) and selecting the official React template. | ||
|
||
Once the sandbox has been created, click the "Add Dependency" button on the left, search for `@reduxjs/toolkit`, add it, and then do the same for `react-redux`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could add a screenshot/GIF here?
#### Key Concept: "Reducers" | ||
|
||
A **_reducer_** is a function that know how to calculate a new state value when asked. A Redux store requires a single reducer function | ||
when it is created, which we call the "root reducer" to say that it is the starting point for any other reducer functions inside. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe skip talking about "root reducers" until later. Get one working first before revealing that there can be a tree of them.
A **_reducer_** is a function that know how to calculate a new state value when asked. A Redux store requires a single reducer function | ||
when it is created, which we call the "root reducer" to say that it is the starting point for any other reducer functions inside. | ||
|
||
Every reducer is called with two arguments: the current `state`, and an object called an **`action`**. We'll look at actions a bit later. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mention here that the reducer "returns the new computed state".
Could also add a few words to describe actions so it's not gnawing at them - "...an object called an action that describes how to update the state"
|
||
- Reducers must always return a state value, never `undefined` | ||
- Reducers can only decide what the next state value should be by looking at the `state` and `action` arguments | ||
- Reducers are not allowed to make changes to the `state` argument, or anything else. They can only create the new state value by making copies of the originals, and updating the copies. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah this is a good point. Later on, it would be good to show "here's the hard way (ignoring that immer is installed)" and "here's the easy way because of immer".
It's _possible_ that we could move the store into a separate file, import that store into the `App.js` file, and call `store.getState()`. But, as the | ||
app gets bigger, we'd have to import the store into _every_ file. That's not a good idea. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this stays, it'd be good to explain why "That's not a good idea." - it will get messy? hard to manage? but there's an easier way?
|
||
#### Key Concept: "Selectors" | ||
|
||
A **_selector_** is a function that takes the Redux store state as an argument, and returns some part of that store state. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It quite literally "selects" a portion of the state.
Haven't given up on this, but I decided I ought to take a step back and take notes on several excellent React+Redux tutorials (and some totally non-Redux-related tutorials) to get a feel for how they handle explanations first. Then I'll try to take some inspiration from those and take another stab at this. |
Should have closed this a while ago. |
PR Type
Does this PR add a new page, or update an existing page?
Adds the new "Quick Start" page
Checklist
What docs page is being added or updated?
For Adding New Content
What kind of content category is this page (tutorial, how-to, explanation, reference)?
The "Quick Start" page is a form of tutorial, but intended to demonstrate the "fastest" / "easiest" / "correct" way to use Redux without explaining why things work this way.
Who is the intended target audience?
Beginners who know nothing about Redux, yet.
What knowledge are we assuming they have?
async/await
, object spreadsfetch
What are the intended results or takeaways from reading this page?
Readers should be able to mimic the demonstrated patterns to create a basic React+Redux app that does some CRUD work.
What is the most critical info they should learn?
configureStore
,createSlice
,useSelector
/useDispatch
)Status
Hacked together this initial skeleton of a page. So far I've done:
<Note>
(including multiple styles based on the Cypress.io docs) and<DetailedExplanation>
I got stuck with some yak shaving when I realized that using the
diff
highlighting format leaves the+-
diff signs as copyable characters, and ideally I'd like them not copied or selectable. I tried playing withuser-select: none
and the:first-letter
selector, but it's not quite doing what I want.Putting this up for ongoing feedback as we work through this.
/cc @taniarascia , @bpas247