/ReduxIntro

An introduction Redux, using actions, and reducers.

Primary LanguageJavaScript

Introduction to Redux

Redux in a nutshell is a collection of all the data that describes the application, while react represents the view which translates the apps data into something a user can interact with. Redux is totally seperate from React, in fact we use a library called react-redux to bridge them together. We centralize all of the data in the application into one object (application state).

TECH STACK

  1. React
  2. Redux

MISC TECH

  1. react-redux (module)
  2. redux (module)

WHAT I LEARNED

  1. ACTIONS
    • Action Cycle
      • Some event is triggered in the browser: either an user event (button click) or browser event (page load) etc..
      • Calls an Action Creactor
        • An action creator is just a function that returns an action which is an object, that has a mandatory type property that describes the purpose of the action.
      • The returned action is automatically sent to all reducers in the application to be interpreted
      • The reducer has a switch statement that switches on the action type.
        • The default case is to simply return the current state
      • Once all reducers process the action the newly assembled state is pumped back into the containers, then the browser is re-rendered with new data
// IN THE CONTAINER THIS FUNCTION IS PASSED A BOOK
export function selectBook(book){
    return {
        type: 'BOOK_SELECTED', // DESCRIBES THE TYPE OF EVENT/ACTION
        payload: book // DATA
    };
}
  1. REDUCERS
    • All reducers get two arguments (state, action)
      • State argument is not application state, only the state this reducer is responsible for
    • The applications state is formed by the reducers and changes depending on the type of action
    • Reducers are only called when an action takes place
    • Reducers are simply functions that return a peice of the application state
    • When the application first loads Redux will send an action to all reducers
      • At this point, the reducer will return an undefined value for state, which is why we default the state to null. You should never return an undefined state.
      • Also, our components that rely on this data will receive null values for state.
    • NEVER mutate state
// DEFAULT STATE TO NULL TO PREVENT RETURNING AN UNDEFINED VALUE
export default function(state = null, action){
    switch (action.type) {
        case 'BOOK_SELECTED':
            return action.payload;
    }
    // IF WE DON'T CARE ABOUT THE ACTION, JUST RETURN STATE
    return state;
}
  1. ROOT REDUCER
    • Uses combineReducers which is a method from redux to form an object that maps our state to the containers
import { combineReducers } from 'redux';

// IMPORT REDUCERS
import BooksReducer from './reducer_books';
import ActiveBookReducer from './reducer_active_book';

// APPLICATION STATE CENTRALIZED INTO ONE OBJECT THAT GETS CALLED BY OUR CONTAINERS
const rootReducer = combineReducers({
  books: BooksReducer,
  activeBook: ActiveBookReducer
});

export default rootReducer;
  1. Import these two into the container
// glue between React and Redux
import { connect } from 'react-redux';

// use this to make sure the action generated by the Action Creator flows through the reducers
import { bindActionCreators } from 'redux';
  1. A container is a react component that has a direct connection to our state managed by redux

    • Also called "smart components"
    • The most parent component that cares about a particular peice of state
    • Only the container component is connected to redux
    • A component that is aware of the state thats contained by Redux
  2. Two manadatory methods inside of containers:

// takes our application state as an argument
// this function is the glue between React and Redux
// whenever our application state changes, this container will instantly re-render
function mapStateToProps(state) {
    // whatever gets returned will show up as props inside of the container
    return {
        // to reference this object we use "this.props.books", because "books" is the key we assigned
        // "state.books" is a reference to the global state object formed by combineReducers()
        books: state.books
    };
}
// anything returned from this function will end up as props to the container
// now we can call this.props.selectBook for our (onClick example)
function mapDispatchToProps(dispatch){
    // Whenever selectBook is called the result will be passed to all reducers
    // dispatch is a function, the 2nd parameter that makes sure the result is received and sent to all the reducers
    // selectBook is a function that returns an object
    // the purpose of bindActionCreators and dispatch is to specifically take what gets returned from selectBook and make sure it flows through all reducers
    return bindActionCreators({ selectBook }, dispatch);
}
  1. Lastly
// connect takes a function and a component and produces a container
// whenever the application state changes the object in mapStateToProps will be assigned as props to the component
export default connect(mapStateToProps, mapDispatchToProps)(BookList);

Source: UDEMY course taught by Stephen Grider (https://github.com/StephenGrider/)