Skip to content

Instantly share code, notes, and snippets.

@kristianfreeman
Last active August 24, 2017 22:16
Show Gist options
  • Save kristianfreeman/6c465fe595d919e8c595d97947cd634d to your computer and use it in GitHub Desktop.
Save kristianfreeman/6c465fe595d919e8c595d97947cd634d to your computer and use it in GitHub Desktop.

This is the "Redux manufacturing" project, which simulates a warehouse that accepts orders, prepares them for delivery, and ships them. It's built with React and Redux.

The project starts with an existing codebase built without Redux. We'll integrate Redux and react-redux, move the component-level functions into reducers, and define actions to be dispatched from the component to make these state changes happen.

What needs to happen

A number of functions are defined in the top-level component, App.js. These functions are passed in as props to various components, and are called to update the App component's state.

We need to move each of these functions into the Redux reducer function, ensure that they are pure functions, and define the appropriate actions (and constants) to be able to dispatch those actions from components.

Patterns for moving React code into Redux:

  • A function in a top-level component that updates state should be moved into the reducer. Look at what state modifications it makes (what does it change in this.setState), and ensure those same keys (orders, packaged) are defined in the Redux state object.
generateOrder() {
  // $DOSTUFF
  this.setState({
  });
}

In Redux:

function appReducer(state, action) {
  switch (action.type) {
    case GENERATE_ORDER:
      // $DOSTUFF
  }
}

Adding an action constant, and the action creator for dispatching that action should be done in actions.js:

// actions.js
export const GENERATE_ORDER = 'GENERATE_ORDER'
export generateOrder = () => { return {
  type: GENERATE_ORDER
}}

In the component:

// App.js
import { generateOrder } from './actions';

class App extends React.Component {
  render() {
    return (
      <div>
        <button onClick={this.props.generateOrder}>
          Generate order
        </button>
      </div>
    )
  }
}

Moving from state to props

Generally, if a component was relying on this.state.<something>, moving that piece of data into Redux application state means that it will become available at this.props.<something>, if passed into the container component.

When to use thunked actions, when to use simple actions

If an action needs to do some kind of logic (checking an existing value in state, or picking between actions to dispatch), or if it needs to dispatch more than one action, it should be a "thunked" action:

const thunkedAction = () => {
  return dispatch => {
    dispatch({ type: 'AN_ACTION' })
  }
}

Actions dispatched inside of a thunked action can be action creators:

const anAction = () => { return { type: AN_ACTION { {
const thunkedAction = () => {
  return dispatch => {
    dispatch(anAction())
  }
}

I don't understand what this component is doing! How can I move it into Redux?

In general, you should be able to move the pieces of functionality in the component into the reducer, and update the behavior accordingly. For instance, instead of referring to this.state, we should have access to the variable state from inside the reducer.

Otherwise, that might be my bad. If the component itself is unclear (what does "packaging an order" mean?), feel free to ask me and I'll do my best to explain.

Cheatsheet

  • Passing props
<MyComponent propName={propValue} />

// In MyComponent, access prop as...
this.props.propName
  • Reducer functions
function myReducer(state, action) {
  switch (action.type) {
    case ACTION_CONSTANT:
      return $newversionofstate;
  }
}
  • Exporting action constants
export const ADD_ITEM = 'ADD_ITEM'
  • Action creators
export const addItem = () => { return {
  type: ADD_ITEM
}}

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