-
Notifications
You must be signed in to change notification settings - Fork 46
Subscribing to state changes #36
Comments
I think you can you do that with |
@xcoderzach From the documentation, with middleware, you can change state and decorate effects to add new functionality. I couldn't see how this might be used to subscribe to change states though. However, I am now seeing from the source code and by inspecting the freactal context passed in the middleware function, that the context exposes a This function isn't documented though. Is this what you were referring to? Edit: Well not exactly what I was looking for. Based on how the middleware function currently works, it is called on every state change, which means I add a new subscription function for every state change. I can work around this by creating a variable that tracks whether I have already added the subscription, to ensure it is only added the first time a state changes , but this does seem a bit hacky. So I am unsure I am using the API as it was intended. See this related issue: #33 |
@dannief Middleware fires every time state changes, so it should be possible with middleware (as @xcoderzack suggests). I think you would have to be responsible for detecting what state had changed within the middleware. The internals of |
That would also be a criteria for us without which we couldn't use it. We have generic classes reacting on state changes, executing actions, etc. Middleware isn't good enough and makes it very restrictive. It needs a simple getState/subscribe functionality. This will allow it to be used without components or in all frameworks and circumstances. |
@drcmda, can you explain more fully what you need? Freactal is designed to be used through its higher-order components, and it is unlikely that we'll expose lower-level APIs for subscribing to state changes. However, if I could better understand the use cases you have in mind, we might be able to find a good solution, and I may change my mind if your use case is compelling :) |
@dannief, the middleware is probably the piece I thought through the least. Definitely open to improvement here. Right now, middleware is a function of signature |
You could create a react component that handles this. import React, { Component, Children } from 'react';
import { injectState } from 'freactal';
const SyncronizeTodos = injectState(
class TodoSyncer extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
// Subscribe to things
}
componentWillReceiveProps({ state }) {
// Do something whenever local state changes
}
componentWillUnmount() {
// Unsubscribe from things
}
render() {
return this.props.children ? Children.only(this.props.children) : null;
}
}
);
export default SyncronizeTodos; While this component is mounted in the tree it will syncronize stuff for you. Component all the things! [INSERT MEME HERE] |
I hadn't thought about it when I first looked at freactal, but it seems like the missing piece here is almost something like MobX's autorun: https://mobx.js.org/refguide/autorun.html |
@divmain Could you elaborate a little on your thoughts for changing the signature of the middleware function? If the middleware function returns a function that is executed on state changes, does this mean that you would (1) execute the top level middleware function once, and (2), store the resultant function to be executed on state changes?. Also, would the Edit: I think the trouble I am having is, with the exception of needing to modify the state in a global way after every state change, I can't think of reason you would want to modify the effects or subscribe in a similar way. What I mean is, I am thinking the middleware function need only be executed once, to add subscriptions and wrap effects with other functionality. The only reason to return another function from the middleware function would be to register state changes. Or am I missing something? @nbostrom That works. I actually like that pattern, though It may not be ideal for all use cases. |
@dannief, middleware can also transform the Your summary of my thoughts is accurate. The outer function would be invoked once on provider construction. The inner/returned function would be invoked on every state change, much like the middleware behaves right now. This approach could also be used to solve #43. |
Since you can store anything in a state hash, couldn't you store a mobX observable in it and begin watching it in initialize? |
that being said - a parameter in the middleware that told us what changed since the last cycle could allow us to write much more effective middleware. |
I am wondering if there is a plan to add a subscription or side effects api. The use case would be to execute functions on state change outside of component rendering. Example: syncing with local storage.
The text was updated successfully, but these errors were encountered: