CharlesStover/reactn

Can property reducers be added to the global state?

dalborgo opened this issue · 2 comments

This is my main file:

import React, { createProvider } from 'reactn'

import { Prova } from './components'

const INITIAL_STATE = {
  n: 0
}
const Provider = createProvider(INITIAL_STATE)

Provider.addReducers({
  increment: (n, x = 1) => n+x
})

function App () {
  return <Provider>
    <Prova/>
  </Provider>
}

export default App

I want use the useDispatch two arguments signature with the addReducers helpers.

I tried this but doesn't work (I get "TypeError: can't convert n to primitive type"):

const dispatch = useDispatch()
const increment = useDispatch(dispatch.increment, 'n')

Using the function directly it works properly:

const increment = useDispatch((n, x = 1) => n+x, 'n')

Thanks for the help.

Thank you for your feedback. This is a great observation and a great topic of discussion.

Unfortunately at this time, addReducers only supports global reducers -- reducers that return a manipulation of the global state as a whole. Property reducers are only usable by passing them to useDispatch directly.

There are some technical reasons this is the case:

  • JavaScript has difficult determining whether or not your reducer is global or a property reducer when it is added. As a result, the dispatcher (the function that ties your reducer to the global state) cannot be accurately generated, because it does not know what parameters your reducer expects.
    • This can be alleviated by generating the dispatcher at the component level instead of the global state level, but generating it so frequently and repeatedly will be a performance trade-off.
  • Error handling will need to occur for when you attempt to use a global reducer with a property or a property reducer without a property.

For the time being, as a workaround, the simplest way to implement this would be to define increment in a file and import it from that file instead of from ReactN. useDispatch(importedIncrementFunction, 'n')

Sorry for the inconvenience.

If this feature is important to you, I can keep this issue open as a feature request. I am on the fence about considering it a breaking change worthy of cutting a 3.0 release for addReducer, addPropertyReducer, useDispatch, and usePropertyDispatch for the sake of simplicity over inference, but the aforementioned component-level dispatcher generation may also be an acceptable implementation that I would consider before making any rushed decisions.

Thanks for bringing this up. I look forward for further feedback.

Thank you for the explanation. I decided to open this issue to discover if I miss something about javascript and to listen an expert opinion. Thanks.