1)Redux Introduction:
===================
What about React State ?
"I thought React already had state, why do i need a separate" tool to do it ?" -you
--> How to handle state that your whole application needs.
--> Lack of organization and clarity.
Guidelines principals
--> A single source of truth("global state")
--> State is read-only("actions")
--> Changes are made with pure functions("reducers")
Fundamentals:
==============
1) Actions & action creators
2) Dispatch
3) Reducers
4) Store
2)Plain JS Redux - Overview:
============================
[email protected] package
[Link]:
=========
const redux = require("redux")
const initialState = {
count: 0
}
function reducer(state=initialState, action) {
switch([Link]) {
case "INCREMENT":
return {
count: [Link] + 1
}
case "DECREMENT":
return {
count: [Link] - 1
}
default:
return state
}
}
const store = [Link](reducer)
[Link](() => {
[Link]([Link]())
})
[Link]({type: "INCREMENT"})
[Link]({type: "INCREMENT"})
[Link]({type: "DECREMENT"})
3)Plain JS Redux - Actions:
===========================
[Link]:
=========
const redux = require("redux")
const action = {
type: "INCREMENT"
}
4)Plain JS Redux - Action Creators:
===================================
const redux = require("redux")
function increment() {
return {
type: "INCREMENT"
}
}
[Link](increment())
5)Plain JS Redux - Reducer:
===========================
[Link]:
=========
const redux = require("redux")
function increment() {
return {
type: "INCREMENT"
}
}
function decrement() {
return {
type: "DECREMENT"
}
}
function reducer(state = {count: 0}, action) {
// return new state based on the incoming [Link]
switch([Link]) {
case "INCREMENT":
return {
count: [Link] + 1
}
case "DECREMENT":
return {
count: [Link] - 1
}
default:
return state
}
}
6)Plain JS Redux Practice 1:
============================
/**
* Challenge:
*
* Enable the ability to double and halve the count.
* If halving, round down instead of letting your count
* become a decimal.
*/
[Link]:
=========
/**
* Challenge:
*
* Do it again, from scratch!
*
* 1. Action creators for increment, decrement, double, and halve
* 2. Reducer to handle these actions 👆🏻
*/
function increment() {
return {
type: "INCREMENT"
}
}
function decrement() {
return {
type: "DECREMENT"
}
}
function double() {
return {
type: "DOUBLE"
}
}
function halve() {
return {
type: "HALVE"
}
}
function reducer(state = 0, action) {
switch([Link]) {
case "INCREMENT":
return state + 1
case "DECREMENT":
return state - 1
case "DOUBLE":
return state * 2
case "HALVE":
return [Link](state / 2)
default:
return state
}
}
7)Plain JS Redux - Creating the Store:
======================================
we need to get store object by using redux methoud createStore(reducer function)
const store = [Link](reducer)
[Link](store)
[Link]:
=========
const redux = require("redux")
function increment() {
return {
type: "INCREMENT"
}
}
function decrement() {
return {
type: "DECREMENT"
}
}
function reducer(state = {count: 0}, action) {
// return new state based on the incoming [Link]
switch([Link]) {
case "INCREMENT":
return {
count: [Link] + 1
}
case "DECREMENT":
return {
count: [Link] - 1
}
default:
return state
}
}
const store = [Link](reducer)
[Link](store)
8)Plain JS Redux - subscribe and getState:
==========================================
by using store object we can subscribe and getState of an object
const store = [Link](reducer)
[Link](()=>{
getState()
})
[Link]:
=========
const redux = require("redux")
function increment() {
return {
type: "INCREMENT"
}
}
function decrement() {
return {
type: "DECREMENT"
}
}
function reducer(state = {count: 0}, action) {
// return new state based on the incoming [Link]
switch([Link]) {
case "INCREMENT":
return {
count: [Link] + 1
}
case "DECREMENT":
return {
count: [Link] - 1
}
default:
return state
}
}
const store = [Link](reducer)
[Link](() => {
[Link]([Link]())
})
9)Plain JS Redux - dispatch
===========================
[Link](actiontype as parameter to pass the values to reducer)
[Link]:
========
const redux = require("redux")
function increment() {
return {
type: "INCREMENT"
}
}
function decrement() {
return {
type: "DECREMENT"
}
}
function reducer(state = {count: 0}, action) {
// return new state based on the incoming [Link]
switch([Link]) {
case "INCREMENT":
return {
count: [Link] + 1
}
case "DECREMENT":
return {
count: [Link] - 1
}
default:
return state
}
}
const store = [Link](reducer)
[Link](() => {
[Link]([Link]())
})
[Link](increment())
[Link]({type:"INCREMENT"})
10)Plain JS Redux - Payload in action creators:
===============================================
Dynamic passing action types into reducer
[Link]:
=========
const redux = require("redux")
function changeCount(amount = 1) {
return {
type: "CHANGE_COUNT",
payload: amount
}
}
function reducer(state = {count: 0}, action) {
switch([Link]) {
case "CHANGE_COUNT":
return {
count: [Link] + [Link]
}
default:
return state
}
}
const store = [Link](reducer)
[Link](() => {
[Link]([Link]())
})
[Link](changeCount())
11)Plain JS Redux - Handling more complex state:
================================================
[Link]:
=========
const redux = require("redux")
function changeCount(amount = 1) {
return {
type: "CHANGE_COUNT",
payload: amount
}
}
function addFavoriteThing(thing) {
return {
type: "ADD_FAVORITE_THING",
payload: thing
}
}
const initialState = {
count: 0,
favoriteThings: []
}
function reducer(state = initialState, action) {
switch([Link]) {
case "CHANGE_COUNT":
return {
...state,
count: [Link] + [Link]
}
case "ADD_FAVORITE_THING":
return {
...state,
favoriteThings: [...[Link], [Link]]
}
default:
return state
}
}
const store = [Link](reducer)
[Link](() => {
[Link]([Link]())
})
[Link](changeCount(2))
[Link](addFavoriteThing("Raindrops on roses"))
[Link](addFavoriteThing("Whiskers on kittens"))
14)Plain JS Redux - Practice::
==============================
/**
* Challenge: implement an action creator called `removeFavoriteThing` which takes
the string
* of the favorite thing you want to remove from the array and removes it
*/
[Link]:
=========
const redux = require("redux")
function changeCount(amount = 1) {
return {
type: "CHANGE_COUNT",
payload: amount
}
}
function addFavoriteThing(thing) {
return {
type: "ADD_FAVORITE_THING",
payload: thing
}
}
function removeFavoriteThing(thing) {
return {
type: "REMOVE_FAVORITE_THING",
payload: thing
}
}
const initialState = {
count: 0,
favoriteThings: []
}
function reducer(state = initialState, action) {
switch([Link]) {
case "CHANGE_COUNT":
return {
...state,
count: [Link] + [Link]
}
case "ADD_FAVORITE_THING":
return {
...state,
favoriteThings: [...[Link], [Link]]
}
case "REMOVE_FAVORITE_THING": {
const arrCopy = [...[Link]]
const updatedArr = [Link](thing =>
[Link]() !== [Link]())
return {
...state,
favoriteThings: updatedArr
}
}
default:
return state
}
}
const store = [Link](reducer)
[Link](() => {
[Link]([Link]())
})
[Link](addFavoriteThing("Raindrops on roses"))
[Link](addFavoriteThing("Whiskers on kittens"))
/**
* Challenge: implement an action creator called `removeFavoriteThing` which takes
the string
* of the favorite thing you want to remove from the array and removes it
*/
[Link](removeFavoriteThing("raindrops on roses"))
15)Plain JS Redux - Even more complex state:
============================================
[Link]:
=========
const redux = require("redux")
function changeCount(amount = 1) {
return {
type: "CHANGE_COUNT",
payload: amount
}
}
function addFavoriteThing(thing) {
return {
type: "ADD_FAVORITE_THING",
payload: thing
}
}
function removeFavoriteThing(thing) {
return {
type: "REMOVE_FAVORITE_THING",
payload: thing
}
}
function setYouTubeTitle(title) {
return {
type: "SET_YOUTUBE_TITLE",
payload: title
}
}
function upvoteVideo() {
return {
type: "UPVOTE_VIDEO"
}
}
const initialState = {
count: 0,
favoriteThings: [],
youtubeVideo: {
title: "",
viewCount: 0,
votes: {
up: 0,
down: 0
}
}
}
[Link](initialState)
/**
* Challenge:
* Implement an action creator and reducer case to handle upvoting our YouTube
video (+1)
*/
function reducer(state = initialState, action) {
switch([Link]) {
case "CHANGE_COUNT":
return {
...state,
count: [Link] + [Link]
}
case "ADD_FAVORITE_THING":
return {
...state,
favoriteThings: [...[Link], [Link]]
}
case "REMOVE_FAVORITE_THING": {
const arrCopy = [...[Link]]
const updatedArr = [Link](thing =>
[Link]() !== [Link]())
return {
...state,
favoriteThings: updatedArr
}
}
case "SET_YOUTUBE_TITLE":
return {
...state,
youtubeVideo: {
...[Link],
title: [Link]
}
}
case "UPVOTE_VIDEO":
return {
...state,
youtubeVideo: {
...[Link],
votes: {
...[Link],
up: [Link] + 1
}
}
}
default:
return state
}
}
const store = [Link](reducer)
[Link](() => {
[Link]([Link]())
})
[Link](setYouTubeTitle("Learn Redux"))
[Link](upvoteVideo())
16 17)Plain JS Redux - combineReducers Part 1 $ Part 2:
=======================================================
// import the separate reducers
// combine the reducers into a single state tree
// create the store
// export the store
redux/[Link]:
===============
export function changeCount(amount = 1) {
return {
type: "CHANGE_COUNT",
payload: amount
}
}
export default function countReducer(count = 0, action) {
switch([Link]) {
case "CHANGE_COUNT":
return count + [Link]
default:
return count
}
}
redux/[Link]:
=========================
export function addFavoriteThing(thing) {
return {
type: "ADD_FAVORITE_THING",
payload: thing
}
}
export function removeFavoriteThing(thing) {
return {
type: "REMOVE_FAVORITE_THING",
payload: thing
}
}
export default function favoriteThingsReducer(favoriteThings = [], action) {
switch([Link]) {
case "ADD_FAVORITE_THING":
return [...favoriteThings, [Link]]
case "REMOVE_FAVORITE_THING": {
const updatedArr = [Link](thing => [Link]() !
== [Link]())
return updatedArr
}
default:
return favoriteThings
}
}
redux/[Link]:
======================
export function setYouTubeTitle(title) {
return {
type: "SET_YOUTUBE_TITLE",
payload: title
}
}
export function incrementViewCount() {
return {
type: "INCREMENT_VIEW_COUNT"
}
}
export function upvoteVideo() {
return {
type: "UPVOTE_VIDEO"
}
}
export function downvoteVideo() {
return {
type: "DOWNVOTE_VIDEO"
}
}
const initialState = {
title: "",
viewCount: 0,
votes: {
up: 0,
down: 0
}
}
export default function youTubeVideoReducer(youTubeVideo = initialState, action) {
switch([Link]) {
case "INCREMENT_VIEW_COUNT":
return {
...youTubeVideo,
viewCount: [Link] + 1
}
case "SET_YOUTUBE_TITLE":
return {
...youTubeVideo,
title: [Link]
}
case "UPVOTE_VIDEO":
return {
...youTubeVideo,
votes: {
...[Link],
up: [Link] + 1
}
}
case "DOWNVOTE_VIDEO":
return {
...youTubeVideo,
votes: {
...[Link],
down: [Link] + 1
}
}
default:
return youTubeVideo
}
}
redux/[Link]:
=========
// import the separate reducers
// combine the reducers into a single state tree
// create the store
// export the store
const redux = require("redux")
const {combineReducers, createStore} = redux
import countReducer from "./count"
import favoriteThingsReducer from "./favoriteThings"
import youTubeVideoReducer from "./youTubeVideo"
const rootReducer = combineReducers({
count: countReducer,
favoriteThings: favoriteThingsReducer,
youTubeVideo: youTubeVideoReducer
})
const store = createStore(rootReducer)
[Link](() => {
[Link]([Link]())
})
export default store
[Link]:
=========
import store from "./redux"
import {changeCount} from "./redux/count"
[Link](changeCount(42))
18)Plain JS Redux Practice 1:
==============================
/**
* Challenge:
*
* 1. Bring in all the action creators we've made so far and dispatch them, just to
make sure things are working
*/
above combine part 1 and part 2 same
===================================
[Link]:
=========
import store from "./redux"
import {changeCount} from "./redux/count"
import {addFavoriteThing, removeFavoriteThing} from "./redux/favoriteThings"
import {setYouTubeTitle, incrementViewCount, upvoteVideo, downvoteVideo} from
"./redux/youTubeVideo"
/**
* Challenge:
*
* 1. Bring in all the action creators we've made so far and dispatch them, just to
make sure things are working
*/
[Link](changeCount(42))
[Link](addFavoriteThing("Door bells"))
[Link](addFavoriteThing("Sleigh bells"))
[Link](removeFavoriteThing("door bells"))
[Link](setYouTubeTitle("Learning Redux is Fun!"))
[Link](incrementViewCount())
[Link](upvoteVideo())
[Link](incrementViewCount())
[Link](upvoteVideo())
[Link](incrementViewCount())
[Link](upvoteVideo())
[Link](downvoteVideo())
/*
{count: 42, favoriteThings: [], youTubeVideo: {title: "", viewCount: 0, votes: {up:
0, down: 0}}}
{count: 42, favoriteThings: ["Door bells"], youTubeVideo: {title: "", viewCount: 0,
votes: {up: 0, down: 0}}}
{count: 42, favoriteThings: ["Door bells", "Sleigh bells"], youTubeVideo: {title:
"", viewCount: 0, votes: {up: 0, down: 0}}}
{count: 42, favoriteThings: ["Sleigh bells"], youTubeVideo: {title: "", viewCount:
0, votes: {up: 0, down: 0}}}
{count: 42, favoriteThings: ["Sleigh bells"], youTubeVideo: {title: "Learning Redux
is Fun!", viewCount: 0, votes: {up: 0, down: 0}}}
{count: 42, favoriteThings: ["Sleigh bells"], youTubeVideo: {title: "Learning Redux
is Fun!", viewCount: 1, votes: {up: 0, down: 0}}}
{count: 42, favoriteThings: ["Sleigh bells"], youTubeVideo: {title: "Learning Redux
is Fun!", viewCount: 1, votes: {up: 1, down: 0}}}
{count: 42, favoriteThings: ["Sleigh bells"], youTubeVideo: {title: "Learning Redux
is Fun!", viewCount: 2, votes: {up: 1, down: 0}}}
{count: 42, favoriteThings: ["Sleigh bells"], youTubeVideo: {title: "Learning Redux
is Fun!", viewCount: 2, votes: {up: 2, down: 0}}}
{count: 42, favoriteThings: ["Sleigh bells"], youTubeVideo: {title: "Learning Redux
is Fun!", viewCount: 3, votes: {up: 2, down: 0}}}
{count: 42, favoriteThings: ["Sleigh bells"], youTubeVideo: {title: "Learning Redux
is Fun!", viewCount: 3, votes: {up: 3, down: 0}}}
{count: 42, favoriteThings: ["Sleigh bells"], youTubeVideo: {title: "Learning Redux
is Fun!", viewCount: 3, votes: {up: 3, down: 1}}}
*/
19)Plain JS Redux Practice 2:
==============================
same as above 18
[Link]:
=========
/**
* Challenge:
*
* Create a new state property to hold the currently-logged-in user info. I.e. if
our app wanted to allow a user to log in, we would likely want to keep track of
some info from the logged in user. For this challenge, you'll save a user with
these properties:
* {
* firstName: ___,
* lastName: ___,
* id: ___,
* email: ___
* }
*
* This will require
* (1) Creating a new file to hold our new Redux stuff re: the user (e.g.
[Link]),
* (2) Creating a new action creator (e.g. "setUserDetails"),
* (3) Creating a new reducer, and
* (4) Adding that reducer to our rootReducer with combineReducers
*/
redux/[Link]:
==============
export function setUserDetails(user) {
return {
type: "SET_USER_DETAILS",
payload: user
}
}
export function removeUserDetails() {
return {
type: "REMOVE_USER_DETAILS"
}
}
export default function userReducer(user = {}, action) {
switch([Link]) {
case "SET_USER_DETAILS":
return {
...user,
...[Link]
}
case "REMOVE_USER_DETAILS":
return {}
default:
return user
}
}
redux/[Link]:
===============
const redux = require("redux")
const {combineReducers, createStore} = redux
import countReducer from "./count"
import favoriteThingsReducer from "./favoriteThings"
import youTubeVideoReducer from "./youTubeVideo"
import userReducer from "./user"
const rootReducer = combineReducers({
count: countReducer,
favoriteThings: favoriteThingsReducer,
youTubeVideo: youTubeVideoReducer,
user: userReducer
})
const store = createStore(rootReducer)
[Link](() => {
[Link]([Link]())
})
export default store
main [Link]:
==============
import store from "./redux"
import {changeCount} from "./redux/count"
import {addFavoriteThing, removeFavoriteThing} from "./redux/favoriteThings"
import {setYouTubeTitle, incrementViewCount, upvoteVideo, downvoteVideo} from
"./redux/youTubeVideo"
import {setUserDetails, removeUserDetails} from "./redux/user"
[Link](setUserDetails({
firstName: "Joe",
lastName: "Schmoe",
id: 1,
email: "joe@[Link]"
}))
[Link](setUserDetails({
email: "[Link]@[Link]"
}))
[Link](removeUserDetails())
Important:
==========
18) Redux in React - Setup & Practice:
======================================
[email protected]
[email protected]
redux/[Link]:
===============
/**
* Challenge: set up redux action creators, reducer, and store
* We'll be building a counter app to start out.
* Read the comments below for the step-by-step challenges
*/
import redux, {createStore} from "redux"
function increment() {
return {
type: "INCREMENT"
}
}
function decrement() {
return {
type: "DECREMENT"
}
}
function reducer(count = 0, action) {
switch([Link]) {
case "INCREMENT":
return count + 1
case "DECREMENT":
return count - 1
default:
return count
}
}
const store = createStore(reducer)
[Link](() => [Link]([Link]()))
export default store
// 1. Create action creators for having the count "increment" and "decrement"
// 2. Create a reducer to handle your increment and decrement actions
// 3. Create a new Redux store
// 4. Set up the subscribe function so we can more easily see the changes to the
Redux state as they happen
// 5. Export the store as a default export
19)Redux in React - react-redux & Provider:
===========================================
same example above 18 Redux in React - react-redux & Provider
[Link]:
=========
import React from "react"
import ReactDOM from "react-dom"
import {Provider} from "react-redux"
import store from "./redux"
import App from "./App"
[Link](
<Provider store={store}>
<App />
</Provider>,
[Link]("root")
)
20)Redux in React - connect()
=============================
--> How does connect work?
--> Pass 2 things:
1."What parts of the global state does this component want access to ?"
2."What actions do you want to be able to dispatch from this component ?"
--> It then returns a function to which you pass the component you want to connect.
When called, this function creates a new component wrapping yours which passes
the
global state and "dispatchable" actions to your component via props.
--> connect("What parts of state do you want ? ","What actions do you want to
dispatch ?")(Components)
connect(mapStateToPropsFunc,mapDispatchToPropsFunc)(Component)
[Link]:
=======
import React from "react"
import {connect} from "react-redux"
function App(props) {
return (
<div>
<h1>COUNT GOES HERE</h1>
<button>-</button>
<button>+</button>
</div>
)
}
export default connect
(/* What parts of state do you want? */, /* What actions to dispatch? */)(App)
21)Redux in React - mapStateToProps:
==================================
function mapStateToProps(globalState) {
// return an object where the keys are the name of the prop your component
wants,
// values are the actual parts of the global state your component wants
return {
bananas: globalState
}
}
// Write the mapStateToProps function from scratch
// Takes the global state from Redux as a parameter
// returns an object where the keys are the name of the prop your component wants,
// and the values are the actual parts of the global state your component wants
[Link]:
=======
import React from "react"
import {connect} from "react-redux"
function App(props) {
return (
<div>
<h1>{[Link]}</h1>
<button>-</button>
<button>+</button>
</div>
)
}
// Write the mapStateToProps function from scratch
// Takes the global state from Redux as a parameter
// returns an object where the keys are the name of the prop your component wants,
// and the values are the actual parts of the global state your component wants
function mapStateToProps(state) {
return {
count: state
}
}
export default connect(mapStateToProps, {})(App)
22)Redux in React - mapDispatchToProps:
=======================================
redux/[Link]:
==============
import redux, {createStore} from "redux"
export function increment() {
return {
type: "INCREMENT"
}
}
export function decrement() {
return {
type: "DECREMENT"
}
}
function reducer(count = 0, action) {
switch([Link]) {
case "INCREMENT":
return count + 1
case "DECREMENT":
return count - 1
default:
return count
}
}
const store = createStore(reducer)
[Link](() => [Link]([Link]()))
export default store
[Link]:
=======
import React from "react"
import {connect} from "react-redux"
import {increment, decrement} from "./redux"
function App(props) {
return (
<div>
<h1>{[Link]}</h1>
<button onClick={[Link]}>-</button>
<button onClick={[Link]}>+</button>
</div>
)
}
// [Link]
export default connect(state => ({count: state}), {increment, decrement})(App)
22)Redux in React - useSelector():
==================================
[Link] replace useConnect with useSelector()
======
import React from "react"
import {useSelector} from "react-redux"
import {increment, decrement} from "./redux"
function App(props) {
const count = useSelector(state => state)
return (
)
}
// export default connect(state => ({count: state}), {increment, decrement})(App)
export default App
24)Redux in React - useDispatch():
==================================
replace connect(1,2) first parameter with useSelector and second parameter with
useDispatch():
-----------------------------------------------------------------------------------
-----------
[Link]:
=======
import React from "react"
import {useSelector, useDispatch} from "react-redux"
import {increment, decrement} from "./redux"
function App(props) {
const count = useSelector(state => state)
const dispatch = useDispatch()
return (
<div>
<h1>{count}</h1>
<button onClick={() => dispatch(decrement())}>-</button>
<button onClick={() => dispatch(increment())}>+</button>
</div>
)
}
export default App
// [Link]
// [Link]
25)Redux in React - Redux Thunk:
================================
not understood:
===============
[Link]:
=======
import redux, {createStore, applyMiddleware} from "redux"
import thunk from "redux-thunk"
export function increment() {
return (dispatch, getState) => {
const number = getState()
const baseUrl = "[Link]
fetch(`${baseUrl}/${number}`)
.then(res => [Link]())
.then(res => {
[Link](res)
dispatch({
type: "INCREMENT",
payload: res
})
})
}
}
/**
{name: "C-3PO", height: "167", mass: "75", hair_color: "n/a", skin_color: "gold",
eye_color: "yellow", birth_year: "112BBY", gender: "n/a", homeworld:
"[Link] films: ["[Link]
"[Link] "[Link]
"[Link] "[Link]
"[Link] species: ["[Link]
vehicles: [], starships: [], created: "2014-12-10T[Link].357000Z", edited: "2014-
12-20T[Link].309000Z", url: "[Link]
*/
export function decrement() {
return {
type: "DECREMENT"
}
}
function reducer(count = 0, action) {
switch([Link]) {
case "INCREMENT":
return count + 1
case "DECREMENT":
return count - 1
default:
return count
}
}
const store = createStore(reducer, applyMiddleware(thunk))
[Link](() => [Link]([Link]()))
export default store
Getting Hired - Edabit:
=======================
For Practicing Coding Challenges
[Link]
Codesignal:
===========
[Link]
pramp:
======
practice:
[Link]
Getting Hired - Problem Solving:
================================
George Polya --> how to solve it ?
1) Understand the problem
2) Devise a plan
3) Execute the plan
4) Review your solution