Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Where's the readme? What is duxtape all about? #1

Open
guillaumearm opened this issue Oct 12, 2016 · 10 comments
Open

Where's the readme? What is duxtape all about? #1

guillaumearm opened this issue Oct 12, 2016 · 10 comments

Comments

@guillaumearm
Copy link

Hi, you may write a readme.md.
same on redux-selectors.

@markerikson
Copy link

To follow on with this: skimmed the repo and I see a ton of code in here. I get a vague idea of what's going on, but would be very interested in seeing a further explanation of what everything's intended to do and how it works.

@brianneisler
Copy link
Owner

brianneisler commented Dec 2, 2016

Hey @guillaumearm and @markerikson. Thanks for opening up this thread and for your interest in this project!

We were holding off on writing a readme since this library is still in the early phases of development and a lot of the API is still taking shape as we experiment with it internally. As things solidify a bit more we will be writing out documentation for each method and how each one works.

That being said, the general concept we are building on is to create a module system for redux. We feel that through the use of frameworks like redux-saga, the entirety of the state and business logic of an application can be built on the redux pattern. While going to that extent is optional there is still a lot of value that shakes out of some of the patterns we're working on.

Here are some of the goals we're working to achieve...

  • Each module should be able tap in to the building process of the state, reducer and enhancer during the redux store creation process through a bottom up assembly process.
  • Modules should be able to use a pattern of hooks to allow other modules to assist in the assembly of the store. e.g. the Enhancers module executes a hook called createEnhancer which allows any modules to implement the 'createEnhancer' hook and return an enhancer that it would like to be included in the composition of the final enhancer plugged in to the redux store. The enhancers module should remain entirely unaware of the other modules that are participating in the createEnhancer hook.
  • Modules can be dependent upon one another but should also be capable of easily being removed without breaking other modules (other than the ones that depend upon it). Effectively this creates a plug and play system where features can be inserted and removed.
  • Once running, each module should be able to tap in to state changes and participate in the runtime of an application similar to the way a React component would. Effectively this creates a headless participant in the app logic. Something we feel is a bit more fitting for core business logic and state management. Further, it opens the door for the use of the common redux/react patterns in applications outside of React (such as command line and server based applications or other UI frameworks beyond React)
  • Each module should be able to rebuild itself on state changes if so desired, allowing for the introduction of dynamic generation of reducers, enhancers and other custom pieces of functionality.
  • Use of recompose style APIs for assembly of modules.
  • Support for hot reload.

I'd love to get some early feedback as we move forward and hear about your own use cases with redux.

@brianneisler brianneisler changed the title write a readme.md What is duxtape all about? Dec 2, 2016
@brianneisler brianneisler changed the title What is duxtape all about? Where's the readme? What is duxtape all about? Dec 2, 2016
@markerikson
Copy link

Yeah, that's what I sorta thought I was seeing. I'm definitely interested in the general idea. FYI, I've got lists of existing libraries that try to implement per-component state or make logic "reusable" as part of my Redux addons catalog, and also have links to a number of articles and discussions about project structure and encapsulation and reusability as part of my React/Redux links list.

As a couple of thoughts/caveats: I've seen a lot of libs that try to put some kind of abstraction layer on top of Redux, but wind up taking it in a very different direction. I've cataloged bunches of them in the variations part of my addons list. The two biggest changes most of these wrappers make are to turn everything into OOP abstractions, where everything is a class (action creators are class methods, etc), and to assume that actions and reducers always have a 1-1 correspondence. Both of those definitely go against how Redux was originally intended to be used.

If you can come up with defining reusable chunks of logic that can be plugged together neatly, while still allowing them to interact with each other, and still generally adhere to idiomatic Redux and its principles, that would definitely be something I'd be interested in.

I'd also be curious to know how components might fit into this, such as a modal dialog that wants to keep its state in Redux while it's open, but also needs to respond to other dispatched actions as well.

@slorber
Copy link

slorber commented Dec 3, 2016

Hi,

This looks interesting but not sure to understand everything :)

Maybe can you submit a solution to https://github.com/slorber/scalable-frontend-with-elm-or-redux so that we can compare your proposal to some other existing solutions?

Modules can be dependent upon one another but should also be capable of easily being removed without breaking other modules (other than the ones that depend upon it). Effectively this creates a plug and play system where features can be inserted and removed.

Have you heard of CQRS in backend systems? It looks a bit like that: you can easily add/reducer a view/projection (that is computed by folding a reducer on a log) without impacting any other existing views, since the log remains the source of truth

Further, it opens the door for the use of the common redux/react patterns in applications outside of React (such as command line and server based applications or other UI frameworks beyond React)

The patterns behind Redux is already used by backend / DB developers for years, however it's not very common, but tends to become more popular because it's very useful with microservice architectures. A good introduction: https://www.confluent.io/blog/turning-the-database-inside-out-with-apache-samza/

and to assume that actions and reducers always have a 1-1 correspondence. Both of those definitely go against how Redux was originally intended to be used.

@markerikson I'd say in most case 1-1 is good but it's not a strict rule. The general idea is that one module should rather avoid listening to actions coming from another module (a "saga" or "epic" should rather handle that coupling), but having 2 reducers in the same module listening to the same action seems a valid usecase for me. Introducing dependencies between modules can work too if your project is not so big but I don't really think having a big file with all your Redux actions is a nice idea.

@markerikson
Copy link

@slorber : don't want to get too off-topic, but a couple quick thoughts:

  • As far as I can see so far, this project is primarily about being able to define independent chunks of Redux-based logic and hook it together in a standardized way at application startup. That may or may not correlate with stuff like the "list of counters" problem, which is at least partly more at the component level.
  • Given that this seems to still be early WIP, I wouldn't expect anything ready to fully show off right away.
  • The "1-1 correspondence" thing is part of the tradeoff in thinking at the component level vs thinking at the app level. For example, my app is based around "projects". The user always has one project open, and while it's open, can do CRUD ops with items in the project. When the user loads a different project, I have multiple slice reducers responding to that action. Old entities are thrown away and new ones loaded, the "current selected item" value is cleared, editing mode is turned off if it was active, etc. So, many different reducers responding to one action. So, the overall point is that it's A) possible, B) an encouraged way to use Redux, and C) something that a lot of wrappers make impossible or try to hide. (Also definitely didn't say anything about having "one big file with all your actions", btw.)

@slorber
Copy link

slorber commented Dec 3, 2016

As far as I can see so far, this project is primarily about being able to define independent chunks of Redux-based logic and hook it together in a standardized way at application startup. That may or may not correlate with stuff like the "list of counters" problem, which is at least partly more at the component level.

I understand that, but I still think it's a valuable challenge to solve for any framework that want to be adopted on real projects. The list of list of pair of newgifs is just an implementation detail of a module, but in my challenge you still can see 3 modules; the gifs stuff, the button and the counter.

The "1-1 correspondence" thing is part of the tradeoff in thinking at the component level vs thinking at the app level.

I think we probably agree on this. If you have a reducer for a module, it doesn't matter much if you decide to split it into multiple "subreducers" and use combineReducer on it IMHO, it's still a reducer, and the subreducers are just implementation details of that reducer, so using a module action in many module subreducers is perfectly fine as long as the action does not leak outside the module. (even if it leaks it's not a big deal we are not in a perfect world)

@brianneisler
Copy link
Owner

@markerikson wow! Thanks for the links. You've really put together some amazing resources and clearly spent a lot of time researching redux. I think I have enough new reading material to last me a couple months now ;)

In a lot of ways, I think the various approaches to building an application with redux may be more of a matter of preference or use case and that there may not be "one right way". Not to exclude the idea of best practices but different use cases may call for different approaches. In that vein I'm hoping to maintain a fair amount of flexibility with this project to help support a number of ways of assembling redux modules. This may even allow for different styles of modules to interoperate.

I've seen a lot of libs that try to put some kind of abstraction layer on top of Redux, but wind up taking it in a very different direction. I've cataloged bunches of them in the variations part of my addons list. The two biggest changes most of these wrappers make are to turn everything into OOP abstractions, where everything is a class (action creators are class methods, etc)

I have noticed the same but feel this goes against the functional nature of redux. This is part of the reason we have opted for a recompose style approach of building modules. This functional approach seems to lend itself better to the assembly of modules where it may need access to parts of the state outside of its own space. It also makes it easy to incorporate actions from other systems if the core logic needs to dispatch them for whatever reason.

and to assume that actions and reducers always have a 1-1 correspondence. Both of those definitely go against how Redux was originally intended to be used.

Agreed, I have certainly found scenarios where it was easier to have multiple reducers reduce the same action or have a reducer reduce multiple actions for some state value. From a modular perspective it also makes sense to me that a child module may not have control over the action being dispatched by some 3rd party parent module. However, that child may still want to reduce some state value or execute some business logic when that action is dispatched by the parent.

If you can come up with defining reusable chunks of logic that can be plugged together neatly, while still allowing them to interact with each other, and still generally adhere to idiomatic Redux and its principles, that would definitely be something I'd be interested in.

That's the general idea :)

I'd also be curious to know how components might fit into this, such as a modal dialog that wants to keep its state in Redux while it's open, but also needs to respond to other dispatched actions as well.

Hmm, this is a good question. Our initial efforts have been around trying to cleanly separate the component and module logic so that the core of the business logic can live separately from UI logic. However, you are right that there are many scenarios where redux and component state/logic are intertwined. Another example that comes to mind is forms, where you may want to keep some form state in redux (such as form input). Perhaps the solution here is that a module would be written to manage the state and business logic in a headless way. The UI would then connect to state in whatever way it needs through some known "key" (such as form name, modal name, etc)

@markerikson
Copy link

Nice. I think there's definitely value in coming up with some sort of reusability story for Redux-related logic. The most common approach I've seen so far is generally a library providing its own reducer function and expecting it to be added to the store at a pre-known key, which is easy to handle but not really flexible.

I appreciate that your thoughts are more closely in tune with what Dan (and I) would consider to be "idiomatic Redux", and I'll be keeping an eye on this library as you put it together. Definitely looking forward to seeing what you come up with!

@markerikson
Copy link

Hiya. It's been a few months since the last commit. Still got plans to work on this? (No hurry, just curious where things stand over here.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants
@slorber @markerikson @brianneisler @guillaumearm and others