Redux Flashcards

1
Q

What will we learn?

A

everything we need to know to build real, complex apps with Redux

work on a real bug tracking app with a node backend

by end of course, know and understand Redux inside/out

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

What is Redux?

A

A state management library for Javascript applications

doesn’t care what library we use for UI development

instead of scattering app state across UI

store state in a single JS object (store)

single source of truth

like a “database” for front end

components get state from store

data is updated in a single place

can see how data changed, why, when and where it came from

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Why do we need redux (state managment)?

A

complex UI, need to keep in sync

data updates from backend request, user interaction, etc. changes must be reflected immediately

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

What are the pro’s of Redux?

A

debugging

transparent state changes

can reload state, view actions and see UI changes

cache/preserve page state

entire app state available on client in JS object (store)

don’t have to reload data from server

centralized state

data is available in one place, accessible by all parts of UI

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

When is redux NOT right for my project?

A

must consider constraints and problem domain

A real software engineer is an active problem solver

not every application requires Redux

DON’T USE

if load data and display statically (not changing)

if it’s a tight budget

if the UI is very simple

**it will be complex and slow you downl

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

What is functional programming?

A

Redux is built on top of functional programming

A good background is critical to building redux apps

One of the programming paradigms

Each paradigm has rules for how to structure code to solve problems

invented in 1950s

decomposing a problem into small, re-usable functions

can compose functions to build complex pipelines

Pros

can run in parrallel

exploit multiple cores

Benefits:

more concise

easier to debug

easier to test

more scalable

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Why are functions first class citizens in Javascript?

A

can treat them like any other variables

assign them as variables

pass them as arguments

return them from other functions

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

What are higher order functions?

A

a function that…

takes a function as an argument

returns a function

both!

Why?

instead of working on strings, numbers or booleans

it goes higher to operates on functions

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

What is the problem with this approach?

A

expression is read right to left

trim, make lowercase, wrap in div

so many parenthesis

Soln?

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

What is currying?

A

Solves this problem:

functional pipeline

function in line requires two parameters (fns)

only have one fn as parameter

How?

allows us to take a fn with N arguments

convert it to an fn with 1 argument

What?

instead of separating args with commas “,”

separate with ( )

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

What is the challenge with this code?

A

wrap function expects two arguments

if we pass type as argument

pipeline will throw an error

Why?

it requires a function as argument, not string

Soln?

currying

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

What are pure functions?

A

a function that given the same args, produces the same result

NOT:

random values

current date/time

global state

Why?

These change

Redux?

reducers must be pure

other fns don’t have to be

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

What are the benefits of pure functions?

A

Self documenting

everything a fn needs is clearly identified in parameter signature

easier to test

no global state

concurrency

because not using global state

can run in parallel

cacheable

can store result in cache and use in future

useful in programs with intensive computations

if we know certain computations produce same results

can optimize by storing in a cache

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

What is immutability?

A

Goes hand in hand with pure functions

once we create an object, cannot be changed

must take a copy and change that copy

Ex. Strings are immutable, create copy, original string not affected

Objects and arrays can be modified directly, not immutable

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Does “const” prevent mutability?

A

No

it prevents re-assignment

common misconception

Ex. cannot re-assign book to another object

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

What are the benefits of immutability?

A

Predicatable apps

if we call a fn, pass an obj

obj won’t get changed, no suprises down road

Fast change detection

React needs to know when changed

creating a new obj, stored in memory

React compares objects by references

this is fast operation

in contrast, without immutability

React has to compare all properties in two objects to see it’s changed

slow operation

Concurrency

can run in parallel

not going to affect something that affects system as a whole

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

What is the problem with this code?

A

Spread operator does a shallow copy

nested objects are copied by reference (not value)

Ex. Both person2 and person2copy have the same reference to “address” in memory (not copied by value) copied by reference

Soln?

Do a deep copy

set a new nested object using spread operator

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q

How do we copy an array and insert a number at a specific location?

A
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
19
Q

How do we update an array using immutability?

Hint:.map ( ) method

A
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
20
Q

How do we enforce immutability?

A

By default, Javascript doesn’t do this

Why?

It’s a multi paradigm language

it doesn’t enforce immutability without libraries

Soln?

Libraries that enforce real immutability

Different people love different tools

Immutable.js (by Facebook)

Immer (becoming trendy, Mosh loves it)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
21
Q

What is immutable.js?

Hint: npm i immutable

A

a library by Facebook

provides a bunch of immutable data structures

*Mosh prefer’s another library

How?

instead of a plan JS object

use one of the datastructures from this library

Problems?

have to learn a new API

cannot access obj properties with . or [] notation

have to use .get( ) method

integration with other libraries

hard to integrate with other libraries that expect plain JS objects

have to call .toJS( ) method to convert to plain JS objects

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
22
Q

What is Immer?

Hint: Immutability library (npm i immer)

A

almost as popular as immutable.js

Pros

writing code as if mutating objects but actually not

better than using spread operator (get’s nasty with nested objs)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
23
Q

Write code to solve this?

Hint: function composition

A
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
24
Q

What are the three building blocks in Redux applications?

A

Store

single JS Object that includes application state

Actions

plain JS Objects that represent what happened

aka events (what happened)

Reducers

one or more functions responsible for updating a slice of Store (single JS object)

aka event handlers or processors

pure functions, don’t mutate arguments, no side effects

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
25
**How** do **Redux building blocks** work **together**?
**Action object** is **dispatched to Store** **Store** calles the **Reducer** **Ex.** When **user performs an action** (add item to shopping cart) Create an **Action item** and **dispatch it** **Store object** has **dispatch method** that **takes an action** **Store object** forwards **action to reducer** **Reducer** is **not called directly**, we **only work with the Store** **Store is in charge of calling the reducer** **Reducer computes new state and returns it to Store** **Store sets state internally and notifies UI components directly**
26
Write **code to solve this?** **Hint:** immutabile objects / arrays
27
**What** is a **store?**
**simple API interface** **JS Object** includes **properties:** **.dispatch** method for **dispatching actions** **.subscribe** method for **subscribing to store** **get notified** everytime state of **store changes** used by **UI layer** **.getState** get current **state of store** to **change state of store**, have to **dispatch an action** **Store object** has **dispatch method** that **takes an action** **Store object** forwards **action to reducer** **Reducer** is **not called directly,** we **only work with the Store** **Store** is in **charge of calling the reducer** **Reducer** computes **new state** and **returns it to Store** **Store** sets **state internally** and **notifies UI** components **directly**
28
**What** is a **reducer?**
**A function** that **takes current instance of the store** (JS state object) and **returns an updated store** **Returns**? using **spread operator** or **immutable library to return an updated store** **How?** **supply store and an action as arguments** **action is a plain JS object describing what just happened** **lets reducer know what to update in store (JS state object)** **Many?** **each reducer** is **responsible** for **updating a specific part** of **the store** **Ex. Many departments in a store, each department has a manager**
29
**What** is **an action?**
**argument** to the **reducer function** tells **reducer** what **properties in store to update** **actions that happen in our applications (events)** **Ex. UserLogin, UserLogout** **based on the type of action, reduce will know what parts of store (state) to update**
30
**Why** is **redux designed this way (ie. to dispatch actions)?**
**Dispatch** is like **entry point to store (JS state object)** **every action** is **sent** through **same entry point** **central place** to **control** what **should happen** every time a **user performs an action** **can log every action** **can implement undue/redue mechanism**
31
**What** are the **four steps** to **follow** when **building a redux app?**
**Design the Store** What do you want keep in the store? **Define Actions** What are actions user can perform in application? **Create Reducers** Take an action, return updated state Setup Store based on Reducer
32
**How** would we **design the store** of a **real world application** for **tracking bugs?**
**An object** with **two properties (slices):** **bugs** - list of bugs **current user** - initially null, then set when user login \***two slices**, requires **two reducers**
33
What **actions** would a **user perform** in a **real bug tracking application**?
An **action** is just **a plain JS object** that **describes what happened** **must have a type property (required)** **Payload property contains minimum data including description or ID for an action** **description can be any serializeable data type** **because description must be able to store on disk, reload later** **use strings so we can view description of what happend** **can store form data in description, etc. (bug type, who logged, etc)** **ADD\_BUG** **bugAdded** **common conventions for type in Redux apps** **(vs. numberss not descriptive)** **Actions (events):** **Add a bug** Change status of bug filter list of bugs change sort order **Mark as resolved** **Delete a bug**
34
**How** do we **create a reducer?**
35
**What's** the **problem with this code**?
In **real app** **payload** contains **minimum required information** Ex. **bugAdded** -\> **only need ID**, not **description too** Use **immutable library** in **real app (not spread operator)**
36
**How** do we **implement this logic** using **switch and case**?
**Reducer** is a **pure function** **everything it needs is passed as arguments (only dependencies)** **given** the **same input,** returns **same output** **doesn't** touch **DOM elements** **doesn't work with global state** **No API calls**
37
**How** do we **create a store**? **Hint:** single **JS object** that **contains app state**
import **{createStore}** from **'redux';** import **reducer** from **'./reducer';**
38
**How** do we **create a store?**
39
**How** do we **dispatch an action?**
**In real app,** **when** **user clicks** **add button** **we** are **going to dispatch an action (raise an event)**
40
**How** do we **subscribe to the store?** **Hint:** get **current state** of **store** everytime **state changes**
**store.subscribe ( )** **takes a fn** **called everytime a change happens in the UI** **UI components** should **subscribe** to **store** so **they are notified** when **changes happen**
41
**What does** the **subscribe method return?**
**a fn** for **unsubscribing from store** possible **user navigates away** from **current page** in **new page**, don't **have UI component** **don't want** to be **subscribed to a UI component** that is **not visable** this can **create memory leaks**
42
**What** is the **redux workflow?** **Hint**: code example
**When we dispatch an action** store.dispatch( { action } ) **store calls reducer** state = reducer (state = [] , action) **store gives reducer current state in store and action passed to store** reducer returns a new state to store **based on logic / type of action (switch case)** **notifies subscribers of changed state**
43
**What's** the **problem with this code?**
we **hard coded** the **action type (string)** if we **change the action type** name later will **have to change in multiple places** or **get a bug** **Soln?** **create a file actionTypes.js**
44
**What's** the **problem with this implementation?**
**dispatching** an **action is not easy** **have** to **type the entire structure** **if re-using action in multiple places, will duplicate code** **Soln?** Create a fn that creates action object
45
**How** do we **implement BUG\_RESOLVED**?
**Create the action first** plan JS object w/ type + payload store.dispatch ( action ) **Create the reducer next** returns an updated state object to store **store.subscribe ( observer )** notifies **observers of state change** **Pass action to store** store.dispatch ( action )
46
**What** is a **good idea** when **learning a new tool**?
Think about **how that tool works** and **how it was built** **Mosh** is going to **show us how Redux works / is built!** **We are going to build Redux from scratch**
47
**How** do we **build the store from scratch?**
**state property** is a **private property**
48
**How** do **we create** a **private property?**
49
**How** do we **implement the dispatch method** in our **custom store?**
**Call the reducer** to **get the new state** **Notify** the **subscribers**
50
**How** do we **implement the subscribe method** from **scratch**?
51
**How** do we use **Redux Dev Tools?** **Hint:** A **powerful tool** for **debugging redux applications**
**We need to pass extension to createStore ( ) method** **Add:** window.\_\_REDUX\_DEVTOOLS\_EXTENSION\_\_ && window.\_\_REDUX\_DEVTOOLS\_EXTENSION\_\_() **A powerful tool for debugging redux applications**
52
**What** is the **log monitor?** **Hint**: Redux Dev Tools
**a plain list of actions** that **have been applied** **Action + state** after **action applied**
53
**What** is the **Chart field?** **Hint:** Redux Dev tools
**show actions** in a **visual way** Ex. **DollarShaveClub's React/Redux** Actions Chart
54
**What** is the **inspector field?** **Hint:** Redux Dev tools
**diff shows** you **how tab has changed**
55
**How** can I **identify the source of problem** in **my Redux app?**
using **Redux Dev Tools**: **1. Look at _actions dispatch_ -** ensure **right action was dispatched, if not _dispatch that action_** 2. **Check** to _**ensure action** was_ **_carrying the right data_, if not _modify action creator_ (responsible for action)** **3. Check state tab - ensure state was updated properly, if not _modify reducer function_ (responsible for state)**
56
**What** is the **test tab?** **Hint:** Redux Dev Tools
**Generates** **basic boiler plate** for **testing action**
57
**How** do we **enable tracing** in **redux dev tools?** **Hint:** $ npm i redux-devtools-extension
Where in **source code** a **given action was dispatched** import in store module replace window.\_REDUX\_DEVTOOLS\_EXTENSION with **devToolsEnhancer()** **call this function, get a function returned** **returns** a **storeEnhancer function**
58
**How** do we **configure Redux Dev tools** tracing **function?**
**maps line of code in bundle and source code** **add devtool: "source-map" to webpack.config.js** **app.js.map** **settings -\> code editor -\> vsCode -\> pwd (working directory path)** **/Users/kingarsalon/Desktop/GitHub/redux/Source Code/redux-starter**
59
**What** is **exporting the store?**
**Very powerful** feature of **redux** Can **store all interactions of user** with **our application** in a **single JSON file** then, reload the state from that JSON file later **Why?** **Easy debugging** **don't have** to **launch application** and **follow all steps leading to a bug** **can** simply **reload app** in **same state as user** **look** at **all actions** **look** at **state updates** **Log Rocket** does this for every user in production **download** from **Redux Dev Tools** **upload** into **Redux Dev Tools**
60
**What** is **one** of the **complaints about Redux**?
**It makes** you **write so much boiler plate code** So... Mosh is going to show us How to **write clean, concise redux code**
61
**How** do **we structure** our **redux code** in a **clean way?** **Hint**: completely **isolate from UI code**
**UI and state management** are **two different concerns** **Move all redux code into a separate folder** next, group all **files by feature** **(subdomain)** **each subdomain should contain it's own:** actions actionTypes reducers **Why?** could have **hundreds of actions** break **down into small subdomains** or **bounded contexts** **Ex. Auth domain** **all about authorization and authentication** **actions - login, logout, changePassword** **Ex. Bugs domain**
62
**What** is the **dux pattern?** Hint: re_dux_
**a bundle** of **actions, actionTypes and reducer** for **a specific domain** **Why?** instead of **having separate files:** **actionTypes.js, actions.js, reducer.js** **combining all** for **particular domain** into **one file** **makes** it **easier to edit, update** redux **domain** **any changes** to that **domain, go to one file**
63
**What** **rules must we follow** when **implementing the dux (redux)** **pattern?**
**reducer** **has** to be a **default export** in **the module** **action creators** **must export individual action creators**
64
**What** is the **Redux Toolkit?** **Hint:** npm i @reduxjs/toolkit
**Redux team** officially **recommends Redux Toolkit** to **simplify your code** **library provides a bunch of helper functions (utility functions) to simplify redux code**
65
**How** can we **refactor this code?**
**npm i @reduxjs/toolkit** **configureStore ( )** wraps **createStore ( )** fn and **development tools** **includes:** **reduxDevTools** we don't have to manually import this anymore **utility functions to help with calling APIs** **able** to dispatch **asynch actions (calling API)** **without this function**, will **have to apply middleware** to **dispatch async functions** for **calling APIs**
66
**How** do we **create actions with less boiler plate?** **Hint:** npm i @reduxjs/toolkit
**every action** creator **returns an object** **can** use **reduxtoolkit** to **simplify the code** **createAction( )** **returns an action creator** **import { createAction } from "@reduxjs/toolkit"**
67
**How** do we **refactor this code** using **Redux toolkit?** **Hint:** refactor **Action creators**
**createAction ( )** returns an **action creator** **call fn** and **pass payload** (see index.js)
68
**What** does the **createAction ( )** fn **return?** **Hint:** createActionCreator( )
**utility function** from react-dev-tools **createAction** ( ) returns **an action creator function** **should** be called **createActionCreator ( ) !** returns an **action creator function** pass args to create an action object
69
**How** can we **refactor** this **reducer** using **Redux toolkit?**
**don't have** to write **immutable updates to state** **can** replace **switch-case statements** **under the hood, uses immer** **code we write in reducer is automatically converted to immutable code!**
70
**What** is the **problem with this code?**
**The string** we are passing to the **actionCreator is hard coded** This **dependency breaks** the **reducer when calling createReducer** and **passing an action with a hardcoded name** that **was changed** **soln?** instead of **hardcoding the name** by **passing a string arugment** **can use []** to **dynamically compute** the **action name (property)** **action object contains a method that returns type property of the action**
71
**What** is the **create reducer method** take **as arguments?** **Hint:** redux toolkit **createReducer ( )**
**createReducer ( )** two **method arguments** **Arg #1** initial state, alias that matches slice of state to be changed **Arg #2** **{ pass an obj }** - that maps **key** = action names **value** = fns **event =\> eventHandler**
72
**What** is **Creating Slices?**
**Redux toolkit** createSlice( ) function creates an **action and a reducer together** cleaner, simplier code **createSlice ( ) method** takes a **configuration object** **with properties** : **name:** initialState: **reducers:** { action: actionHandler}
73
**How** do we **refactor this code?** ## Footnote **Hint: createSlice( ) redux toolkit**
use **CreateSlice ( ) method** **internally** the **reducer property** function **calls** **two functions** - **createAction ( ) , createReducer ( )**
74
What is the **createSlice ( ) method?**
Redux tool kit takes a configuration object pass action as key (event) **pass reducer as value (eventHandler)**
75
**How** do we use the **createSlice ( ) method** to write **clean, beautiful redux code?**
**don't have** to **explicitly create actions** and actionhandlers **createSlice ( )** creates both for us
76
What is a **slice?**
**Redux Toolkit** creates action using **createAction ( )** creates reducer using **createReducer ( )** allows us to **write mutable looking code** converts to **immer (immutable code)**
77
**Okay to have local state** in **our UI components** or **do we have to put all our state into redux store**?
Two **approaches to organizing data in redux apps**: 1. **Global Data Only** - in Redux store if multiple components use data, store in Redux store Ex. e**Commerce** - put **user and shopping cart** (global data) in redux store everything else in outside of store **Mosh is not a fan** because it doesn't allow us to **get all redux benefits** **Using redux** in **small part of application** no time **travel debugging** no **testable code** **no caching and persistence** **Don't use Redux in a small app with simple data flows** **Therefore...** if all we do is use **Redux to share global data**, it's a waste, **better to use Context Objects** to share **global data in React** 2. **Put everything in store** - single, unified way to access data, **comes at a cost** **Benefits:** more consistent more maintanable code store as a cache easier debugging using redux dev tools code becomes easier to test **Mosh favors this approach**
78
What are the **benefits of putting all the UI data in a redux store?** Hint: **Exception** - **form state data**
Don't store **form state data in Redux** Put **everything in store** single, **unified way to access data**, comes at a cost **Benefits:** more consistent more maintanable code store as a cache easier debugging using redux dev tools code becomes easier to test
79
Why is it **not a good approach** to **only store global data in Redux** and **other UI data locally?**
**Global Data Only -** in Redux store if multiple **components use data, store in Redux store** Ex. eCommerce - put **user and shopping cart (global data)** in **redux store** **everything else in outside of store** **Mosh is not a fan** because it doesn't allow us to get all redux benefits **Using redux in small part of application** no time travel debugging no testable code **no caching** and **persistence** **Don't use Redux for small data apps**
80
**Why should we not** store **form state in Redux store?** **Hint:** Store **form state locally** in **components**
Reasons: 1. **Temporary values in a form** have no impact on other UI **until user submits form** okay to **populate a form with data from store** don't want to **update the store as the user is typing** **no value** in **keeping temporary data in the store** **update store only when user submits** 2. Too many dispatches we shouldn't dispatch an action on every key stroke causes **performance issues** makes **debugging more challenging** Ex. 50 actions as user was typing full name **Soln?** Store form state locally in components
81
**What** is the **best way to structure our store?** ## Footnote **Hint: use an object**
**Use an object** each key **represents an ID** each value represents an object **Benefits:** Can quickly lookup object by ID (accessing property) this is a very fast operation very clean and fast lookup doesn't preserve order vs. using an array, first find index (slow operation, iteration)
82
**What** are the **Pros and Cons of structuring the Redux store using an objec**t?
**Pros** allow fast lookup (hashmap, key-value pairs) if you need **fast lookups, use an object** **Cons** doesn't preserve order cannot re-order properties in an object if you **need ordered data, use an array** **Or use a combination of two!** Ex. using an **object to store bugs**, **array to store bugID's**
83
**How should** we **structure our store**?
**each slice** represented **as an array** **wrap** **slices** in **a parent slice called (**nested) another **high level slice** for **user** (name, id , authtoken) another **high level slice called** UI (**state specific for components)**
84
**How c**an we **create a store** with **multiple slices (multiple reducers)**?
**combineReducers ( ) from redux** **combines our reducers** into a **single reducer** we can **pass to our store**
85
**What are we** doing **essentially by nesting slices under entities?**
**combining reducers** creating a **hierarchy of reducer functions** **root reducer passes action to entities** **entities reducer passes actions to children reducers** **Main Idea?** **multiple reducers** can **handle same action** each reducer is **responsible for updating only one property in the store** this **keeps each reducer in a single responsibility**
86
**What** does **normalization mean?**
We should **not duplicate data in our store** **remove nested data by replacing with identifiers** **connect related data using identifiers** aim to **keep data as flat as possible** **get rid of duplicates, using identifiers** **No nesting** **can look up object by objectID if neccesary** Ex. project **object in a few places of store** - update **name, have to update every instance of data** or will **have inconsistent data**
87
**What is the library normalizr?** **Hint**: npm i normalizr
If your **app talks to an API** **received de-normalized, hierarchical data from server** use **normlizr to normalize your data**
88
**How do we compute** **derived data** from **data in our store?**
**Write a query using method chaining after** **.getState( )** A **derived data element** is a **data element** derived from **other data elements** using a **mathematical, logical, or other type of transformation**, **e.g. arithmetic formula, composition, aggregation.**
89
**What** is the **problem with this approach**?
**In real application** **logic for computing derived data** can **be complex** logic may be in **a few different places** without a deriving class (selector) these **objects will break with changes** **Soln?** **Selector fn** **takes state, returns a computed state**
90
**What** are **selectors?** **Hint**: computed state functions (query state logic)
**functions t**hat **return computed data** take **state as an argument** **return a computed state** **Naming conventions:** **getUnresolvedBugs( ) \*** mosh's favorite, it's shorter unresolvedBugsSelector ( ) selectUnresolvedBugs ( ) **Benefits:** single place to modify function can re-use in multiple places in application
91
**What** is the **problem with this code?** ## Footnote **Hint: .filter ( ) method returns a new array** **$ npm i reselect**
**$ npm i reselect** **createSelector ( ) method returns a memoized selector (cacheable)** **selector won't execute logic if it's in cache** **will return value from cache** **.filter ( )** method **returns a new array** we **don't want state** to **re-render everytime we query the store** Soln? **Memoization** **memoize this function** a technique for **optimizing expensive functions** can **build a cache of input / output** before **executing expensive logic, look at cache** if **operation has previously been run, get data from cache**
92
**What** is **createSelector ( ) ?**
**from npm i reselect** a function that **creates a memoized selector** **Two arguments:** **selector** - get's state and passes it to **results function (query logic)** **results function** - selector passes state, logic is executed if value not in cache if value is in cache, results function will get data from cache
93
How do we **assign a bug to a user?**
94
**What** is **middleware in redux?**
a **curried function** with **three parameters** **store** =\> **next** =\> **action** an **advanced topic in Redux** **building block that allows** us **to do side effects** (like **calling APIs)** **How?** **add functions that are executed everytime an action is dispatched** **called middleware** **peice of code that is executed after it's dispatched, before reaching root reducer** **Why?** **Calling APIs** **Error Reporting** **Analytics** **Authorization**
95
**How** can we **parameterize a middleware function**?
96
**How can** we **change our .dispatch ( ) method** in our **store to accept functions?** **Hint:** allows us to make Async API calls
**By default** **store.dispatch ( ) takes an object** with **type property ONLY** will **give errors if we try passing a function** or **obj without type property** **Soln** create a **middleware function called func.js** **handles calling the function if store.dispatch ( ) is passed a fn** **allows us to make async API calls** **How?** **logic** - if **typeOf action** is function, **call function** **otherwise,** pass to **next middleware** or **reducer (if no more middleware)** **Why?** passing a function is used **call asynchronous APIs that return promises** **Redux Toolkit** **creates this middleware func (thunk) for us!** **Use redux toolkit**
97
What is the problem with this code?
In **index.js** have access to **store.dispatch ( )** in **other parts of our application** we **can not dispatch functions easily** if we **try to import the store** in **other parts of application, a new store is created** **How can we dispatch functions using the store in other parts of our application?** **Soln?** pass a **reference to the dispatch function** when **dispatching a function**
98
**Why do we** need to **call APIs in our redux applications?** **Hint: Getting or Saving Data** with **Backend**
Almost **every front end application needs** to **talk to a backend** for **getting or saving data** **Very important topic** Really **important principles** Change how you **think about software design**
99
Where **should we put code with side effects (API calls, global data, etc.)**? **Hint:** Action creators
In **action creators** **Why?** Reducers must be **pure functions** this **makes them easy to test** no API calls no DOM manipulation **How?** With T**hunk middleware** (dispatch functions) can **return a function from an action creator** **re-write actionCreator ( ) fn using =\> syntax** **with dispatch and getState can do more processing**
100
**How** can we **refactor this action creator**? **Hint:** use arrow fn syntax
**action creator** is a **fn with no parameters** **returns** a **function with (dispatch, getState) as parameters** **returns some logic** **this is currying in action**
101
**How** do we **call an API** using our **action creator?**
**Three things (basic pattern):** 1. **Call API** - axios, fetchApi, any library (async) returns a promise 2. **Dispatch success action** - promise resolves reducer catches and updates state **Resolved: dispatch (success)** 3. **Dispatch error action** - promise rejects **Rejected: dispatch (error)**
102
**What** are the **naming conventions** for **actions that return functions for calling APIs?** **Hint:** Past tense vs Present tense
**Present** GET\_BUGS\_REQUEST GET\_BUGS\_SUCCESS GET\_BUGS\_FAIL **Past tense** bugsRequested bugsRecieved bugsRequestFailed
103
**What's** the **problem with this pattern for calling APIs** using **actionCreators?**
Very repetative as we implement more features in App each time we call an API **have to follow three steps** write code for **calling, dispatching, error handling** chaining then and catch methods or **try catch blocks** **Soln?** **Middleware** **can implement this pattern in middleware**
104
**What** **kind of action object** should our **api middleware** be **able to handle?**
**serializable** passing strings vs functions
105
**What** are the **problems with this implementation**?
**hard coded** action type's one in **middleware** one in **action** **soln?** **create an actionCreator( )** Inconsistent naming better to have names match **Soln?** refactor action creators! access .type property in middleware fns
106
**How** can we **restructure our store**? **Hint:** [] vs { }
**restructure** from **array to object** data type **add properties :** **loading** display loading to user **lastFetch** used to determine cache integrity (up to datedness)
107
**Why** should we **not have these details** in **our UI layer?**
have to repeat this action creation in multiple UI places Ex. drop down, bugs page, etc. breaks with changes have to update multiple lines of code Soln? **store.dispatch(loadBugs() )** details of endpoint, action, etc. abstracted
108
**How** do we **design a feature** to **handling loading** while **app is getting data from server?**
When call server set loading to true in UI show/hide spinner **Steps:** **1. Define new action** bugsRequested in bugs slice automatically creates an action **2. Define new reducer** sets loading prop to true fn in slice **3. Change middleware** generat action based on property (onStart) by loadBugs ( ) to middleware dispatch new action before making an API call
109
**How** do we **handle the situation** in which **something goes wrong?**
**create a new action** and **reducer** that **set's the loading property** to **false if an error occurs**
110
**How** do we **solve this problem?** **Hint: npm i moment**
Don't want **server to call API second time in 2 seconds** ## Footnote **Soln?** **Caching** **re-write loadBugs action creator to return a fn that includes dispatching new action** **stamps currentTime** **moment ( ) library returns current date time** **can compare to current time if** **in real app, extract logic into re-usable component**
111
**How** do we **save data to the server?** **Hint:** Http Post request
**Soln?** **dispatch API call**, let **API middleware handle everything** **loadBugs ( )** is dispatching an **API action (bugs.js)** **addBug ( )** dispatches an **API action (bugs.js)** consume using **.dispatch ( API action)** Why? **Same steps as making an API call:** **Make an API call** **dispatch (success)** **dispatch (error)** **just let API middleware handle this logic**
112
**How** do we **resolve a bug?**
**create** an **actionCreator** to create an **API action** let **API middlware** handling **calling server, handling errors** **updates server** **updates store**
113
What's the problem with this code?
exporting **bugAdded, bugResolved, etc.** only place they're used is in bugs.js module **Soln?** Don't expose to outside other modules cannot use internals of bugs module
114
**What is Mosh** going to **show us around testing?**
**Right way** to do **testing in Redux applications** there is a **lot of bad information out there** **Short / practical introduction to testing (included)** **lot's of misconceptions around automated testing**
115
What is **automated testing?** ## Footnote **Hint: npm i** **jest** **@types/jest** **@bale/core** **@bale/preset-env** **babel-just**
**Writing code to test our code** can run **hundreds or thousands of tests** **far faster and easier** than **manually testing functions** always **an element of manual testing** there is a **balance between automated testing** and **manual testing** **Unit Test** tested without external dependencies fast to run, uses mock functions focus of this course\*\* (unit testing) run **during production** **Integration** test app with external resources slower but give greater confidence run at **certain phases** like committing code, getting production ready **End-to End** launch application, drive through UI slowest, most fragile tests
116
**How** do we **write tests**? Hint: Write social tests not solidarity tests
# Define a group / suit of tests describe ( ) function first arg - name (group) second arg - fn called by jest (includes test fns) **Name should be meaningful** "isEven should return true if given an even number" **function to define test** it ( ) given by jest **first arg** - name of test **second arg** - test fn (contains code of test) **Call function under test** call function you're testing **create an expectation (make an assertion)** expect ( ) fn provided by jest **Use a matcher in assertion** .toEqual ( ) , NaN, contains, etc
117
**How** can we **unit test** a **redux application?** ## Footnote **Hint: Solidarity tests are poor way**
as long as **no external resources**, it's **a unit test** **Solidarity (lonely) tests** **test individual building blocks in isolation** **write separate tests for** **actions creators, reducers, middleware** **POOR WAY** **Sadely, most books / courses teach this way** **Why?** **Coupled to implementation** **Know too much about how app is structured** structured to implementation when our implementation changes, **tests break** **slow us down, re-writing tests!** **Soln?** **Social tests** **implementation details** not important, **study behavior**
118
**What should** our **unit tests test**? **Hint:** test behavior NOT implementation
**Behavior of application** **NOT implementation** Ex. Test timer or microwave don't care how current goes around, etc in microwave only care about pressing start button test behavior not implementation **solidarity tests** are **testing action creators, reducers, etc.** They know too much about implementation details They're **too connected to implementation** **can test a lot of building blocks, but doesn't show if app work** **Redux is about changing state of store** **building blocks ensure app state changes accordingly** **test all building blocks together!** **Soln** **Social Tests**
119
What are social tests?
**Proper way to test redux applications** **dispatch an action, check state** **what happens under hood, irrelevant to tests** **Tests that involve multiple functions / objects working together** **Benefits:** **less fragile** **don't break** **more reliable** **test behavior of application** **don't care if an action, calls another action** **don't care if middleware catches an action, dispatches another** **don't care about reducers and how we combine them**
120
Are **solidarity tests evil?**
**Absolutely not** **they're great** and **have their own uses** if building **block is complex** test it **in isolation** **Redux building blocks are simple** **they don't have algorithms or complex logic** **no logic** **action creators** return **an action** **reducers** return **state**
121
How do we **write a solidarity test** for **adding a bug?**
**action creator addBug** r**eturns an action object** that **represents API call** have to call it, look at object **API middleware takes object,** on success **dispatches another action** **reducer takes action, updates store**
122
**What** is the **problem with writing solidarity tests?**
If we **change the implementation details**, **test fails!** **Solidarity tests:** break easily don't give confidence
123
**What's** the **problem with solidarity tests?** **Hint:** Doesn't test behavior of application
They **don't test application behavior** Ex. **api middleware commented out,** **test still passing**
124
**How** can we **write a social test?**
A **test that excercises multple building blocks** (units) **together** **doesn't break** with **updated implementation** **behavior is not changed** **beauty of social tests** **Ex.** Change **addBug ( )** implementation to **omit API middleware**
125
**How** do we **convert this test** from **an integration test** to **a unit test**? **Hint**: npm i axios-mock-adapter -D
**npm i axios-mock-adapter -D** creates mock axios HTTP objects **mock HTTP calls** **Why?** calling **external resources** slows **down our test** **external resources** might **not be available** when **running tests**
126
**What are techniques** for **writing clean and maintainable tests?**
**tests** are **equally as important as source code** **Many people don't treat them that way!** **spending time with messy test code** **Soln?** **write, clean maintainable testing code** **common pattern (arrange, act, assert)** **arrange** initialization code **act** triggering an action **assert** expectation code **What else?** **beforeEach ( )** **executes a function** before **each test** can **initialize things** before **each test**
127
**How** do we **write clean, maintainable tests?** ## Footnote **Hint: Arrange, Act, Assert**
**Arrange** setup the testing needs **Act** call function **Assert** make a statement about expected result
128
**How** do we **see how much of our code** is **covered by tests?** **Hint**: ./node\_modules/.bin/jest --coverage
**Jest --coverage** as we write more tests, have better coverage **coverage report** can **immediately see** which **parts of code** are **covered or not (by tests)**
129
**How** can we **make this test code cleaner?**
**Object structure (store)** is **cluttering testing code** will **need this store object in other tests** **repeating code is un-necessary** **Soln?** **create helper function** for **creating object structure** (store object) **createState( )** **makes test clean and readable**
130
**How do we write** a **test for testing the behavior** of the **resolveBug ( ) feature**?
Totally **okay to dispatch multiple actions** **interacting with the system,** **looking at behavior** **we are testing the behavior not the individual building blocks** **Two Tests:** **Happy Path** **Negative Path**
131
**How** can we **test our loadBugs ( ) feature**? **Hint:** **challenging** and **important excercise**
**most challenging and important excercises** **Pay lots of attention** **Lots of "aha" moments** **Key Moment:** **fakeAxios** has **two method signatures** call **second signature** to **execute code** before **server responds** **testing if using cache vs. server call** call method twice (dispatch loadBugs( ) x 2) check to see if have single HTTP request to backend **fakeAxios.history returns an array of get requests (see docs)** **can see if length of array equals 1**
132
**What** are **we going to learn** about **Redux and React** **integration?**
**How** to **subscribe to redux store** to **get data**
133
**What** is the **proper way** to **connect a React app to Redux?**
using **React Redux library** **Mosh is going to show us the manual way**
134
**How** **do we connect** our **React app to Redux** by **scratch?**
import **configureStore module** **pass store down** using **context (not prop drilling)** **can provide at top of tree, all others have access** **part of React course**
135
**How** do we **get the bugs from the backend** and **display them on the page?**
**Two Steps**: 1. **subscribe to store** get **list of bugs from store**, **render on screen** takes a function **executed** everytime an **action is dispatched** get bugs in store, store them locally in component 2. **dispatch(loadBugs())** to **get bugs** from **backend** and **put them in the store**
136
**What** is the **problem with this code**?
**It's very tedious** **have** to **write code** in **every component** **componentDidMount ( )** subscribe to store **componentWillUnmount ( )** unsubscribe from store if **forget anything,** will **cause memory leaks** **very tedious and error prone** **Soln?** **React Redux** **takes care of all this complexity**
137
**How** do I use **React-Redux library** to **connect my app to redux**?
**storeContext** **no longer needed** **no longer** do I have to **maintain local state** **React Redux will handle subscribing and unsubscribing from the store** **don't need componentWillUnmount** **this.props**
138
**What** is the **connect ( )** function in **React-Redux?**
called a **container component** **why?** because it **returns a function that can pass bugs component** **so that bugs doesn't know anything about store (redux)** Takes **two arguments:** **1. A function that takes state, returns part of the store our component is interested** state.entities.bugs.list **takes state** and returns part interested in **pass as props** to **component** const **mapStateToProps** = **state** =\> (**{** **bugs: state.entites.bugs.list }**) 2. **mapDispatchToProps** - dispatching actions takes **dispatch function** from store **maps to props** for **component**
139
**What** are **hooks**?
**kind** of **a new thing (feature) in react** **covered in detail in React course (final section)**
140
**Should** I connect a **top-level component** or **many small components to the Redux store**?
If you connect a **top-level component to the store**, that **component and all its children will get re-rendered every time the store gets updated.** Let's say App component has two children: Bugs and Projects. If you **connect App component** to the store, it **gets notified every time the list of bugs or projects is modified**. So if you add a bug, App component gets notified and the **list of bugs as well as the list of projects will be re-rendered.** This is **unnecessary and can cause a performance penalty.** So, as a best practice, **each component should independently subscribe to a small slice of the store it is interested in.** This way it **won't be re-rendered if other slices of the store are updated.**