Skip to content

Instantly share code, notes, and snippets.

@katemalone
Forked from qfarenwald/redux.md
Created November 6, 2019 14:33
Show Gist options
  • Save katemalone/4ed35a2395bdba5aa7d798de56f45e02 to your computer and use it in GitHub Desktop.
Save katemalone/4ed35a2395bdba5aa7d798de56f45e02 to your computer and use it in GitHub Desktop.

Redux notes that might get deleted from OUR gist

Redux Notes

https://frontend.turing.io/lessons/module-3/ideabox-to-redux.html https://frontend.turing.io/lessons/module-3/react-to-redux-workshop.html

Set Up

git clone https://github.com/filepath.git rename-if-you-want
cd rename-if-you-want
npm i
npm start

repeat for both UI and API

npm i redux react-redux redux-devtools-extension -S

Cycle

App.js should be set up as normal React with a state...

/App/App.js

What is in state that you want in store? Identify the method...

Action Creator Create directory and files

/src/

mkdir Actions
touch index.js

Create action in index.js

Name variable the same as the method

export const actionName = payLoadName => ({
  type: 'YELL_ACTION_NAME',
  payLoadName
});

No need to export or import anything

Reducer Create directory and files

Name individual reducer file what you would name the property in state

Create an individual reducer file for each property in state we want to update

/src/

mkdir Reducers
touch index.js todos.js

Create reducer in todos.js file

export const nameOfProperty = (state = [], action) => {
  switch (action.type) {
    case 'TYPE_NAME':
      return action.payLoadName
    default:
      return state;
  }
}

Ex reducer with multiple cases:

export const nameOfProperty = (state = [], action) => {
  switch (action.type) {
    case 'TYPE_NAME_1':
      return action.payLoadName
    case 'TYPE_NAME_ADD_2':
      return [...state, action.payLoadName]
    case 'TYPE_NAME_DELETE_3':
      state = state.filter(item => item.item_id !== action.id)
      return state
    case 'TYPE_NAME_LOGOUT_4':
      state = []
      return state
    default:
      return state
  }
}

Combine Reducers Either create the roote reducer and/or add the reducer to the rootReducer

/reducers/index.js

import { combineReducers } from 'redux';
import { reducerName } from './reducerName'; // reducer, must import each reducer 

const rootReducer = combineReducers({
  reducerName
});

export default rootReducer;

Set Up In Index Time to set up the store

/src/index.js

Import: Provider, createStore, composeWithDevTools, rootReducer

Create store

Wrap App

import { Provider } from 'react-redux';
import { createStore } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension';
import rootReducer from './reducers';

const store = createStore(rootReducer, composeWithDevTools());

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

Go to console, redux tool, check to see if state is updated

Connect React Components To Store mapDispatchToProps Do you need to send information to the store?

Go to that file

Import: connect, action, maybe bindActionCreators

Make sure to assign method to props

Create mapDispatchToProps

Edit export with connect

import { connect } from 'react-redux';
import { actionName } from '../actions';
import { bindActionCreators } from 'redux';

class AddTodoForm extends Component {

  funcName = () => {
    const { actionName } = this.props;
    actionName(this.state);
  }

  render(){
  }
}

export const mapDispatchToProps = dispatch => ({
  actionName: item => dispatch( actionName(item) )
})

// OR

export const mapDispatchToProps = (dispatch) => (
  bindActionCreators(
    {
      actionName,
    },
    dispatch,
  )
);

export default connect(null, mapDispatchToProps)(Component);

mapStateToProps Do you need to get information from the store?

Go to that file

Import: connect, action

Create mapStateToProps

Edit export with connect


import { connect } from 'react-redux';

const funcName = ({ itemInStoreName }) => {
  const displayWhatever = itemInStoreName.map(singularItemInStoreName => {
    return (
      <Component
        {...singularItemInStoreName}
        key={singularItemInStoreName.id}
      />
    )
  })

  return (
    <ul>
      {displayWhatever}
    </ul>
  )
}

const mapStateToProps = state => ({
  itemInStoreName: state.itemInStoreName
});

export default connect(mapStateToProps, null)(ToDoList);

Boilerplates - Redux Tests

actions

import * as actions from '../actions';

describe('actions', () => {

  describe('actionName', () => {
    it('should have a type of TYPE_NAME', () => {
      const whatYouAreFeedingTheAction = [
        {
          key: value,
          key: value
        },
        {
          key: value,
          key: value
        }
      ]
      const expectedAction = {
        type: 'TYPE_NAME',
        varInAction: [
          {
            key: value,
            key: value
          },
          {
            key: value,
            key: value
          }
        ]
      }

      const result = actions.actionName(varFeedingToTheAction);

      expect(result).toEqual(expectedAction);
    });
  });
});

Reducers

import { reducerName } from './reducerName';

describe('reducerName', () => {
  it('should return the initial state', () => {
    const expected = [];

    const result = reducerName(undefined, {});

    expect(result).toEqual(expected);
  });

  it('should add payLoadName to state', () => {
    const initialState = [];
    const mockNewPayLoadName = {
      name: 'Quinne Farenwald'
    };
    const state = initialState;
    const action = {
      type: 'TYPE_NAME',
      payloadName: mockNewPayLoadName
    };

    const newState = [...initialState, mockNewPayLoadName];

    const result = reducerName(state, action);

    expect(result).toEqual(newState);
  });
});

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