Redux

No one really knows what redux is (except Dan Abromov). For real, no one. They pretend.

REDUCERS MUST BE PURE FUNCTIONS.

Removing Items from Array

Utilize slice for the purest way

Adding Items to an Array

Utilize the … operator for the purest way

1) Everything is described in a single state tree 2) The only way to change the state tree is to dispatch an action. An action is a plain javascript object describing in the minimal way what action is taken. Always uses type:type: SET_VISIBILITY_FILTER or type: DECREMENT or type: INCREMENT or type: TOGGLE_BUTTON 3) The third principle of redux is that it must return three things. The original state of the application, action being dispatched, then returns the entire state of the application.

INCREDIBLY IMPORTANT PAGE FOR ISSUING API CALLS WITH REDUX https://github.com/reactjs/redux/issues/291

Testing the provider, store, dispatch in console

You can test it with this…

$r.store.dispatch.increment({ type: 'INCREMENT_LIKES', index: 0  });

Fundamental SHIT

When you dispatch an action, every reducer will fire. It’s up to the reducer to decide whether to act on that or not.

PRACTICAL SHIT 1. When your appplication uses Redux, it handles all of the state for you front end. THAT MEANS YOU DO NOT NEED TO TRACK THE STATE WITHIN THE REACT COMPONENT

Critical Components of Redux

Store - store.js - it holds the entire state of our application.?

Provider - does something similar to what the Store does. But I think this makes the state available to our entire application.

WHAT A REDUCER DOES

A reducer takes the inital state, modifies it, returns state. A reducer also takes an action.

Implementation: Create individual reducers in a /reducers/ folder. Then import them all into a big reducer which will be utilized by the application. The giant reducer is known as the ROOT REDUCER

DO I REALLY NEED react-redux when I’m using redux with react… ?

YES YES YES

import { Provider } from 'react-redux';

react-redux connect

import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as ActionCreators from '../actions';

function mapStateToProps(state) {
  return {
    posts: state.posts,
    comments: state.comments
  }
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators(actionCreators, dispatch);
}

const App = connect(mapStateToProps, mapDispatch)(ComponentToPassPropsTo);

export default App;

Pure Functions (Good)

This is an important concept.

function square(x) {
  return x * x
}

function squareAll(items) {
  return items.map(square);
}

No network calls, does not override the arguments passed into the function.

Impure functions (Bad)

function square(x) {
  updateXInDatabase(x);
  return x * x;
}

function squareAll(items) {
  for (let i = 0, i < items.length; i++) {
    items[1] = square(items[i]);
  }
}

That last function overrides the variable that you passed it.

The view layer is most predictable when it is described as a pure function as the application state.

Redux compliments this approach that The state mutations need to be represented in your app as a pure function. Takes your current state and your action and returns your new state.

Basic Redux Application

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

const { createStore } = Redux;
// var createStore = Redux.createStore;
// import { createStore } from 'redux';
// all the same

const store = createStore(counter);

// store has 3 important methods
  // getState()
  // dispatch() --> most common
  // subscribe() -->

const render = () => {
  document.body.innerText = store.getState();
};

store.subscribe(render);
render();

document.addEventListener('click', () => {
  store.dispatch({ type: 'INCREMENT' })
});

expect(
  counter(0, { type: 'INCREMENT' })
).toEqual(1);

expect(
  counter(1, { type: 'INCREMENT' })
).toEqual(2);

expect(
  counter(1, { type: 'DECREMENT' })
).toEqual(0);

expect(
  counter(2, { type: 'DECREMENT' })
).toEqual(1);

expect(
  counter(1, { type: 'ANOTHER_FUCKING_ACTION'})
).toEqual(1);

expect(
  counter(undefined, {})
).toEqual(0);

console.log("Tests passed!");

If you’re like Dan Abramov, you like to understand the tools you are using, so reimplementing them is good.

Recreate the createStore method from Redux

const createStore = (reducer) => {
  let state;
  let listeners = [];

  const getState = () => state;

  const dispatch = (action) => {
    state = reducer(state, action);
    listeners.forEach(listener => listener());
  };

  const subscribe = (listener) => {
    listeners.push(listener);

    return () => {
      listeners = listeners.filter(l => l !== listener);
    }
  };

  dispatch({});

  return { getState, dispatch, subscribe };
}

Counter with React and Redux

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

const Counter = ({
  value,
  onIncrement,
  onDecrement
}) => (
  <div>
    <h1>{value}</h1>
    <button onClick={onIncrement}>+</button>
    <button onClick={onDecrement}>-</button>
  </div>
);


const { createStore } = Redux;
// var createStore = Redux.createStore;
// import { createStore } from 'redux';
// all the same

const store = createStore(counter);

// store has 3 important methods
  // getState()
  // dispatch() --> most common
  // subscribe() -->

const render = () => {
  ReactDOM.render(
    <Counter
      value={store.getState()}
      onIncrement={() =>
        store.dispatch({
        type: 'INCREMENT'
      })
    }
    onDecrement={() =>
      store.dispatch({
        type: 'DECREMENT'
      })
    }
    />,
    document.getElementById('root')
  );
};

store.subscribe(render);
render();


expect(
  counter(0, { type: 'INCREMENT' })
).toEqual(1);

expect(
  counter(1, { type: 'INCREMENT' })
).toEqual(2);

expect(
  counter(1, { type: 'DECREMENT' })
).toEqual(0);

expect(
  counter(2, { type: 'DECREMENT' })
).toEqual(1);

expect(
  counter(1, { type: 'ANOTHER_FUCKING_ACTION'})
).toEqual(1);

expect(
  counter(undefined, {})
).toEqual(0);

console.log("Tests passed!");

Post Content