-
Notifications
You must be signed in to change notification settings - Fork 32
Reducers
A reducer is an entity within the Redux library that focuses on maintaining partial state of the application. It does this by initializing state values, and when incoming actions come through (with payload data), it returns a whole new state according to specific actions (i.e. when an action to set the current FHIR server comes in, it sets the currentFhirServer
property in a new state). Together, reducers make up the store
, which is where data for the Sandbox application is held. One reducer could handle the state for all things relating to FHIR servers, like the fhir-server-reducers.js
file, while another reducer may handle state for all things concerning configured CDS Services, like the cds-services-reducers.js
file. See below for an example of the state properties fhir-server-reducers.js
maintains.
const initialState = {
testFhirServer: null,
currentFhirServer: '',
currentMetadata: null,
defaultFhirServer: 'https://api.hspconsortium.org/cdshooksdstu2/open',
fhirVersion: '1.0.2',
isDefaultFhirServer: true,
accessToken: null,
};
A reducer will simply listens for actions
that come through, and return new state that gets sent to the view components. However, it will only act on specific actions it is interested in, and this is determined by the action type
. See below for an example action that may come through to the reducer.
{
type: 'SET_TEST_FHIR_SERVER',
fhirServer: 'http://example-test-fhir-server.com',
}
When the fhirServerReducer
sees this action come through, it may be interested in setting it's own testFhirServer
property in state. Since all actions come through all reducers, the Sandbox filters actions based on its action types
using switch statements like below.
const fhirServerReducers = (state = initialState, action) => {
switch (action.type) {
case types.SET_TEST_FHIR_SERVER: {
return Object.assign({}, state, {
testFhirServer: action.fhirServer,
});
}
. . .
}
}
Above, we are simply making a copy of the current state object that the reducer holds, and changing the testFhirServer
property to hold the value http://example-test-fhir-server.com
from the action it intercepted, and returning the entire state afterwards. This state then gets emitted to all components who listen for this property in mapStateToProps
and otherwise automatically.
In order for the view components to receive new state automatically when state is changed via reducers (as done above), reducers must be connected to the store. First, reducers are combined together, as seen in src/reducers/index.js
, and together will make up the entire state of the application. Then, in the store file, we simply create the store with the combined reducers. See src/store/store.js
for more details on this.
To add another reducer to the project, first consider if any of the new data/state can be incorporated into any of the existing reducers. If it makes sense to make a new separate reducer for the application, create a reducer file under the src/reducers/
directory. Follow the pattern of the existing reducers to get an idea of how to create the logic behind storing and updating data. Next, import the reducer to the src/reducers/index.js
file to combine it with the other reducers to make the application state. Then you can start to use this data in the view components accordingly. Lastly, make sure to add tests for the reducers under the tests/reducers/
directory.