# Plain JS Redux Practice

## Plain JS Redux Practice

{% tabs %}
{% tab title="count.js" %}

```jsx
// changeCount Action
export function changeCount(amount = 1) {
    return {
        type: "CHANGE_COUNT",
        payload: amount
    }
}

// count Reducer
export default function countReducer(count = 0, action){
    switch(action.type){
        case "CHANGE_COUNT":
            return count + action.payload
        default:
            return count
    }   
}
```

{% endtab %}

{% tab title="favoriteThing.js" %}

```jsx
// addfavoriteThing Action
export function addFavoriteThing(thing) {
    return {
        type: "ADD_FAVORITE_THING",
        payload: thing
    }
}

// removeFavoriteThing Action
export function removeFavoriteThing(thing) {
    return {
        type: "REMOVE_FAVORITE_THING",
        payload: thing
    }
}

export default function favoriteThingsReducer(favoriteThings = [], action){
    switch(action.type){
        case "ADD_FAVORITE_THING":
            return [...favoriteThings, action.payload]
        case "REMOVE_FAVORITE_THING":
            const updatedArr = favoriteThings.filter(thing => thing !== action.payload)
            return updatedArr
        default:
            return favoriteThings
    }
}
```

{% endtab %}

{% tab title=" youTubeVideo.js" %}

```jsx
// setYoutubeTitle Action
export function setYoutubeTitle(title) {
    return {
        type: "SET_YOUTUBE_TITLE",
        payload: title
    }
}

// incrementViewCount Action
export function incrementViewCount() {
    return {
        type: "INCREMENT_VIEW_COUNT"
    }
}

// giveUpvote Action
export function giveUpvote() {
    return {
        type: "GIVE_UPVOTE"
    }
}

// giveDownvote Action
export function giveDownvote() {
    return {
        type: "GIVE_DOWNVOTE"
    }
}

const initialState = {
    title: "",
    viewCount: 0,
    votes:{
        upvote:0,
        downvote:0
    }
}

// youTubeVideo Reducer
export default function youTubeVideoReducer(youTubeVideo = initialState, action){
    switch(action.type){
        case "SET_YOUTUBE_TITLE":
            return {
                ...youTubeVideo,
                title: action.payload
            }
        case "INCREMENT_VIEW_COUNT":
            return {
                ...youTubeVideo,
                viewCount: youTubeVideo.viewCount + 1
            }
        case "GIVE_UPVOTE":
            return {
                ...youTubeVideo,
                votes: {
                    ...youTubeVideo.votes,
                    upvote: youTubeVideo.votes.upvote + 1
                }   
            }
        case "GIVE_DOWNVOTE":
            return {
                ...youTubeVideo,
                votes: {
                    ...youTubeVideo.votes,
                    downvote: youTubeVideo.votes.downvote - 1
                }
            }
        default:
            return youTubeVideo
    }
}
```

{% endtab %}

{% tab title="user.js" %}

```jsx
// setUserDetails Action
export function setUserDetails(user) {
    return {
        type: "SET_USER_DETAILS",
        payload: user
    }
}

// removeUserDetails Action
export function removeUserDetails() {
    return {
        type: "REMOVE_USER_DETAILS"
    }
}

export default function userReducer(user = null, action) {
    switch(action.type) {
        case "SET_USER_DETAILS":
            return {
                ...user, // keep previous state
                ...action.payload // append new state
            }
        case "REMOVE_USER_DETAILS":
            return null // empty user detail
        default:
            return user
    }
}
```

{% endtab %}

{% tab title="rootReducer.js" %}

```jsx
// Importing all reducers
import countReducer from "./count"
import favoriteThingsReducer from "./favoriteThings"
import youTubeVideoReducer from "./youTubeVideo"
import userReducer from "./user"

// Importing Redux
const redux = require("redux")

// Destructure combineReducers & createStore from Redux 
const {combineReducers, createStore} = redux

// Combining the reducers into a single state tree
const rootReducer = combineReducers({
    count: countReducer,
    favoriteThings: favoriteThingsReducer,
    youTubeVideo: youTubeVideoReducer,
    user: userReducer
})

// Creating Store - createStore() takes rootReducer() as input
const store = createStore(rootReducer)

// subscribe() - a redux method that is called everytime a change occurs in the Store 
store.subscribe(() => {
    // getState() returns the current state tree of your application
    console.log(store.getState())
})

// Exporting Store
export default store

```

{% endtab %}

{% tab title="index.js" %}

```jsx
// Importing Store 
import store from "./redux"

// Importing Actions
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"

// Dispatch - carries the information to Reducer to inform what Type of Action should be performed 
store.dispatch(setUserDetails({
    firstName: "Joe",
    lastName: "Schmoe",
    id: 1,
    email: "joe@schmoe.com"
}))
store.dispatch(setUserDetails({
    email: "joe.schmoe@gmail.com"
}))
store.dispatch(removeUserDetails())
```

{% endtab %}
{% endtabs %}
