mattkrick / meatier

:hamburger: like meteor, but meatier :hamburger:

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Integrate react-redux-provide

sompylasar opened this issue · comments

From the initial look at the react-redux-provide is seems to me that a large redevelopment would be needed; furthermore another thing that is apparent is counter-ideology to the nature of redux by creation of more than one store. The structuring is also much different than the currently preferred redux so it seems that while it aims to alleviate the js fatigue, it will in the end add to it. While I'll be looking into it I'd say that currently the divergence between how things are done in react-redux community and this new way are much too broad to simply jump in without having a deeper understanding of all the pros and cons. However if you would like to go over the benefits in contract to meatier, and tackle the initial outline of the scope of action to take in the conversion, by all means do proceed.

@bartekus thanks for digging into this, I was having trouble grokking this from the readme. I'm still thinking that a memorized reducer extended is the way to handle shared client server data and then allowing for vanilla redux api for local state, but im open

The core benefit is modularity, not only in React components, but in Redux logic. For large apps this is crucial, and Redux currently does not offer a solid solution.

The real-world problems are outlined in detail here: reduxjs/react-redux#278

@sompylasar maybe i'm not understanding the problem. Primarily, we're talking about instantiating multiple instances of a reducer, eg 3 identical counters with different state, right? Have you checked out https://github.com/erikras/multireducer? If there's something else I'm missing let me know, bonus points for real world examples!

Multireducer requires design-time structure of the app state with static reducer identifiers. In a large multi-component app there can be a requirement to instantiate "counters" (components) dynamically, each with its own startup options, own state controlled by a set of reducers, and actions targeted specifically at each instance, so that's not just React component reuse, but the whole ( view + state logic ) reuse.

Right, redux-form is the only component I know which provides reusable reducers. The reducer logic can be customized ( http://erikras.github.io/redux-form/#/api/reducer/normalize , http://erikras.github.io/redux-form/#/api/reducer/plugin ), but the customizations for each form should be written upfront, and passed during the app state construction -- they cannot be added dynamically without extra hacking, for example, if the form itself gets code-splitted away.

so assuming we've got a huge app & we piggyback on a bunch of form actions so we want to code-split those piggybacked reducers (eg the login function in that redux form plugin example). I could just say login: () => require('asyncModule'), right?

Sure, you could, but 1) you'll have to make it asynchronously, and this is a side-effect which must not be in a reducer, and 2) the "login:" has to be there always. Imagine you've got "login-abc", "login-def", "login-ghi" etc. dynamically generated forms, having these "abc", "def", "ghi" identifiers retrieved from a database in run time (actually, I've got other kind of components in mind, but forms will do for this example).

gotcha... so I think the underlying problem is currently redux has a global state (good!) and a global reducer (bad!). What'd be fun to play around with is doing away with reducers & replacing it with an API. For example, creating a store or adding a reducer gives you a store.actions.increase = [{fn1, 'counter1'}, {fn2, 'counter2'}]. The result of calling fn1 on counter1 is passed to counter2, etc, same as compose or a reduce function works. In doing so, you don't have to trust a 3rd party reducer because that reducer will only be called when needed. You can spec out an API description, etc similar to what GraphQL does right now, you have a predictable execution order (that you could declare), and you know who calls what. This would make debugging really easy, solve the problem you mentioned, plus the one here reduxjs/redux#1315 (comment).

Yes, global state is good, but the hardcoded structure is not so good in complex reuse cases. Of course, it should be hardcoded to certain extent to be testable, but it should be extendable and partially reusable. And yes, the Bounded Contexts concept of DDD, as well as Sagas, is definitely related.

I failed to understand this part of your comment:

For example, creating a store or adding a reducer gives you a store.actions.increase = [{fn1, 'counter1'}, {fn2, 'counter2'}]. The result of calling fn1 on counter1 is passed to counter2, etc, same as compose or a reduce function works. In doing so, you don't have to trust a 3rd party reducer because that reducer will only be called when needed.

The most clever idea I have seen for now remains the one with "provide".

i'll carve out some time & submit something on the redux repo over the next week or 2.

👍 thanks for your input!