You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm creating a TodoList example app using Flux. Right now I have three components: TodoListApp, TodoItems and AddItem. TodoListApp is simply a NavigatorIOS component which shows TodoItems by default and a method to push the AddItem page to the navigator stack when the user taps the '+' button.
My question is: is there a way for my AddItem component (child of NavigatorIOS) to handle the onRightButtonPress event? Right now I've had to put in a bunch of hacks to accommodate adding a todo item when the user taps the 'Save' button from the AddItem page.
My thoughts exactly. I'm trying to give it the exact same functionality as the iOS demo app you build in the first tutorial. Except the tutorial for this will be about 1/10th the length ;-)
@nick I've got a similar issue - I need to be notified that a "back" happened #26. I'm currently hacking around it by having the NavigatorIOS children call a prop callback on componentWillUnmount.
Currently the best way to do that is to create an EventEmitter in the owner of the NavigatorIOS, then you can pass it down to children using route.passProps. The child can mix in Subscribable.Mixin and then in componentDidMount, you can this.addListenerOn(this.props.events, 'myRightBtnEvent', this._handleRightBtnPress);
It is clear that this API needs improvement. We are actively working the routing API in Relay, and hopefully react-router, but we want NavigatorIOS to be usable independently. Maybe we should add an event emitter inside the navigator object, so child components can subscribe to various navigator activity: this.addListenerOn(this.props.navigator.events, 'rightButtonPress', this._handleRightBtnPress);
That last api looks good to me. In the meanwhile I'll try your suggestion. Can't wait to see what @ryanflorence and @mjackson do with support in react-router! Already using it in all my other projects.
Subscribable.Mixin is something we use internally to make sure nobody forgets to unsubscribe to an emitter from a component on unmount. The mixin will automatically remove subscriptions added with this.addListenerOn. We are currently phasing it out, though, because we will be transitioning to observables in an upcoming version of React.
@Teebolt
I agree with you, because I met a new problem when I trying to use Flux:
I created a TodoItems app too, When I succeeded in pushing a notification to the child component, and the child component will save the new item to the db, after this, the child component will push another notification to the list component for reload the list, the problem is, there are two dispatches in this process and it will cause a error: Invariant Violation: Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch.
In my main file (index.io.js) I created a new event emitter outside of the class: var rightButtonHandler = new EventEmitter();
Then, inside the class I created a method to be called when the button is pressed: handleSaveButton() { rightButtonHandler.emitEvent('saveButtonPressed'); }
And right below that I am passing the event emitter as a property to the sub-component: passProps: { events: rightButtonHandler }
Now, switching to the sub-component class, add this or update your componentDidMount method: componentDidMount() { this.props.events.addListener('saveButtonPressed', this.saveConcert.bind(this)); }
The above will be calling this saveConcert: saveConcert() { /// This is now called when the navigatorIOS right button is pressed. }
Hope this helps!
shiyuanhai, Nermine1, onimushapooh, touchapp, Polidoro and 2 moredangbh1002-org
@Teebolt
Thank you very much, it works.
But if you want to start another dispatch in a listener that is triggered by emitChange() of a Store, you will get the same error like I said above: Invariant Violation: Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch.
@ericvicenti I tried the approach you mentioned in one of the replies, thanks for the detailed explanation. Just wanted to check if the same holds true now or is there another way of solving it in a better way. If so could you please help me out with that.
These days I would just go with a redux-style control flow, but its not too easy to pass props down into the inside of NavigatorIOS scenes. But it can probably be done with a redux provider, and that would be a much cleaner solution
Activity
nick commentedon Feb 2, 2015
btw I'd love to contribute this example to the official repo once it's done :-)
vjeux commentedon Feb 2, 2015
You are right, we need to have a todo app example otherwise we're not a real js lib :p
nick commentedon Feb 2, 2015
My thoughts exactly. I'm trying to give it the exact same functionality as the iOS demo app you build in the first tutorial. Except the tutorial for this will be about 1/10th the length ;-)
zertosh commentedon Feb 2, 2015
@nick I've got a similar issue - I need to be notified that a "back" happened #26. I'm currently hacking around it by having the
NavigatorIOS
children call a prop callback oncomponentWillUnmount
.ericvicenti commentedon Feb 3, 2015
Currently the best way to do that is to create an
EventEmitter
in the owner of theNavigatorIOS
, then you can pass it down to children usingroute.passProps
. The child can mix inSubscribable.Mixin
and then incomponentDidMount
, you canthis.addListenerOn(this.props.events, 'myRightBtnEvent', this._handleRightBtnPress);
It is clear that this API needs improvement. We are actively working the routing API in Relay, and hopefully react-router, but we want NavigatorIOS to be usable independently. Maybe we should add an event emitter inside the
navigator
object, so child components can subscribe to various navigator activity:this.addListenerOn(this.props.navigator.events, 'rightButtonPress', this._handleRightBtnPress);
Feedback welcome!
nick commentedon Feb 3, 2015
That last api looks good to me. In the meanwhile I'll try your suggestion. Can't wait to see what @ryanflorence and @mjackson do with support in react-router! Already using it in all my other projects.
ReadingSteiner commentedon Apr 28, 2015
@ericvicenti
Why not use
directly in the
componentDidMount
?What is
Subscribable.Mixin
's job here?ericvicenti commentedon Apr 28, 2015
Subscribable.Mixin
is something we use internally to make sure nobody forgets to unsubscribe to an emitter from a component on unmount. The mixin will automatically remove subscriptions added withthis.addListenerOn
. We are currently phasing it out, though, because we will be transitioning to observables in an upcoming version of React.For more info on the existing EventEmitter, see the github project here: https://github.com/facebook/emitter
ReadingSteiner commentedon Apr 29, 2015
@ericvicenti
Thanks a lot for ur reply :)
backslash112 commentedon Mar 25, 2016
@nick
Checkout this demo: react-native_flux_demo
tbolt commentedon Mar 26, 2016
Flux being the only solution for this isn't ideal.
backslash112 commentedon Mar 28, 2016
@Teebolt
I agree with you, because I met a new problem when I trying to use Flux:
I created a TodoItems app too, When I succeeded in pushing a notification to the child component, and the child component will save the new item to the db, after this, the child component will push another notification to the list component for reload the list, the problem is, there are two dispatches in this process and it will cause a error:
Invariant Violation: Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch.
tbolt commentedon Mar 28, 2016
I was able to solve this using a simple event emitter. I can post more details if anyone needs.
backslash112 commentedon Mar 29, 2016
@Teebolt Please post more details about simple event emitter, thank you.
tbolt commentedon Mar 29, 2016
@backslash112 Here is how I was able to have the "onRightButtonPress" trigger a function in the sub-component.
The only dependency I used is https://github.com/Olical/EventEmitter which can be added:
var EventEmitter = require('wolfy87-eventemitter');
In my main file (index.io.js) I created a new event emitter outside of the class:
var rightButtonHandler = new EventEmitter();
Then, inside the class I created a method to be called when the button is pressed:
handleSaveButton() { rightButtonHandler.emitEvent('saveButtonPressed'); }
And right below that I am passing the event emitter as a property to the sub-component:
passProps: { events: rightButtonHandler }
Now, switching to the sub-component class, add this or update your componentDidMount method:
componentDidMount() { this.props.events.addListener('saveButtonPressed', this.saveConcert.bind(this)); }
The above will be calling this saveConcert:
saveConcert() { /// This is now called when the navigatorIOS right button is pressed. }
Hope this helps!
backslash112 commentedon Mar 30, 2016
@Teebolt
Thank you very much, it works.
But if you want to start another
dispatch
in alistener
that is triggered byemitChange()
of aStore
, you will get the same error like I said above:Invariant Violation: Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch.
chetankothari commentedon May 23, 2016
@ericvicenti I tried the approach you mentioned in one of the replies, thanks for the detailed explanation. Just wanted to check if the same holds true now or is there another way of solving it in a better way. If so could you please help me out with that.
Thanks.
ericvicenti commentedon May 23, 2016
These days I would just go with a redux-style control flow, but its not too easy to pass props down into the inside of NavigatorIOS scenes. But it can probably be done with a redux provider, and that would be a much cleaner solution
chetankothari commentedon May 23, 2016
@ericvicenti Thanks for the prompt response. Will try out getting redux-style control flow.
JSONKit usage here may cause serious crash hard to debug(I found the …
littlehome-eugene commentedon Jul 23, 2017
@ericvicenti @chetankothari
Can you elaborate what you mean by redux-style control flow?
Notify the click event through redux state?