-
Notifications
You must be signed in to change notification settings - Fork 11
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
API of Middleware #51
Comments
Despite the name, ReduxFX is not an attempt to simply reimplement Redux for JavaFX. (Well, maybe it started that way...) :) I have looked at several frameworks that enable FRP for UI-development (mostly Elm, Cycle.js, and Redux) while designing ReduxFX, therefore it has become a mixture of different approaches. I.e. there is no original API that one can stay close to or not. Redux does a lot things right, but the concept of thunks is one of the few I do not like. I did not plan to implement them and I am afraid I did not even consider them while designing ReduxFX. I am not really opposed to the idea of supporting them in ReduxFX and I can see their value when used in small applications with only few concurrent tasks. At this point ReduxFX does not really have a store. Instead the main functionality is implemented through a couple of reactive streams. What you already can do is to listen to state-changes by subscribing to the Publisher that is returned from ReduxFX.getStatePublisher(). I guess all we need is a small adapter that subscribes to this publisher and caches the last value. I wonder if this adapter should be integrated into the class ReduxFX or if this is something the thunk-middleware should do. So far the API of the ReduxFX class is mostly based on reactive streams. The adapter implements a paradigm shift, therefore I am reluctant to add it to the class. On the other hand, if this functionality is needed in several places, it would make sense to have it in a central place. Hmmm... My suggestion is, that we leave it out of the ReduxFX class for now and wait to see how often it is needed. Instead we can add a separate component, that implements the adapter. What do you think? |
Yes, I think my confusion comes from the name of the library. I'm totally ok with not reimplementing redux but using inspiration from other good libraries. However, then the name is indeed a little misleading, especially when terms like "middleware" are used but don't work like the "original redux" variants. On the other hand the term "middleware" is not redux specific but is used in many different contects so I think it's ok. It's not my goal to have a thunk-middleware. I don't really "need" a thunk-middleware. I'm ok using another mechanism that allows me to create side-effects in a controlled way. If I understand your code and docs correctly this is done with the "Drivers"? I've seen the HttpDriver but I wonder how to do arbitrary side-effects other then http requests? Do I have to implement my own driver for this? However, I think a good extension mechanism would be cool for the library. Thunk-middleware is not the only interesting middleware. For me it's not important that it works the same way with the same API as redux.js but it would be cool to have similar possibilities. My starting point was to implement a Redux-Devtool for JavaFX (which is also the reason for my recent PullRequests ;-) ). However, I had a hard time to get this working with the Reactive-Streams implementation of ReduxFX. So my approach for now is the same as with the fxml: Use a simple redux-clone for the first prototype to see what API is needed and then port it back to ReduxFX. |
I'd love to be able to use a Redux-Devtool for JavaFX. It should not be too hard IMO, at least when it comes to the core functionality. Luckily most of the complex stuff is already solved in RxJava. What would we need to implement a Devtool for ReduxFX? I'd by happy to add the required hooks. |
I have a first prototype here: https://github.com/lestard/redux-javafx-devtool I need to be notified when an action is dispatched and when a new state is produced. I'm trying out how to do this with reduxfx-store now. The state view already works but I don't know how to get notified when actions are dispatched. The next step is to find out how to implement time-traveling. For this most likely we need other interactions with the redux-library like replacing the state. |
I've updated the devtool. It now also supports time-traveling. You can try it out with this example application. I've introduced an interface that defines the connection between the redux-library and the dev-tool. We would need to create an implementation of this interface for reduxfx. I've also prepared the class for this here. |
I have to admit I am stuck here, because I am still struggling to understand the original design of Redux. I guess the problem boils down to this: The dispatching mechanism is defined as an asynchronous feature. Or to use the official definition:
But a lot of code (including for example the redux-logger, but also the JvmReduxDevToolConnector) treat dispatch as if it was a synchronous call. From JvmReduxDevToolConnector: final Object result = store.dispatch(action);
final STATE newState = store.getState(); My question is, how can you be sure that newState contains the state after the action was dispatched, if the store "may or may not dispatch one or more actions"? What am I missing? |
In redux by default the dispatching is synchronous (see here for reference). Only if you add a middleware that "understands" some sort of asynchronous actions it can become asynchronous. Middlewares compose/wrap the original dispatch method but in the end the original dispatch method has be invoked. The code you mentioned is from the original dispatch method of the store. When this code runs I can't know if there there is still another asynchronous operation running. But it doesn't matter because I know that this operation has to use the original dispatch method to get it's result to the store and then I can intercept it. Interesting is this sentence in the redux docs: "When the last middleware in the chain dispatches an action, it has to be a plain object. This is when the synchronous Redux data flow takes place." |
I have created a pull request with a connector for ReduxFX. To my own surprise no changes in ReduxFX were required. But I got some ideas how the ReduxFX-store could be made more extensible, which would make it easier to integrate tools like the devtool. |
Hi,
I'm having problems understanding the API of the middleware in reduxfx.
In the original redux API a middleware "is a higher-order function that composes a dispatch function to return a new dispatch function." redux docs.
Additionally the constructor of a middleware has also access to the
getState
function.Also see the detailed API description of applyMiddleware.
In reduxfx on the other hand the middleware operates with the Reducer/Updater function. It takes a reducer as argument and returns an enhanced reducer.
If I like to implement, for example, a thunk-middleware, I need access to the getState method because Thunk-Actions have to be able to decide which async actions to dispatch based on the current state. As far as I can see this isn't possible with the current reduxfx middleware API?
In my opinion it would be a good idea to stay as close to the original redux API as possible. But maybe I've overlooked something? Can you describe your ideas and your reasoning behind the current API?
At the moment I'm playing around with the reduxfx code to get this working but it takes some time because I'm not familiar with the reactivex API (yet).
The text was updated successfully, but these errors were encountered: