Skip to content

Commit 696c01d

Browse files
committed
Revamp parts 3, 4, and half of 5 based on review feedback
1 parent cec44b9 commit 696c01d

File tree

3 files changed

+348
-308
lines changed

3 files changed

+348
-308
lines changed

docs/tutorials/essentials/part-3-data-flow.md

+36-16
Original file line numberDiff line numberDiff line change
@@ -107,21 +107,37 @@ We'll start by adding a `src/app/store.ts` file and creating the store.
107107

108108
```ts title="src/app/store.ts"
109109
import { configureStore } from '@reduxjs/toolkit'
110+
import type { Action } from '@reduxjs/toolkit'
111+
112+
interface CounterState {
113+
value: number
114+
}
115+
116+
// An example slice reducer function that shows how a Redux reducer works inside.
117+
// We'll replace this soon with real app logic.
118+
function counterReducer(state: CounterState = { value: 0 }, action: Action) {
119+
switch (action.type) {
120+
// Handle actions here
121+
default: {
122+
return state
123+
}
124+
}
125+
}
110126

111127
// highlight-start
112128
export const store = configureStore({
113129
// Pass in the root reducer setup as the `reducer` argument
114130
reducer: {
115-
// An example slice reducer function that returns a fixed state value
116-
value: (state: number = 123) => state
131+
// Declare that `state.counter` will be updated by the `counterReducer` function
132+
counter: counterReducer
117133
}
118134
})
119135
// highlight-end
120136
```
121137

122138
**`configureStore` always requires a `reducer` option**. This should typically be an object containing the individual "slice reducers" for the different parts of the application. (If necessary, you can also create the root reducer function separately and pass that as the `reducer` argument.)
123139

124-
For this first step, we're passing in a mock slice reducer function for the `value` field, to show what the setup looks like. We'll replace this with a real slice reducer in just a minute.
140+
For this first step, we're passing in a mock slice reducer function for the `counter` slice, to show what the setup looks like. We'll replace this with a real slice reducer for the actual app we want to build in just a minute.
125141

126142
:::tip Setup with Next.js
127143

@@ -173,17 +189,21 @@ Now that we have a store, we can use the Redux DevTools extension to view the cu
173189

174190
If you open up your browser's DevTools view (such as by right-clicking anywhere in the page and choosing "Inspect"), you can click on the "Redux" tab. This will show the history of dispatched actions and the current state value:
175191

192+
**[TODO] Update screenshot**
193+
176194
![Redux DevTools: initial app state](/img/tutorials/essentials/devtools-initial.png)
177195

178196
The current state value should be an object that looks like this:
179197

180198
```ts
181199
{
182-
value: 123
200+
counter: {
201+
value: 123
202+
}
183203
}
184204
```
185205

186-
That shape was defined by the `reducer` option we passed into `configureStore`: an object, with a field named `value`, and the slice reducer for the `value` field returns a number as its state.
206+
That shape was defined by the `reducer` option we passed into `configureStore`: an object, with a field named `counter`, and the slice reducer for the `counter` field returns an object like `{value}` as its state.
187207

188208
### Exporting Store Types
189209

@@ -194,11 +214,11 @@ We need to export those types from the `store.ts` file. We'll define the types b
194214
```ts title="src/app/store.ts"
195215
import { configureStore } from '@reduxjs/toolkit'
196216

217+
// omit counter slice setup
218+
197219
export const store = configureStore({
198-
// Pass in the root reducer setup as the `reducer` argument
199220
reducer: {
200-
// An example slice reducer function that returns a fixed state value
201-
value: (state: number = 123) => state
221+
counter: counterReducer
202222
}
203223
})
204224

@@ -212,7 +232,7 @@ export type RootState = ReturnType<typeof store.getState>
212232
// highlight-end
213233
```
214234
215-
If you hover over the `RootState` type in your editor, you should see `type RootState = { value: number; }`. Since this type is automatically derived from the store definition, all the future changes to the `reducer` setup will automatically be reflected in the `RootState` type as well. This way we only need to define it once, and it will always be accurate.
235+
If you hover over the `RootState` type in your editor, you should see `type RootState = { counter: CounterState; }`. Since this type is automatically derived from the store definition, all the future changes to the `reducer` setup will automatically be reflected in the `RootState` type as well. This way we only need to define it once, and it will always be accurate.
216236
217237
### Exporting Typed Hooks
218238
@@ -283,11 +303,14 @@ const postsSlice = createSlice({
283303
export default postsSlice.reducer
284304
```
285305

286-
Every time we create a new slice, we need to add its reducer function to our Redux store. We already have a Redux store being created, but right now it doesn't have any data inside. Open up `app/store.ts`, import the `postsReducer` function, and update the call to `configureStore` so that the `postsReducer` is being passed as a reducer field named `posts`:
306+
Every time we create a new slice, we need to add its reducer function to our Redux store. We already have a Redux store being created, but right now it doesn't have any data inside. Open up `app/store.ts`, import the `postsReducer` function, remove all of the `counter` code, and update the call to `configureStore` so that the `postsReducer` is being passed as a reducer field named `posts`:
287307

288308
```ts title="app/store.ts"
289309
import { configureStore } from '@reduxjs/toolkit'
290310

311+
// highlight-next-line
312+
// Removed the `counterReducer` function, `CounterState` type, and `Action` import
313+
291314
// highlight-next-line
292315
import postsReducer from '@/features/posts/postsSlice'
293316

@@ -307,7 +330,7 @@ We can confirm that this works by opening the Redux DevTools Extension and looki
307330

308331
### Showing the Posts List
309332

310-
Now that we have some posts data in our store, we can create a React component that shows the list of posts. All of the code related to our feed posts feature should go in the `posts` folder, so go ahead and create a new file named `PostsList.tsx` in there.
333+
Now that we have some posts data in our store, we can create a React component that shows the list of posts. All of the code related to our feed posts feature should go in the `posts` folder, so go ahead and create a new file named `PostsList.tsx` in there. (Note that since this is a React component written in TypeScript and using JSX syntax, it needs a `.tsx` file extension for TypeScript to compile it properly)
311334

312335
If we're going to render a list of posts, we need to get the data from somewhere. React components can read data from the Redux store using the `useSelector` hook from the React-Redux library. The "selector functions" that you write will be called with the entire Redux `state` object as a parameter, and should return the specific data that this component needs from the store.
313336

@@ -647,11 +670,8 @@ Let's recap what you've learned in this section:
647670
Here's what the app looks like so far:
648671

649672
<iframe
650-
class="codesandbox"
651-
src="https://codesandbox.io/embed/github/reduxjs/redux-essentials-example-app/tree/checkpoint-1-postAdded/?codemirror=1&fontsize=14&hidenavigation=1&theme=dark&runonclick=1"
652-
title="redux-quick-start-example-app"
653-
allow="geolocation; microphone; camera; midi; vr; accelerometer; gyroscope; payment; ambient-light-sensor; encrypted-media; usb"
654-
sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"
673+
class="codesandbox"
674+
src="https://stackblitz.com/github/reduxjs/redux-essentials-example-app/tree/ts-checkpoint-1/?ctl=1&embed=1&file=src%2Ffeatures%2Fposts%2FpostsSlice.ts&terminalHeight=0"
655675
></iframe>
656676
657677
## What's Next?

0 commit comments

Comments
 (0)