-
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
lib
files - 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-redux
libraries
- Install
-
- Reorganize and update directory structure for Redux
-
- Set up routes, Root component, store, and root reducer
-
- Refactor
FullApp
andSlimApp
as 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.jsx
tosrc/components/LandingPage.js
and update imports - Move
src/apps/FullApp.jsx
tosrc/containers/FullApp.js
and update imports - Move
src/apps/SlimApp.jsx
tosrc/containers/SlimApp.js
and 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.jsx
tosrc/components/WithTracker.js
- Create
src/routes.js
file to handle routes (see example below) - Update
src/index.js
file to use new Root component (see example below) - Move any props from
src/apps/AppManager.jsx
into appropriateFullApp
orSlimApp
container and update imports - Update any remaining imports and verify routing works and all tests pass
- Delete
src/Apps.jsx
andsrc/routes.js
files - 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.js
to 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
, andmapDispatchToProps
and hook up to new redux store usingconnect
- Step 2 - Move any corresponding stylesheets into
/styles
folder 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
/utils
folder 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
/components
folder and update imports - Step 2 - Move any corresponding stylesheets into
/styles
folder and update imports - Step 3 - Move any corresponding utils in
/utils
folder 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
/utils
folder 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
, andProgressionForm
in 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)