# Handling Complex State

## Handling Complex State Phase: 1

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

// Initializing State
const initialState = {
    count: 0,
    favColor: []
}

// Action Creators - Describe the types of actions

// changeCount Action
function changeCount(amount) {
    return {
        type: "CHANGE_COUNT",
        payload: amount
    }
}

// favoriteColor Action
function favoriteColor(color){
    return {
        type: "ADD_COLOR",
        payload: color
    }
}

// Reducer - takes an Action & Old Version of State as Input and returns a New Version of State 
function reducer(state = initialState, action) {
    switch(action.type) {
        case "CHANGE_COUNT":
            return {
                ...state, // return all previous states
                count: state.count + action.payload // append the new state of `count`
            }
        case "ADD_COLOR":
            return {
                ...state, // return all previous states
                favColor: [...state.favColor, action.payload] // append the new state of `favColor`
            }
        default:
            return state // return the latest state
    }
}

// Creating Store - createStore() takes reducer() as input
const store = redux.createStore(reducer)

// 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())
})

// Dispatch - carries the information to Reducer to inform what Type of Action should be performed 
store.dispatch(changeCount(5))
store.dispatch(favoriteColor("yellow"))
store.dispatch(favoriteColor("red"))

```

## Handling Complex State Phase: 2

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

// Initializing State
const initialState = {
    count: 0,
    favoriteThings: [],
    youtubeVideo: {
        title: "",
        viewCount: 0,
        votes:{
            upvote:0,
            downvote:0
        }
    }
}

// Action Creators - Describe the types of actions

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

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

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

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

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


// Reducer - takes an Action & Old Version of State as Input and returns a New Version of State 
function reducer(state = initialState, action) {
    switch(action.type) {
        case "CHANGE_COUNT":
            return {
                ...state,
                count: state.count + action.payload
            }
        case "ADD_FAVORITE_THING":
            return {
                ...state,
                favoriteThings: [...state.favoriteThings, action.payload]
            }
        case "REMOVE_FAVORITE_THING":
            const updatedArr = state.favoriteThings.filter(thing => thing !== action.payload)
            return {
                ...state,
                favoriteThings: updatedArr
            }
        case "SET_YOUTUBE_TITLE":
            return {
                ...state,
                 youtubeVideo: {
                     ...state.youtubeVideo,
                     title: action.payload
                 }
            }
        case "GIVE_UPVOTE":
            return {
                ...state,
                 youtubeVideo: {
                     ...state.youtubeVideo,
                     votes: {
                         ...state.youtubeVideo.votes,
                         upvote: state.youtubeVideo.votes.upvote + 1
                     }
                 }
            }
        default:
            return state
    }
}

// Creating Store - createStore() takes reducer as input
const store = redux.createStore(reducer)

// 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())
})

// Dispatch - carries the information to Reducer to inform what Type of Action should be performed 
store.dispatch(addFavoriteThing("Raindrops on roses"))
store.dispatch(addFavoriteThing("Whiskers on kittens"))
store.dispatch(removeFavoriteThing("Raindrops on roses"))
store.dispatch(setYoutubeTitle("Learn Js"))
store.dispatch(giveUpvote())

```
