Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redux: where to place interaction with the DOM, that is triggered by an action but changes outside of the React app

I have a React/Redux app that takes care of a interactive list of items for a real time selling (auctions). My <div id='app'></div> only takes care of the list.

The problem is when and item is sold, I need to add it to another list, which is not inside the React app. Since the list is rendered on the server, and the only interaction needed for it is to add those sold items.

Right now I'm doing something like this

// redux thunk action
export const sellItem = (item) => (dispatch) => {
  dispatch(requestSellItem(item)); // set loading state

  return fetch('api/sell_item/' + item.id)
    .then(response => response.json())
    .then(json => {
      // remove the item from the React list
      dispatch(sellItemSuccess(item.id));
      // append the item to the sold items list
      // this is the function that puts the sold item in the 
      // list outside of the React app
      appendSoldItem(item);
    })
    .catch(err => {
      // do fallback here
      dispatch(sellItemError(err));
    });
};

I wonder if that is the right place to do it or should I place it somewhere else?

like image 931
Christian Gill Avatar asked Nov 09 '22 13:11

Christian Gill


1 Answers

If you don't envision a scenario where it is possible to sell items without "adding the item to another list", then this is perfectly acceptable. If not, you may want to decouple the act of selling an item from notifying the external service.

In any case, since we are dealing with an external service, I'd say this is a perfect example for a middleware layer. Here's an example:

import { ITEM_SOLD_SUCCESS } from ... // Import same action created by sellItemSuccess()

let itemSoldNotifier = store => next => action => {
  if (action.type === ITEM_SOLD_SUCCESS) {
    // Notify the external service that the item was sold
    appendSoldItem(action.item); // Assuming that the action contains the item sold itself
  }
  return next(action);
}

And here's how to apply that layer in the store:

let store = createStore(
  combineReducers(reducers),
  applyMiddleware(
    itemSoldNotifier
  )
)
like image 159
Ashitaka Avatar answered Nov 14 '22 22:11

Ashitaka