From 681f098e78e385d396356b375592e41b828ad664 Mon Sep 17 00:00:00 2001 From: Elizabeth Craig Date: Mon, 4 Mar 2019 18:37:43 -0800 Subject: [PATCH] Day 2 step 5 updates (#83) --- step2-05/demo/README.md | 58 ++++++++++++++++++------------------- step2-05/exercise/README.md | 6 ++-- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/step2-05/demo/README.md b/step2-05/demo/README.md index a53cdc5..f2cbf96 100644 --- a/step2-05/demo/README.md +++ b/step2-05/demo/README.md @@ -2,74 +2,74 @@ [Lessons](../) | [Exercise](./exercise/) | [Demo](./demo/) -In this step, we will look at solving the problems of complex application (as mentioned in Step 4) with a library called Redux. +In this step, we will look at solving the problems of complex applications (as mentioned in Step 4) with a library called [Redux](https://redux.js.org). 1. Introduction to Redux -2. Why Use Redux? +2. Why use Redux? 3. Creating the Redux store 4. Writing reducers 5. Dispatching actions ---- - ## Introduction to Redux -As a reminder, the problem that we want to address are: +As a reminder, the problems that we want to address are: -1. Data needs to be passed down from component to component via props. Even when some components do not need to know about some data. -2. Shared data can be changed by various actors (user interaction, updates from server), and there is no coordination of these changes +1. Data needs to be passed down from component to component via props, even when some intermediate components don't use all of the data. +2. Shared data can be changed by various actors (user interaction, updates from server), and there is no coordination of these changes. Redux is an implementation of the Flux architectural pattern: -![Flux Diagram](../assets/flux.png) +![Flux Diagram](../../assets/flux.png) ### View A view is a React component that consumes the store as its data. -### Action +### Actions -[Actions](https://redux.js.org/basics/actions) are serializable JSON messages that represent some event, such as a user's action or a network request. With the aid of _reducers_, they affect the overall state. At the minimum, it should contain a `type` key. Sometimes it contains additional data as a _payload_. +[Actions](https://redux.js.org/basics/actions) are serializable JSON messages that represent some event, such as a user's action or a network request. With the aid of **reducers**, they affect the overall state. At minimum, an action should contain a `type` key. Sometimes it contains additional data as a **payload**. ### Store The [store](https://redux.js.org/basics/store) consists of a **state tree**, a **dispatcher**, and **reducers**. -1. The **state tree** is a _singleton_, _serializable_, _immutable_ nested json data. It is updated from one snapshot to another through `reducers`. +1. The **state tree** is a _singleton_, _serializable_, _immutable_ nested JSON structure. It is updated from one snapshot to another using reducers. -2. The **dispatcher** accepts actions passing them to the reducers. +2. The [**dispatcher**](https://redux.js.org/basics/data-flow) accepts actions, passing them to the reducers. -3. **Reducers** are functions that take in the current state tree and an action, producing the next snapshot of the state tree. This is the only way to update the state tree. +3. [**Reducers**](https://redux.js.org/basics/reducers) are functions that take in the current state tree and an action, producing the next snapshot of the state tree. This is the only way to update the state tree. -## Why Use Redux? +## Why use Redux? There are lots of alternatives available, but here are some really good reasons to go with Redux: 1. For more complex applications, Flux pattern forces code to be written in a way that is easy to reason about -2. There maybe a need to serialize the application state to be transmitted across the wire somehow +2. There may be a need to serialize the application state to be transmitted across the network somehow 3. Dev tooling is really amazing 4. Popularity of the framework means the ecosystem is mature at this point -# Creating the Redux store +## Using Redux -The [`createStore()`](https://redux.js.org/api/createstore) function is provided by Redux to create a store. In general, an application would just have one single store. It takes in the reducer and an initial snapshot of the state tree. +### Creating the Redux store + +The [`createStore()`](https://redux.js.org/api/createstore) function is provided by Redux to create a store. In general, an application has a single store. The function typically takes in the main reducer and an initial snapshot of the state tree. ```ts const store = createStore(reducer, initialState); ``` -# Writing Reducers +### Writing reducers -We will write our reducers with the help of some utilities from the official `redux-starter-kit`. Here is how we will write our reducers: +We'll write our reducers with the help of some utilities from the official [`redux-starter-kit`](https://redux-starter-kit.js.org/), which greatly decreases the amount of boilerplate needed. The process for designing and implementing reducers is as follows: -## 1. Organize reducers according to the keys of the state tree object: +#### 1. Organize reducers according to the keys of the state tree object ```ts import { createReducer } from 'redux-starter-kit'; +// first argument: initial state +// second argument: object whose keys correspond to possible values of action.type const todosReducer = createReducer({}, { - // first argument is the initial state - // second argument is an object where the keys corresponds to the "action.type" addTodo: (state, action) => ... }); @@ -80,19 +80,19 @@ const filterReducer = createReducer('all', { const reducer = combineReducer({ todos: todosReducer, filter: filterReducer -}) +}); ``` -## 2. Write the reducers with mutables. +#### 2. Write the reducers with mutables -`createReducer()` will automatically translate all the mutations to the state into immutable snapshots (!!!!!): +In plain Redux, reducers must make a copy of the state before making modifications, but `createReducer()` will automatically translate all the mutations to the state into immutable snapshots (!!!!!): ```ts +// first argument: initial state +// second argument: object whose keys correspond to possible values of action.type const todosReducer = createReducer( {}, { - // first argument is the initial state - // second argument is an object where the keys corresponds to the "action.type" addTodo: (state, action) => { state[action.id] = { label: action.label, completed: false }; } @@ -100,9 +100,9 @@ const todosReducer = createReducer( ); ``` -# Dispatching Actions +### Dispatching actions -Dispatching action will pass the action and the current state to the _reducers_. The root _reducer_ will produce a new snapshot for the entire state tree. We can inspect the affected snapshot with the help of `getState()`. +Dispatching an action will pass the action and the current state to the reducers. The root reducer will produce a new snapshot of the entire state tree. We can inspect the affected snapshot with the help of `getState()`. ```ts const store = createStore(reducer, initialState); diff --git a/step2-05/exercise/README.md b/step2-05/exercise/README.md index 52c9eb2..77db0e2 100644 --- a/step2-05/exercise/README.md +++ b/step2-05/exercise/README.md @@ -4,7 +4,7 @@ If you don't already have the app running, start it by running `npm start` from the root of the `frontend-bootcamp` folder. Click the "exercise" link under day 2 step 5 to see results. -1. First, take a look at the store interface in `exercise/src/store/index.ts`. Note that the `Store` interface has two keys: `todos` and `filter`. We'll concentrate on `todos`, which is an object where the keys are string IDs and the values are of a `TodoItem` type. +1. First, take a look at the store interface in `exercise/src/store/index.ts`. Note that the `Store` interface has two keys: `todos` and `filter`. We'll concentrate on `todos`, which is an object where the keys are string IDs and the values are of type `TodoItem`. 2. Open `exercise/src/reducers/index.ts` and fill in the missing case statements for the switch on `action.type`. @@ -12,6 +12,6 @@ If you don't already have the app running, start it by running `npm start` from 4. Take a look what is written in the console (F12 on PC, cmd-option-I on Mac). -5. Install the [Chrome](https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd) or [Firefox](https://addons.mozilla.org/en-US/firefox/addon/reduxdevtools/) extensions +5. Install the Redux DevTools [Chrome](https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd) or [Firefox](https://addons.mozilla.org/en-US/firefox/addon/reduxdevtools/) extensions -6. Observe the state changes, try doing "time travel" +6. Observe the state changes and try doing "time travel"