Skip to content

Instantly share code, notes, and snippets.

@ryo33
Last active July 12, 2018 02:38
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 ryo33/e9025aff382554171f09ee4ec58ba45e to your computer and use it in GitHub Desktop.
Save ryo33/e9025aff382554171f09ee4ec58ba45e to your computer and use it in GitHub Desktop.
redux-pages
// 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';
npx create-react-app our-app
cd our-app
npm install --save redux react-redux history redux-pages redux-middlewares
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
);
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');
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;
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);
// Selectors
export const pageSelector = ({ page }) => page;
export const doneSelector = ({ done }) => done;
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