Skip to content

Instantly share code, notes, and snippets.

@JackHowa
Last active May 22, 2022 17:49
Show Gist options
  • Save JackHowa/ead36f33879c672d8c5ed937690b654e to your computer and use it in GitHub Desktop.
Save JackHowa/ead36f33879c672d8c5ed937690b654e to your computer and use it in GitHub Desktop.
fcc redux curriculum snippets
this is for the free code camp course on Redux https://learn.freecodecamp.org/front-end-libraries/redux/create-a-redux-store
@JackHowa
Copy link
Author

https://learn.freecodecamp.org/front-end-libraries/redux/create-a-redux-store

  • need to use reducer as the param for creating a new redux store
  • redux store is the single source of truth
const reducer = (state = 5) => {
  return state;
}

// Redux methods are available from a Redux object
// For example: Redux.createStore()
// Define the store here:
const store = Redux.createStore(reducer);

@JackHowa
Copy link
Author

https://learn.freecodecamp.org/front-end-libraries/redux/get-state-from-the-redux-store

  • get ... state
  • retrieve the state (that sounds better 'retrieve')
const store = Redux.createStore(
  (state = 5) => state
);

// change code below this line
const currentState = store.getState();

@JackHowa
Copy link
Author

https://learn.freecodecamp.org/front-end-libraries/redux/define-a-redux-action

  • an action is just a js object that contains info about what's occurred with data
  • redux is about dispatching these actions
  • actions need a type property
// Define an action here:
const action = { type: 'LOGIN' };

@JackHowa
Copy link
Author

https://learn.freecodecamp.org/front-end-libraries/redux/define-an-action-creator

  • as simple as returning the obj is an action creator

An action creator is simply a JavaScript function that returns an action.

const action = {
  type: 'LOGIN'
}
// Define an action creator here:
function actionCreator() {
  return action;
};

@JackHowa
Copy link
Author

https://learn.freecodecamp.org/front-end-libraries/redux/dispatch-an-action-event

  • use the const with the () as the end loginAction() to return it
const store = Redux.createStore(
  (state = {login: false}) => state
);

const loginAction = () => {
  return {
    type: 'LOGIN'
  }
};

// Dispatch the action here:
store.dispatch(loginAction());

@JackHowa
Copy link
Author

https://learn.freecodecamp.org/front-end-libraries/redux/handle-an-action-in-the-store

  • used an an expression here to simplify
  • basically conditional reducer based on action type
const defaultState = {
  login: false
};

const reducer = (state = defaultState, action) => {
  // change code below this line
  return {
    login: action.type === 'LOGIN',
  }
  // if (action.type === 'LOGIN') {
  //   return {
  //     login: true,
  //   }
  // } else {
  //   return {
  //     login: false,
  //   }
  // change code above this line
};

const store = Redux.createStore(reducer);

const loginAction = () => {
  return {
    type: 'LOGIN'
  }
};

@JackHowa
Copy link
Author

JackHowa commented Jun 3, 2018

https://learn.freecodecamp.org/front-end-libraries/redux/create-a-redux-store/

redux is a state management framework

  • redux state is one object
  • each component can have its own local state
  • redux state is the single source of truth
  • createStore on the redux object
const reducer = (state = 5) => {
  return state;
}

// Redux methods are available from a Redux object
// For example: Redux.createStore()
// Define the store here:

// takes in the reducer as an argument 
// the the method createStore on the Redux object 
// the redux store is the one source of truth 
const store = Redux.createStore(reducer);

@JackHowa
Copy link
Author

JackHowa commented Jun 3, 2018

https://learn.freecodecamp.org/front-end-libraries/redux/get-state-from-the-redux-store

  • retrieve the current state of the state
  • next and current seem to be redux syntax
const store = Redux.createStore(
  (state = 5) => state
);

// change code below this line
// this is the getter for the state 
const currentState = store.getState();

@JackHowa
Copy link
Author

JackHowa commented Jun 3, 2018

https://learn.freecodecamp.org/front-end-libraries/redux/define-a-redux-action

  • updating state via redux is one of the key areas of its use
// Define an action here:
// basically a bare action object 
// type property is important here 

const action = { type: 'LOGIN'};

@JackHowa
Copy link
Author

JackHowa commented Jun 3, 2018

https://learn.freecodecamp.org/front-end-libraries/redux/define-an-action-creator

  • what about action creators vs dispatchers
const action = {
  type: 'LOGIN'
}
// Define an action creator here:
// just minimal returning an action via the function 

const actionCreator = () => action;

@JackHowa
Copy link
Author

JackHowa commented Jun 4, 2018

https://learn.freecodecamp.org/front-end-libraries/redux/dispatch-an-action-event

  • dispatch the created action
  • the store is responsible for dispatching this action
// redux store object
// with reducer as arg
const store = Redux.createStore(
  (state = {login: false}) => state
);

// set the type through the action creator
// returns an action obj
const loginAction = () => {
  return {
    type: 'LOGIN',
  }
};

// Dispatch the action here:
store.dispatch(loginAction());

@JackHowa
Copy link
Author

JackHowa commented Jun 4, 2018

@JackHowa
Copy link
Author

JackHowa commented Jun 4, 2018

const defaultState = {
  login: false
};

const reducer = (state = defaultState, action) => {
  // change code below this line
  switch (action.type) {
    // look for the action.type 
    // the reducer seems kinda like the decider or interpreter
    // for the action creator
    
    case 'LOGIN':
      return {
        login: true
      }
      break;
    default: 
      return state;
  }
  // change code above this line
};

const store = Redux.createStore(reducer);

const loginAction = () => {
  return {
    type: 'LOGIN'
  }
};

@JackHowa
Copy link
Author

JackHowa commented Jun 4, 2018

https://learn.freecodecamp.org/front-end-libraries/redux/use-a-switch-statement-to-handle-multiple-actions

  • case statements are a standard for writing reducers in redux
  • for now, with small objects, can return whole new ones
const defaultState = {
  authenticated: false
};

const authReducer = (state = defaultState, action) => {
  // change code below this line
  switch (action.type) {
    case 'LOGIN':
      return { authenticated: true };
      break;
    case 'LOGOUT':
      return { authenticated: false };
      break;  
    default:
      return state;
  }
  // change code above this line
};

const store = Redux.createStore(authReducer);

const loginUser = () => {
  return {
    type: 'LOGIN'
  }
};

const logoutUser = () => {
  return {
    type: 'LOGOUT'
  }
};

@JackHowa
Copy link
Author

JackHowa commented Jun 4, 2018

A common practice when working with Redux is to assign action types as read-only constants, then reference these constants wherever they are used.

  • therefore, should maintain them as only for working with changes
  • should define the types before the action creators for easy code reusability
// change code below this line
// changed here to reference before the methods 
const LOGIN = 'LOGIN';
const LOGOUT = 'LOGOUT';

// change code above this line

const defaultState = {
  authenticated: false
};

const authReducer = (state = defaultState, action) => {

  switch (action.type) {

    // changed here to reference const in reducer
    case LOGIN:
      return {
        authenticated: true
      }

    // changed here to reference const in reducer
    case LOGOUT:
      return {
        authenticated: false
      }

    default:
      return state;

  }

};

const store = Redux.createStore(authReducer);

// use const strings within the action creator
const loginUser = () => {
  return {
    type: LOGIN
  }
};

// use const strings within the action creator
const logoutUser = () => {
  return {
    type: LOGOUT
  }
};

@JackHowa
Copy link
Author

JackHowa commented Jun 4, 2018

https://learn.freecodecamp.org/front-end-libraries/redux/register-a-store-listener/

this is cool

  • the store subscribe listener function
  • this is called the store subscribe listener function
  • register a store listener
const ADD = 'ADD';

const reducer = (state = 0, action) => {
  switch(action.type) {
    case ADD:
      return state + 1;
    default:
      return state;
  }
};

const store = Redux.createStore(reducer);

// global count variable:
let count = 0;

// change code below this line
const updateCount = () => count++;

store.subscribe(updateCount); 
// change code above this line

store.dispatch({type: ADD});
console.log(count);
store.dispatch({type: ADD});
console.log(count);
store.dispatch({type: ADD});
console.log(count);

@JackHowa
Copy link
Author

JackHowa commented Jun 4, 2018

When the state of your app begins to grow more complex, it may be tempting to divide state into multiple pieces. Instead, remember the first principle of Redux: all app state is held in a single state object in the store. Therefore, Redux provides reducer composition as a solution for a complex state model. You define multiple reducers to handle different pieces of your application's state, then compose these reducers together into one root reducer. The root reducer is then passed into the Redux createStore() method.

@JackHowa
Copy link
Author

JackHowa commented Jun 4, 2018

https://learn.freecodecamp.org/front-end-libraries/redux/combine-multiple-reducers

  • combineReducers() is how to manage multiple, more complex state interactions
  • since redux state is all one object, a root reducer can be used that's the result of the combineReducers function
const INCREMENT = 'INCREMENT';
const DECREMENT = 'DECREMENT';

const counterReducer = (state = 0, action) => {
  switch(action.type) {
    case INCREMENT:
      return state + 1;
    case DECREMENT:
      return state - 1;
    default:
      return state;
  }
};

const LOGIN = 'LOGIN';
const LOGOUT = 'LOGOUT';

const authReducer = (state = {authenticated: false}, action) => {
  switch(action.type) {
    case LOGIN:
      return {
        authenticated: true
      }
    case LOGOUT:
      return {
        authenticated: false
      }
    default:
      return state;
  }
};

// this consolidates the two reducers 
// the keys you give the reducers is the name of the assoc
// piece of state 
const rootReducer = Redux.combineReducers({
  count: counterReducer,
  auth: authReducer
})


// define the root reducer here

const store = Redux.createStore(rootReducer);
 

@JackHowa
Copy link
Author

JackHowa commented Jun 4, 2018

https://learn.freecodecamp.org/front-end-libraries/redux/send-action-data-to-the-store/

  • just look at what is in the arguments
  • they're in the console
  • don't look for properties that aren't there in the obj
// this defines the type value 
const ADD_NOTE = 'ADD_NOTE';

// this is the reducer that takes in an action 
const notesReducer = (state = 'Initial State', action) => {
  switch(action.type) {
    // change code below this line
    case ADD_NOTE:
      // weird just returning the new state
      state = action.text;
      return state;
      break;
    // change code above this line
    default:
      return state;
  }
};

const addNoteText = (note) => {
  // change code below this line
  // make sure to just update text with base note
  return { 
    type: ADD_NOTE, 
    text: note
  }
  // change code above this line
};

const store = Redux.createStore(notesReducer);

console.log(store.getState());
store.dispatch(addNoteText('Hello!'));
console.log(store.getState());

@JackHowa
Copy link
Author

  • subscribe is a method on the redux store object
  • that subscribe called every time there's an action on the store
  • if we dispatch to the store 3 times, then subscribe will be called 3 times
// this is the action name
const ADD = 'ADD';

// this is the reducer that (perhaps wrongly)
// modifies state directly 
const reducer = (state = 0, action) => {
  switch(action.type) {
    case ADD:
      // increment state by 1
      return state + 1;
    default:
      // default returns unchanged state
      return state;
  }
};

// store created with reducer as arg
const store = Redux.createStore(reducer);

// this count variable will change
// global count variable:
let count = 0;

// change code below this line
// so want to reflect state changes here
// with count
// increments the value, then evaluates and stores it.
// which is better than:
// x++ evaluates the value, then increments and stores it.
// anywho... redux 
store.subscribe(() => ++count)
// change code above this line

store.dispatch({type: ADD});
console.log(count);
store.dispatch({type: ADD});
console.log(count);
store.dispatch({type: ADD});
console.log(count);

@JackHowa
Copy link
Author

++x > x++ via https://stackoverflow.com/questions/3469885/somevariable-vs-somevariable-in-javascript

for performance and make sure that alert(1++) returns 2

@JackHowa
Copy link
Author

  • don't want to divide state into mutiple pieces when things get complex

  • first principle of redux: all app state is held in store object

  • multiple reducers for multiple pieces of state

  • can use keys for when the reducers are combined

const rootReducer = Redux.combineReducers({
auth: authenticationReducer,
notes: notesReducer
});

@JackHowa
Copy link
Author

  • the state held in the redux store will have different properties auth and notes

@JackHowa
Copy link
Author

JackHowa commented Jun 16, 2018

https://learn.freecodecamp.org/front-end-libraries/redux/combine-multiple-reducers

  • need to use the object syntax
  • used the function references, not calling them, via functionName not functionName()
// two redux action names
const INCREMENT = 'INCREMENT';
const DECREMENT = 'DECREMENT';

// one reducer for counter 
// interesting how the reducer consts are right near it
const counterReducer = (state = 0, action) => {
  switch(action.type) {
    case INCREMENT:
      return state + 1;
    case DECREMENT:
      return state - 1;
    default:
      return state;
  }
};

const LOGIN = 'LOGIN';
const LOGOUT = 'LOGOUT';

const authReducer = (state = {authenticated: false}, action) => {
  switch(action.type) {
    case LOGIN:
      return {
        authenticated: true
      }
    case LOGOUT:
      return {
        authenticated: false
      }
    default:
      return state;
  }
};

const rootReducer = Redux.combineReducers({
  count: counterReducer,
  auth: authReducer, 
});

const store = Redux.createStore(rootReducer);

@JackHowa
Copy link
Author

https://learn.freecodecamp.org/front-end-libraries/redux/send-action-data-to-the-store

  • can get the initial state to compare it the new state
// action's type value
const ADD_NOTE = 'ADD_NOTE';

const notesReducer = (state = 'Initial State', action) => {
  switch (action.type) {
    // change code below this line
    // just taking away from the action
    // text property to the store
    case (ADD_NOTE): 
      return action.text;
    // change code above this line
    default:
      return state;
  }
};

// action creator
const addNoteText = (note) => {
  // change code below this line
  return { type: ADD_NOTE, text: note };
  // change code above this line
};

const store = Redux.createStore(notesReducer);

console.log(store.getState()); 
// logs Initial State

// dispatch the action creator's object
store.dispatch(addNoteText('Hello!'));

// get the new state after dispatching
// to the reducer
console.log(store.getState());
// logs 'Hello!'

@JackHowa
Copy link
Author

https://learn.freecodecamp.org/front-end-libraries/redux/use-middleware-to-handle-asynchronous-actions

  • redux thunk is middleware designed for async actions
  • async actions are an unavoidable part of web dev

https://gist.github.com/markerikson/ea4d0a6ce56ee479fe8b356e099f857e

const REQUESTING_DATA = 'REQUESTING_DATA'
const RECEIVED_DATA = 'RECEIVED_DATA'

const requestingData = () => { return {type: REQUESTING_DATA} }
const receivedData = (data) => { return {type: RECEIVED_DATA, users: data.users} }

const handleAsync = () => {
  return function(dispatch) {
    // dispatch request action here

    dispatch(requestingData());
    setTimeout(function() {
      let data = {
        users: ['Jeff', 'William', 'Alice']
      }
      // dispatch received data action here
      dispatch(receivedData(data));

    }, 2500);

  }
};

const defaultState = {
  fetching: false,
  users: []
};

const asyncDataReducer = (state = defaultState, action) => {
  switch(action.type) {
    case REQUESTING_DATA:
      return {
        fetching: true,
        users: []
      }
    case RECEIVED_DATA:
      return {
        fetching: false,
        users: action.users
      }
    default:
      return state;
  }
};

const store = Redux.createStore(
  asyncDataReducer,
  Redux.applyMiddleware(ReduxThunk.default)
);

@JackHowa
Copy link
Author

JackHowa commented Jun 17, 2018

https://learn.freecodecamp.org/front-end-libraries/redux/write-a-counter-with-redux

  • need to return the whole action creator
  • need to initialize a default state to get it going

// define a constant for increment action types
const INCREMENT = 'INCREMEMENT'; 

// define a constant for decrement action types
const DECREMENT = 'DECREMENT'; 

// define the counter reducer which will increment or decrement the state based on the action it receives
const counterReducer = (state = 0, action) => {
  switch (action.type) {
    case (INCREMENT): 
      return ++state;
    case (DECREMENT): 
      return --state;
    default:
      return state;
  }
}; 

// define an action creator for incrementing
const incAction = () =>  {return {type: INCREMENT}}; 

// define an action creator for decrementing
const decAction = () =>  {return {type: DECREMENT}}; 

// define the Redux store here, passing in your reducers
const store = Redux.createStore(counterReducer); 

@JackHowa
Copy link
Author

https://learn.freecodecamp.org/front-end-libraries/redux/never-mutate-state

Immutable state means that you never modify state directly, instead, you return a new copy of state.
This immutability, in fact, is what provides such features as time-travel debugging that you may have heard about.

// define action type constant
const ADD_TO_DO = 'ADD_TO_DO';

// A list of strings representing tasks to do:
const todos = [
  'Go to the store',
  'Clean the house',
  'Cook dinner',
  'Learn to code',
];

const immutableReducer = (state = todos, action) => {
  switch(action.type) {
    case ADD_TO_DO:
      // don't mutate state here or the tests will fail
      // return all the todos spread
      // with the new action.todo
      return [...todos, action.todo];
    default:
      return state;
  }
};

// an example todo argument would be 'Learn React',
const addToDo = (todo) => {
  return {
    type: ADD_TO_DO,
    // nice tricky es6  object assignment
    todo
  }
}

const store = Redux.createStore(immutableReducer);

@JackHowa
Copy link
Author

https://learn.freecodecamp.org/front-end-libraries/redux/remove-an-item-from-an-array

  • need to remove an item without slice
  • nope: let newState = state.slice(action.index);

https://stackoverflow.com/questions/34582678/is-this-the-correct-way-to-delete-an-item-using-redux

  • fitler returns a new arr
const immutableReducer = (state = [0,1,2,3,4,5], action) => {
  switch(action.type) {
    case 'REMOVE_ITEM':
      // don't mutate state here or the tests will fail

      let newState = state.filter((element, index) => {
       return  index !== action.index
      })
      console.log(newState);
      return newState
    default:
      return state;
  }
};

const removeItem = (index) => {
  return {
    type: 'REMOVE_ITEM',
    index
  }
}

const store = Redux.createStore(immutableReducer);

@JackHowa
Copy link
Author

JackHowa commented Jun 17, 2018

https://learn.freecodecamp.org/front-end-libraries/redux/copy-an-object-with-object-assign

  • const newObject = Object.assign({}, obj1, obj2);

This creates newObject as a new object, which contains the properties that currently exist in obj1 and obj2.

  • basically edit the properties mentioned
  • doesn't mutate
const defaultState = {
  user: 'CamperBot',
  status: 'offline',
  friends: '732,982',
  community: 'freeCodeCamp'
};
undefined
console.log(Object.assign({}, defaultState, {status: 'online'}))

{user: "CamperBot", status: "online", friends: "732,982", community: "freeCodeCamp"}
const defaultState = {
  user: 'CamperBot',
  status: 'offline',
  friends: '732,982',
  community: 'freeCodeCamp'
};

const immutableReducer = (state = defaultState, action) => {
  switch(action.type) {
    case 'ONLINE':
      // don't mutate state here or the tests will fail
      return Object.assign({}, defaultState, {status: 'online'});
    default:
      return state;
  }
};

const wakeUp = () => {
  return {
    type: 'ONLINE'
  }
};

const store = Redux.createStore(immutableReducer);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment