Skip to content

Instantly share code, notes, and snippets.

@RuairiSpain
Created May 18, 2017 21:55
Show Gist options
  • Save RuairiSpain/963deb636e40451d1cb2ceb184ea32e2 to your computer and use it in GitHub Desktop.
Save RuairiSpain/963deb636e40451d1cb2ceb184ea32e2 to your computer and use it in GitHub Desktop.
Ducks
import { actions as ticketActions } from 'ducks/ticket'
import { actions as messageActions } from 'ducks/message'
import { actions as navigationActions } from 'ducks/navigation'
...
const mapDispatchToProps = (dispatch) => ({
...bindActionCreators({
...ticketActions,
...messageActions,
...navigationActions
}, dispatch)
})
https://hackernoon.com/my-journey-toward-a-maintainable-project-structure-for-react-redux-b05dfd999b5
ortort
exportexport const types = {
AUTO_LOGIN: 'AUTH/AUTH_AUTO_LOGIN',
SIGNUP_REQUEST: 'AUTH/SIGNUP_REQUEST',
SIGNUP_SUCCESS: 'AUTH/SIGNUP_SUCCESS',
SIGNUP_FAILURE: 'AUTH/SIGNUP_FAILURE',
LOGIN_REQUEST: 'AUTH/LOGIN_REQUEST',
LOGIN_SUCCESS: 'AUTH/LOGIN_SUCCESS',
LOGIN_FAILURE: 'AUTH/LOGIN_FAILURE',
LOGOUT: 'AUTH/LOGOUT'
}
export const initialState = {
user: null,
isLoading: false,
error: null
}
export default (state = initialState, action) => {
switch (action.type) {
case types.SIGNUP_REQUEST:
case types.LOGIN_REQUEST:
return { ...state, isLoading: true, error: null }
case types.SIGNUP_SUCCESS:
case types.LOGIN_SUCCESS:
return { ...state, isLoading: false, user: action.user }
case types.SIGNUP_FAILURE:
case types.LOGIN_FAILURE:
return { ...state, isLoading: false, error: action.error }
case types.LOGOUT:
return { ...state, user: null }
default:
return state
}
}
//Actions in a object, easier to import
export const actions = {
signup: (email, password) => ({ type: SIGNUP_REQUEST, email, password })
login: (email, password) => ({ type: actionTypes.LOGIN_REQUEST, email, password }),
logout: () => ({ type: actionTypes.LOGOUT })
}
//Selectors
export const getProduct = (state) => state.product.products
export const getProductById = (state, id) => find(state.product.products, id)
export const getProductSortedByName = (state) => sortBy(state.product.products, 'name')
export const getExpiredProducts = (state) => filter(state.product.products, { isExpired: true })
ducks/auth.js, you can create sagas/auth.js, containing the sagas that are triggered by authTypes.SIGNUP_REQUEST, authTypes.LOGIN_REQUEST and so on…
import { types as authTypes } from 'ducks/auth'
import { types as productTypes } from 'ducks/product'
import { * as authSagas } from 'sagas/auth'
import { * as productSagas } from 'sagas/product'
export default function* rootSaga () {
yield [
takeEvery(authTypes.AUTO_LOGIN, authSagas.autoLogin),
takeEvery(authTypes.SIGNUP_REQUEST, authSagas.signup),
takeEvery(authTypes.LOGIN_REQUEST, authSagas.login),
takeEvery(authTypes.PASSWORD_RESET_REQUEST, authSagas.resetPassword),
takeEvery(authTypes.LOGOUT, authSagas.logout),
takeEvery(productTypes.GET_PRODUCTS_REQUEST, productSagas.getTickets)
]
}
Shared saga across child sagas
// sagas/index.js
takeEvery(authTypes.LOGIN_FAILURE, uiSagas,showErrorAlert),
takeEvery(menuTypes.GET_MENU_ERROR_FAILURE, uiSagas.showErrorAlert)
// sagas/ui.js
import { call } from 'redux-saga/effects'
import { Alert } from 'react-native'
export function* showErrorAlert (action) {
const { error } = action
yield call(Alert.alert, 'Error', error)
}
src
├── components
├── containers
│ ├── auth.js
│ ├── productList.js
│ └── productDetail.js
├── reducers (aka ducks)
│ ├── index.js (combineReducers + complex selectors)
│ ├── auth.js (reducers, action types, actions creators, selectors)
│ └── product.js (reducers, action types, actions creators, selectors)
├── sagas
│ ├── index.js (root saga/table of content of all the sagas)
│ ├── auth.js
│ └── product.js
└── services
├── authenticationService.js
└── productsApi.js
OR
src
├── actions
│ ├── index.js (action types + action creators)
│ ├── auth.js (action types + action creators)
│ ├── other.js (action types + action creators)
│ └── product.js (action types + action creators)
├── reducers
│ ├── index.js (combineReducers + complex selectors)
│ ├── auth.js (reducer + specific reducer selectors)
│ └── product.js (reducer + specific reducer selectors)
└── sagas
├── index.js (root saga/table of content of all the sagas)
├── auth.js
└── product.js
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment