Skip to content

Adding Actions to the Host Context

Alex Younger edited this page Apr 2, 2021 · 2 revisions

Adding Actions to the Host Context

To add actions to the host context there are two files you may need to edit depending on if you need to execute side effects, change the application state, or both.

Executing side effects with your action

  1. open frontend/src/contexts/HostContext/hostReducerMiddleware.js
  2. add a case to the switch, with the case type matching the type your dispatch function will send
  3. define a function before the exported function to perform the side effect you need to perform
  4. in your case call your new function and add a break on the next line (or a return if you need to make sure that your action doesn't reach the hostReducer)

Example

If the dispatch in your component looks like: dispatch({ type: 'FOO_FIGHTER', payload: { playerId: 'Dave' } }) and it needs to send a message, your addition to hostReducerMiddleware should look something like:

// before hostReducerMiddleware is declared

function sendFooFightingMessage(payload) {
 //foo fighting functionality goes here
}

...

// in the switch 

case 'FOO_FIGHTER':
  sendFooFightingMessage(payload);
  break;

Using asynchronous fetched data to update application state

  1. open frontend/src/contexts/HostContext/hostReducerMiddleware.js
  2. add a case to the switch, with the case type matching the type your dispatch function will send
  3. define an async function before the exported function to fetch and return the data
  4. in your case, add brackets to allow for instantiating new variables.
  5. declare a new variable to await the return value of your async fetching function
  6. return the dispatch call with the data in the payload. You must return the dispatch so that it doesn't fall through and fire twice

Example

// before hostReducer is declared

async function getSomeTastyData() {
  const deliciousData = await fetch('https://yummydata.gov/query?type=deep_fried');
  return deliciousData;
}

...
// in the switch
case 'SET_TASTY_STATE': {
   const data = await getSomeTastyData();
   return dispatch({
      type: 'SET_TASTY_STATE',
      payload: { data },
    });
  }

Updating application state with your action

  1. open frontend/src/contexts/HostContext/HostReducer.js
  2. add a case to the switch, with the case type matching the type your dispatch function will send
  3. define a function before the exported function to perform the state update you need to perform
  4. in your case return the output of calling you new function

Example

If the dispatch in your component looks like: dispatch({ type: 'FOO_FIGHTER', payload: { playerId: 'Dave' } }) and it needs update the state, your addition to hostReducerMiddleware should look something like:

// before HostReducer is declared

function fightTheFoos(state, { playerId }) {
 //foo fighting functionality goes here
}

...

// in the switch 

case 'FOO_FIGHTER':
  return fightTheFoos(state, payload);

If you need to cause a side effect or retrieve API data and update state you will need to do both of the above

Why you need to add actions to the host context like this

During development bug #167 was discovered. The cause was determined to be that the useReducer hook being used was causing the dispatch to be processed a second time when the host context re-rendered.

The solution involved moving the processing of side effects into an asynchronous function (hostReducerMiddleware) that was separate from the state updating function (HostReducer) and having dispatches flow through the side effect function and into the state updating function.