-
Notifications
You must be signed in to change notification settings - Fork 19
Redux Implementation Guide
The purpose of this guide is to create a living document for conversion of Flux Notes from React to React+Redux.
Redux Architecture Chart (as of 2017.12.14)
- What to do with all the data models and classes - should we convert them to prop types?
- What to do with
libfiles - should they be separated or included in the app?
The following tasks will need to be performed to successfully refactor Flux Notes to use Redux.
-
- Install
redux, andreact-reduxlibraries
- Install
-
- Reorganize and update directory structure for Redux
-
- Set up routes, Root component, store, and root reducer
-
- Refactor
FullAppandSlimAppas Redux containers
- Refactor
-
- Refactor remaining app files by recommended group below
$ yarn add --save redux react-redux
Since Redux is just a data store library, it has no direct opinion on how your project should be structured. However, most Redux developers tend to the following pattern.
- Create the following folders under
src/:actions,components,containers,reducers,styles,store, andutils - Move
src/apps/LandingPage.jsxtosrc/components/LandingPage.jsand update imports - Move
src/apps/FullApp.jsxtosrc/containers/FullApp.jsand update imports - Move
src/apps/SlimApp.jsxtosrc/containers/SlimApp.jsand update imports
src/
├── actions/
├── components/
| ├── LandingPage.js
| └── Root.js (create in step 3)
├── containers/
| ├── FullApp.js
| └── SlimApp.js
├── reducers/
| └── index.js (create in step 3)
├── styles/
| └── app.scss
├── store/
| └── configureStore.js
├── utils/
| └── tbd.js
├── routes.js (create in step 3)
└── index.js
- Move
src/analyticsTracker/WithTracker.jsxtosrc/components/WithTracker.js - Create
src/routes.jsfile to handle routes (see example below) - Update
src/index.jsfile to use new Root component (see example below) - Move any props from
src/apps/AppManager.jsxinto appropriateFullApporSlimAppcontainer and update imports - Update any remaining imports and verify routing works and all tests pass
- Delete
src/Apps.jsxandsrc/routes.jsfiles - Add
redux-promise-middleware(to handle middleware),redux-thunk(to handle async actions), andredux-logger(to handle logging) libraries - Implement
src/store/configureStore.js(see example below - uses Redux DevTools) - Create
src/reducers/index.jsto set up root reducer (see example below)
Example routes.js:
import React from 'react';
import { Route } from 'react-router';
import WithTracker from './components/WithTracker';
import App from './components/App';
import LandingPage from './components/LandingPage';
import FullApp from './containers/FullApp';
import SlimApp from './containers/SlimApp';
export default (
<Route component={App}>
<Route exact path="/" component={WithTracker(LandingPage)} />
<Route path="/patient" component={WithTracker(FullApp)} />
<Route path="/patina" component={WithTracker(SlimApp)} />
</Route>
);Example srcs/index.js:
import 'babel-polyfill';
import React from 'react';
import { render } from 'react-dom';
import Root from './components/Root';
import configureStore from './store/configureStore';
import './styles/app.scss';
const store = configureStore();
window.store = store;
render(
<Root store={store} />,
document.getElementById('root')
);Example src/store/configureStore.js:
import { createStore, applyMiddleware, compose } from 'redux';
import promiseMiddleware from 'redux-promise-middleware';
import thunkMiddleware from 'redux-thunk';
import logger from 'redux-logger';
import rootReducer from '../reducers';
export default function configureStore(initialState) {
let middleware = applyMiddleware(
promiseMiddleware(),
thunkMiddleware,
logger()
);
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
let store = createStore(rootReducer, initialState, composeEnhancers(middleware));
return store;
}Example src/reducers/index.js:
import { combineReducers } from 'redux';
import { routerReducer } from 'react-router-redux';
const rootReducer = combineReducers({
routing: routerReducer
// additional reducers added here
});
export default rootReducer;For each container:
- Step 1 - Define
mapStateToProps, andmapDispatchToPropsand hook up to new redux store usingconnect - Step 2 - Move any corresponding stylesheets into
/stylesfolder and update imports - Step 3 - Move any pieces of state that aren't component-specific to the redux store and pass in
- Step 4 - Move any functions that aren't component-specific to the
/utilsfolder and import - Step 5 - Refactor any data flow logic to be an action and pass in
Recommend refactoring features in groups of related components:
- Group 1:
LandingPage - Group 2:
NavBar,FormList,ShortcutViewer,LandingPageForm - Group 3:
DashboardViewManager - Group 4:
PatientControlPanel,SummaryHeader - Group 5:
PreEncounterView,PostEncounterView,EncounterView - Group 6:
NotesPanel - Group 7:
FluxNotesEditor,ContextPortal,ContextItem,EditorToolbar,StructuredFieldPlugin - Group 8:
NoteAssistant,ContextTray,TemplateForm,ContextOptions - Group 9:
TargetedDataPanel - Group 10:
TargetedDataSubpanel - Group 11:
TabularNameValuePairsVisualizer,NarrativeNameValuePairsVisualizer - Group 12:
TimelineEventsVisualizer,TimelineLegend,HoverItem,Item - Group 13:
TargetedDataControl,ConditionSelection,ClinicalEventSelection - Group 14:
Minimap,SlateSuggestionsDist(lib)
For each group, perform the following steps to refactor to use Redux:
- Step 1 - Move component into
/componentsfolder and update imports - Step 2 - Move any corresponding stylesheets into
/stylesfolder and update imports - Step 3 - Move any corresponding utils in
/utilsfolder and update imports - Step 4 - Move any pieces of state that aren't component-specific to the redux store and pass in
- Step 5 - Move any functions that aren't component-specific to the
/utilsfolder and import - Step 6 - Refactor any data flow logic to be an action and pass in
Recommend evaluating use of the following components which don't appear in the redux architecture:
-
ClinicalTrialForm(used inShortcuts.json) -
DataCaptureForm(not used) -
DeceasedForm(used inShortcuts.json) -
FormSearch(not used) -
ProgressionForm(used inShortcuts.json) -
StagingForm(used inShortcuts.json) -
ToxicityForm(used inShortcuts.json) -
DatePicker(used inClinicalTrialForm,DeceasedForm, andProgressionFormin this list)
Copyright © 2017 The MITRE Corporation | Approved for Public Release; Distribution Unlimited. Case Number 16‑1988
- Home
- About Flux Notes
- Active Treatment Summary Objects
- Data Standards for Breast Cancer
- Database decision
- Declarative Shortcut Format
- Demo Script
- Deployment Plan - Lite Mode
- Dragon Software Information and Troubleshooting
- Flux Notes Lite Demo Script
- How To Create New Shortcuts
- Interaction Between REACT.js Components in Flux
- JavaScript and HTML Code Style Guide
- Key Application Features
- Minimap Evaluation
- Naming Convention for Visual Components
- NLP Server: Provisioning and Troubleshooting
- Pre Release Testing Script
- Profiling and Performance
- Redux Implementation Guide
- Shorthand Context Problem
- Testing
- Third Party Libraries Changes
- Demo Scenarios -- (out of date)