Redux
Redux
===================
"I thought React already had state, why do i need a separate" tool to do it ?" -you
Guidelines principals
Fundamentals:
==============
1) Actions & action creators
2) Dispatch
3) Reducers
4) Store
index.js:
=========
store.subscribe(() => {
console.log(store.getState())
})
store.dispatch({type: "INCREMENT"})
store.dispatch({type: "INCREMENT"})
store.dispatch({type: "DECREMENT"})
index.js:
=========
const redux = require("redux")
const action = {
type: "INCREMENT"
}
function increment() {
return {
type: "INCREMENT"
}
}
console.log(increment())
index.js:
=========
const redux = require("redux")
function increment() {
return {
type: "INCREMENT"
}
}
function decrement() {
return {
type: "DECREMENT"
}
}
/**
* Challenge:
*
* Enable the ability to double and halve the count.
* If halving, round down instead of letting your count
* become a decimal.
*/
index.js:
=========
/**
* 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"
}
}
index.js:
=========
function increment() {
return {
type: "INCREMENT"
}
}
function decrement() {
return {
type: "DECREMENT"
}
}
store.subscribe(()=>{
getState()
})
index.js:
=========
const redux = require("redux")
function increment() {
return {
type: "INCREMENT"
}
}
function decrement() {
return {
type: "DECREMENT"
}
}
index.js:
========
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 action.type
switch(action.type) {
case "INCREMENT":
return {
count: state.count + 1
}
case "DECREMENT":
return {
count: state.count - 1
}
default:
return state
}
}
store.dispatch(increment())
store.dispatch({type:"INCREMENT"})
index.js:
=========
const redux = require("redux")
function changeCount(amount = 1) {
return {
type: "CHANGE_COUNT",
payload: amount
}
}
store.dispatch(changeCount())
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: []
}
store.dispatch(changeCount(2))
store.dispatch(addFavoriteThing("Raindrops on roses"))
store.dispatch(addFavoriteThing("Whiskers on kittens"))
index.js:
=========
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: []
}
store.dispatch(addFavoriteThing("Raindrops on roses"))
store.dispatch(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
*/
store.dispatch(removeFavoriteThing("raindrops on roses"))
index.js:
=========
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
}
}
}
console.log(initialState)
/**
* Challenge:
* Implement an action creator and reducer case to handle upvoting our YouTube
video (+1)
*/
store.dispatch(setYouTubeTitle("Learn Redux"))
store.dispatch(upvoteVideo())
redux/count.js:
===============
export function changeCount(amount = 1) {
return {
type: "CHANGE_COUNT",
payload: amount
}
}
redux/favouriteThings.js:
=========================
export function addFavoriteThing(thing) {
return {
type: "ADD_FAVORITE_THING",
payload: thing
}
}
redux/youTubeVideo.js:
======================
export function setYouTubeTitle(title) {
return {
type: "SET_YOUTUBE_TITLE",
payload: title
}
}
const initialState = {
title: "",
viewCount: 0,
votes: {
up: 0,
down: 0
}
}
redux/index.js:
=========
// import the separate reducers
// combine the reducers into a single state tree
// create the store
// export the store
index.js:
=========
import store from "./redux"
import {changeCount} from "./redux/count"
store.dispatch(changeCount(42))
index.js:
=========
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
*/
store.dispatch(changeCount(42))
store.dispatch(addFavoriteThing("Door bells"))
store.dispatch(addFavoriteThing("Sleigh bells"))
store.dispatch(removeFavoriteThing("door bells"))
store.dispatch(setYouTubeTitle("Learning Redux is Fun!"))
store.dispatch(incrementViewCount())
store.dispatch(upvoteVideo())
store.dispatch(incrementViewCount())
store.dispatch(upvoteVideo())
store.dispatch(incrementViewCount())
store.dispatch(upvoteVideo())
store.dispatch(downvoteVideo())
/*
{count: 42, favoriteThings: [], youTubeVideo: {title: "", viewCount: 0, votes: {up:
0, down: 0}}}
*/
index.js:
=========
/**
* 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.
user.js),
* (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/user.js:
==============
export function setUserDetails(user) {
return {
type: "SET_USER_DETAILS",
payload: user
}
}
main index.js:
==============
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"
store.dispatch(setUserDetails({
firstName: "Joe",
lastName: "Schmoe",
id: 1,
email: "[email protected]"
}))
store.dispatch(setUserDetails({
email: "[email protected]"
}))
store.dispatch(removeUserDetails())
Important:
==========
18) Redux in React - Setup & Practice:
======================================
[email protected]
[email protected]
redux/index.js:
===============
/**
* 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
*/
function increment() {
return {
type: "INCREMENT"
}
}
function decrement() {
return {
type: "DECREMENT"
}
}
// 1. Create action creators for having the count "increment" and "decrement"
// 4. Set up the subscribe function so we can more easily see the changes to the
Redux state as they happen
index.js:
=========
import React from "react"
import ReactDOM from "react-dom"
import {Provider} from "react-redux"
import store from "./redux"
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
)
--> connect("What parts of state do you want ? ","What actions do you want to
dispatch ?")(Components)
connect(mapStateToPropsFunc,mapDispatchToPropsFunc)(Component)
App.js:
=======
function App(props) {
return (
<div>
<h1>COUNT GOES HERE</h1>
<button>-</button>
<button>+</button>
</div>
)
}
App.js:
=======
import React from "react"
import {connect} from "react-redux"
function App(props) {
return (
<div>
<h1>{props.count}</h1>
<button>-</button>
<button>+</button>
</div>
)
}
App.js:
=======
import React from "react"
import {connect} from "react-redux"
import {increment, decrement} from "./redux"
function App(props) {
return (
<div>
<h1>{props.count}</h1>
<button onClick={props.decrement}>-</button>
<button onClick={props.increment}>+</button>
</div>
)
}
// https://react-redux.js.org/api/connect#connect
function App(props) {
const count = useSelector(state => state)
return (
)
}
App.js:
=======
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>
)
}
// https://thoughtbot.com/blog/using-redux-with-react-hooks
// https://react-redux.js.org/api/hooks#usage-warnings
/**
{name: "C-3PO", height: "167", mass: "75", hair_color: "n/a", skin_color: "gold",
eye_color: "yellow", birth_year: "112BBY", gender: "n/a", homeworld:
"https://swapi.co/api/planets/1/", films: ["https://swapi.co/api/films/2/",
"https://swapi.co/api/films/5/", "https://swapi.co/api/films/4/",
"https://swapi.co/api/films/6/", "https://swapi.co/api/films/3/",
"https://swapi.co/api/films/1/"], species: ["https://swapi.co/api/species/2/"],
vehicles: [], starships: [], created: "2014-12-10T15:10:51.357000Z", edited: "2014-
12-20T21:17:50.309000Z", url: "https://swapi.co/api/people/2/"}
*/
Codesignal:
===========
https://app.codesignal.com/signup
pramp:
======
practice:
https://www.pramp.com/.
2) Devise a plan
3) Execute the plan