Skip to content

Instantly share code, notes, and snippets.

@n0m0r3pa1n
Created June 23, 2016 06:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save n0m0r3pa1n/267caa2b26174b6d5c74adca5bd00401 to your computer and use it in GitHub Desktop.
Save n0m0r3pa1n/267caa2b26174b6d5c74adca5bd00401 to your computer and use it in GitHub Desktop.

Redux Rules

  1. Immutable state - it should not be changeable instead is replaced. Everything that changes in your app including the date and the UI state is stored in a single object tree.
  2. State is read only - to make a change you need to dispatch an action. An action is a plain javascript object. State = data, change = action

Pure vs Impure functions

  1. Pure 2. Depend only on their input params 3. Some value for some input elements 4. No DB or network calls 5. Does not mutate input values 6. Do not keep state

The Reducer

  1. The UI is most predictable when it is described as a pure function of the application state
  2. The state mutations in the app can be described as pure functions that takes the previous state and the action being dispatched and returns the next state of the app. It always returns a new function. There is a single function that does it for a single applications
  3. To describe state mutations you need to use a function called a reducer

Reducers

If it receives "undefined" as state, it should return the default state. Reducers can be combined. We have 1 main reducer internally that calls other reducers with undefined state to get the initial state of the app. When an action comes it calls all of the reducers. combineReducers function generates a main reducer function that is used into the store.

The Store

Store bind the 3 principles of redux.

  • Holds state
  • Lets Dispatch actions
  • Specify reducer that tells how state is updated withactions when app is created

Methods:

  • getState - current state
  • dispatch({ type: "INC" }) - actions
  • subscribe - called when an action has been dispatched. Does not fire the very first time. Extract a method for subscribe, call the method on init.

Libraries

DeepFreeze to not allow array modification.

Object.assign - assign properties to a target object. The last property overrides the previous existing.

... - spread operator for new props.

Components

  1. Presentation - dumb components without any presentation logic. They delegate events to other components. Pass only the text, not objects.
  2. Container - passes method refs to Presentation components.

Containers extraction

Parent components need to know what data child components need. This breaks encapsulation and makes passing props more and more to the bottom.

Containers

  1. Rerender on update
  2. Unsubscribe when unmount
  3. Use state to render presentational components
  4. ContextTypes to get thestore 5. mapStateToProps - return the props depending on the current state for the Presentational components 6. mapDispatchToProps - props that depend on the dispatch method. Which callback prop dispatches which action for the presentational component.

For more info on Presentational and Container components check Redux website

connect from react-redux creates a container with state in context. connect(mapStateToProps, mapDispatchToProps)(PresentationalComponent)

  • creates a container which passes props to the Presentational component. Will pass the state. Merges properties from state, dispatch and props.
  • Export both the component calss and the connect. connect returns decorated component.
  • Depend on the dispatch method, not on the store. Inject dispatch through props. Create a container with connect.
  • mapStateToProps can be replaced by null
  • connect() will inject just the dispatch as a prop by default
  • make mapStateToProps and mapDispatchToProps per component. It is OK having multiple.
  • map... receives (state, ownProps) or (dispatch, ownProps)

Action Creators

  1. Extract creators as functions
  2. Actions should have as small data as possible
  3. To initiate dispatch call dispatch(action_creator(text)) or const addToDo => (text) => dispatch(addToDo(text))

Async Actions (redux-actions)

Calling Async APIs (redux-thunk)

  1. An action informing reducers that request started
  2. Action informing reducers that request finished successfully
  3. Action informing request is error - Use field like "error" in action or use separate type.

Redux-Thunk

applyMiddleware - to add as part of Redux It passes the dispatch function to action creators. It allows a function to return a function. Redux-Promise or Redux-Saga are alternative.

Middleware is used to allow other libs to attach between the moment when an event is dispatched and received by a reducer.

Reducing boilerplate

  1. Use constants as action names. It is visible for larger projects.
  2. Action creators - functions that return actions. Boilerplate! But with async they can access state and have logic.
  3. Use an action creator creating a function - redux-act, redux-actions
  4. Async action creators move API calls to more common places
  5. switch in reducer is not boilerplate
  6. Reducers can be expressed as key-method objects with fancy syntax

Others

Writing Tests

Testing reducers is easy and straight forward.

mocha can have a babel compiler set to write ES6 tests.

Redux-Undo

Keeps an object of the state in:

{
	past: [T], // array
	present: T, // single object
	future: [T] // array
}

Reducer-Enhancer

Takes a reducer and returns reducer with more options.

Computing derived data

Memoized selectors to not recalculate the whole state whenever a change is applied. Use reselect.

React

  1. React does not need "return". Only () are enough. A simple function can return jsx, not needed to extend a class. Dumb components are just a single function with jsx.
  2. Object.assign = { ..state }
  3. forceUpdate - force rerendering. store.subscribe return unsubscribe function.
  4. Pass store store through props to test it easier
    1. Create a Provider component which is a wrapper for the whole App component
    2. Uses advanced context feature and passes it to each inside component
    3. define getChildContext() { return this.props.store }
    4. Provider.childContextTypes = { store: React.proptypes.object }
    5. Access store via this.context
    6. Add proptypes to inside component
    7. DumbComponent(props: { store }) + PropTypes

react-redux - passes the store through the context. Uses Provider component, but still PropTypes are needed to receive it.

FAQ

Consult the FAQ of Redux if you have any more questions. It is very useful.

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