Last active
July 12, 2018 02:38
-
-
Save ryo33/e9025aff382554171f09ee4ec58ba45e to your computer and use it in GitHub Desktop.
redux-pages
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Increase the number of done tasks | |
export const DONE = 'DONE'; | |
// Reset the number | |
export const RESET = 'RESET'; | |
// Switch 'on' and 'off' | |
export const SWITCH = 'SWITCH'; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
npx create-react-app our-app | |
cd our-app |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
npm install --save redux react-redux history redux-pages redux-middlewares |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { | |
createMiddleware, composeMiddleware | |
} from 'redux-middlewares'; | |
import { SWITCH, RESET } from './actions.js'; | |
import { taskPage, relaxPage } from './pages.js'; | |
import { doneSelector, pageSelector } from './selectors.js'; | |
// Switch 'on' or 'off' | |
const switchMiddleware = createMiddleware( | |
SWITCH, // When the SWITCH action is given | |
({ getState, dispatch, nextDispatch, action }) => { | |
nextDispatch(action); | |
switch (pageSelector(getState()).name) { | |
case relaxPage.name: | |
dispatch(taskPage.action()); | |
break; | |
case taskPage.name: | |
dispatch(relaxPage.action()); | |
break; | |
default: | |
break; | |
} | |
} | |
); | |
// Check whether the number of done tasks is one or more, or not | |
const checkDoneTasksMiddleware = createMiddleware( | |
// When the relaxPage action is given | |
({ action }) => relaxPage.check(action), | |
// When the number of done tasks is 0 | |
({ getState }) => doneSelector(getState()) === 0, | |
// Transition to 'on' page | |
({ dispatch }) => dispatch(taskPage.action()) | |
); | |
// Reset the number of done tasks when switch to relax page. | |
const resetDoneTasksMiddleware = createMiddleware( | |
({ action }) => relaxPage.check(action), // When the relaxPage action is given | |
({ dispatch, nextDispatch, action }) => { | |
nextDispatch(action); | |
dispatch({type: RESET}); | |
} | |
); | |
export default composeMiddleware( | |
switchMiddleware, | |
checkDoneTasksMiddleware, | |
resetDoneTasksMiddleware | |
); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { createPages } from 'redux-pages'; | |
// Define pages | |
export const pages = createPages(); | |
export const taskPage = pages.addPage('/on', 'on'); | |
export const relaxPage = pages.addPage('/off', 'off'); | |
export const otherPages = pages.addPage('/*', 'error'); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { combineReducers } from 'redux'; | |
import { createPagesReducer } from 'redux-pages'; | |
import { taskPage } from './pages.js'; | |
import { DONE, RESET } from './actions.js'; | |
// Create a reducer which stores a page to show | |
const pageReducer = createPagesReducer(taskPage.name, {}); | |
// Create a reducer which stores the number of done tasks | |
const doneReducer = (state = 0, action) => { | |
switch (action.type) { | |
case DONE: return state + 1 | |
case RESET: return 0 | |
default: return state | |
} | |
}; | |
// Create the final reducer. | |
const reducer = combineReducers({ | |
page: pageReducer, | |
done: doneReducer | |
}); | |
export default reducer; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import { connect } from 'react-redux'; | |
import { pageSelector } from './selectors.js'; | |
import { taskPage, relaxPage } from './pages.js'; | |
import TaskPage from './TaskPage.js'; | |
import RelaxPage from './RelaxPage.js'; | |
import ErrorPage from './ErrorPage.js'; | |
const mapStateToProps = state => { | |
const page = pageSelector(state); | |
return page; | |
}; | |
const Router = page => { | |
switch (page.name) { | |
case taskPage.name: | |
return <TaskPage />; | |
case relaxPage.name: | |
return <RelaxPage />; | |
default: | |
return <ErrorPage />; | |
} | |
}; | |
export default connect(mapStateToProps)(Router); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Selectors | |
export const pageSelector = ({ page }) => page; | |
export const doneSelector = ({ done }) => done; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { createStore, applyMiddleware } from 'redux'; | |
import createHistory from 'history/createBrowserHistory'; | |
import { pageSelector } from './selectors.js'; | |
import { pages } from './pages.js'; | |
import reducer from './reducer.js'; | |
import middleware from './middleware.js'; | |
// Create a history object | |
const history = createHistory(); | |
// Create a function to get a current path | |
const getCurrentPath = () => history.location.pathname; | |
// Create a function to push a next path | |
const pushPath = (path) => history.push(path); | |
// Create a redux-pages middleware | |
const pagesMiddleware = pages.middleware(pageSelector, getCurrentPath, pushPath); | |
// Create a store | |
const store = createStore( | |
reducer, | |
applyMiddleware(pagesMiddleware, middleware) | |
); | |
// Apply the current path | |
pages.handleNavigation(store, history.location.pathname); | |
// Listen the history updates. | |
history.listen((location, action) => { | |
pages.handleNavigation(store, location.pathname) | |
}); | |
export default store; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment