Search code examples
javascriptreactjsreduxmiddleware

Performing heavy functions on the client and side effects


I have a few heavy functions in the program which, for example, may take some time to complete (<.2s and > 1s). These pure functions, but i do not want to delay the main flow of the application with computing. Where will it be more correct to call it? I thought in mapDispatchToProps, in the selector (output of the function is stored in the store), but again this will all be done synchronously, as I understand. In AC it seems to me to do it wrong, although the function is clean.

  • Now I do it in middleware (computing on the client’s side, but this is not a side effect or what?)

next(action) in the middleware first simply sets a flag at the beginning of the computing, and then calls inside the MW function that returns Promise, when the function has complete, it dispatch data to the store and sets the flag (calculate is done). I feel that this approach is not entirely correct. Any thoughts on that?

  • What if the average function calculation time were > 1s?

The function is CLEAN, and must computing ONLY on the client

Now i call this pure func in middleware

export default (store) => (next) => (action) => {
  const { computeSomeData, type, ...rest } = action

  if (!computeSomeData) return next(action)

  store.dispatch({
    type: type + START,
    ...rest
  })

  someAsyncFunc(computeSomeData)
    .then(
      response => store.dispatch({...})
      error => store.dispatch({...})
  )
}
  • It's correct?

Solution

  • Yes your approach is correct. Middleware ist excatly there place for these side effects. You call an action and update the state asynchronous with the newly computed data after it is done in a none blocking way. So thats best practice. Regarding your mapStateToProps comment. You should keep your state as small as possible and don't keep duplicated data. So if your computed Data is derived from actual data in the store and saving the computed data will create a second source of truth, you should move the calculation into a selector, which is called in mapStateToProps. To prevent unnecessary computations and to prevent lagging, should should memorize the output. For example with reselect or memoize-one. Hope this helps. Happy coding