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

Can NavigatorIOS notify that a "back" happened? #26

Closed
zertosh opened this issue Feb 2, 2015 · 14 comments
Closed

Can NavigatorIOS notify that a "back" happened? #26

zertosh opened this issue Feb 2, 2015 · 14 comments
Labels
Resolution: Locked This issue was locked by the bot.

Comments

@zertosh
Copy link
Member

zertosh commented Feb 2, 2015

Not sure if I'm missing something, but does NavigatorIOS have a way of notifying its owner that there is a new top route because the "<" back button was pressed? Otherwise, to get that functionality, the removed component would have to itself notify during componentWillUnmount, and that just feels weird.

@vjeux
Copy link
Contributor

vjeux commented Feb 2, 2015

cc @evv

@vjeux
Copy link
Contributor

vjeux commented Feb 2, 2015

@ericvicenti actually :p

@zertosh
Copy link
Member Author

zertosh commented Feb 2, 2015

@vjeux: So far I'm having a great time with react-native. I wrote a tumblr browser that uses the flux pattern heh. This is what it looks like: min-s-react-native-demo-gif. (I'm not inlining the gif because it's too distracting.)

@vjeux
Copy link
Contributor

vjeux commented Feb 2, 2015

Nice! Glad to hear :)

Hopefully we can get gif support soon so that you can have a fully functional app soon

@paramaggarwal
Copy link
Contributor

Unfortunately, the default back button of UINavigationController does not provide an event. The way to get around it is to either set your custom back button on the left side, or to implement - viewWillDisappear: in iOS. So I guess, this limitation is here to stay.

@vjeux
Copy link
Contributor

vjeux commented Feb 7, 2015

Since iOS doesn't support it, let's close this for now.

@vjeux vjeux closed this as completed Feb 7, 2015
@liubko
Copy link
Contributor

liubko commented May 16, 2015

@paramaggarwal is it possible to be notified when any rote changes?
something like

<NavigatorIOS onChange={...}
              initialRoute={...} />

I mean when someone do navigator.push(...)

@paramaggarwal
Copy link
Contributor

@liubko please look into Navigator instead, which is much more customisable. Docs are here: Navigator Comparison

@arypurnomoz
Copy link

i think you can wrap the route component with a wrapper and listen to the wrapper's componentWillUnmount

harrykiselev pushed a commit to harrykiselev/react-native that referenced this issue Aug 5, 2015
<noscript /> -> null in todomvc-flux Footer
dustturtle added a commit to dustturtle/react-native that referenced this issue Jul 6, 2016
…crash on simulator, on device I got nothing but app freezed)!

My app has an old version of JSONKit which is still using MRC. I think JSONKit is not needed if system version is available. Kicking out of JSONKit will make react native stronger.
Crash stack:
* thread facebook#11: tid = 0xbd672f, 0x000000010a10edeb imobii-waiqin`jk_encode_add_atom_to_buffer(encodeState=0x00007f9b820a1000, objectPtr=22 key/value pairs) + 16971 at JSONKit.m:2807, name = 'com.facebook.React.JavaScript', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
    frame #0: 0x000000010a10edeb imobii-waiqin`jk_encode_add_atom_to_buffer(encodeState=0x00007f9b820a1000, objectPtr=22 key/value pairs) + 16971 at JSONKit.m:2807
    frame facebook#1: 0x000000010a10ef67 imobii-waiqin`jk_encode_add_atom_to_buffer(encodeState=0x00007f9b820a1000, objectPtr=2 key/value pairs) + 17351 at JSONKit.m:2811
    frame facebook#2: 0x000000010a10ef67 imobii-waiqin`jk_encode_add_atom_to_buffer(encodeState=0x00007f9b820a1000, objectPtr=25 key/value pairs) + 17351 at JSONKit.m:2811
    frame facebook#3: 0x000000010a10e768 imobii-waiqin`jk_encode_add_atom_to_buffer(encodeState=0x00007f9b820a1000, objectPtr=@"3 elements") + 15304 at JSONKit.m:2778
  * frame facebook#4: 0x000000010a10a26a imobii-waiqin`-[JKSerializer serializeObject:options:encodeOption:block:delegate:selector:error:](self=0x00007f9b831fbc80, _cmd="serializeObject:options:encodeOption:block:delegate:selector:error:", object=@"3 elements", optionFlags=0, encodeOption=10, block=0x0000000000000000, delegate=0x0000000000000000, selector=<no value available>, error=domain: class name = NSInvocation - code: 0) + 2250 at JSONKit.m:2876
    frame facebook#5: 0x000000010a109992 imobii-waiqin`+[JKSerializer serializeObject:options:encodeOption:block:delegate:selector:error:](self=JKSerializer, _cmd="serializeObject:options:encodeOption:block:delegate:selector:error:", object=@"3 elements", optionFlags=0, encodeOption=10, block=0x0000000000000000, delegate=0x0000000000000000, selector=<no value available>, error=domain: class name = NSInvocation - code: 0) + 178 at JSONKit.m:2831
    frame facebook#6: 0x000000010a10f700 imobii-waiqin`-[NSArray(self=@"3 elements", _cmd="JSONStringWithOptions:error:", serializeOptions=0, error=domain: class name = NSInvocation - code: 0) JSONStringWithOptions:error:] + 112 at JSONKit.m:2985
    frame facebook#7: 0x000000010ac13c02 imobii-waiqin`_RCTJSONStringifyNoRetry(jsonObject=@"3 elements", error=domain: class name = NSInvocation - code: 0) + 338 at RCTUtils.m:49
    frame facebook#8: 0x000000010ac13990 imobii-waiqin`RCTJSONStringify(jsonObject=@"3 elements", error=0x0000000000000000) + 128 at RCTUtils.m:77
    frame facebook#9: 0x000000010ab5fdfa imobii-waiqin`__27-[RCTContextExecutor setUp]_block_invoke_2(.block_descriptor=<unavailable>, moduleName=@"UIManager") + 218 at RCTContextExecutor.m:363
    frame facebook#10: 0x00000001134495cc CoreFoundation`__invoking___ + 140
    frame facebook#11: 0x000000011344941e CoreFoundation`-[NSInvocation invoke] + 286
    frame facebook#12: 0x000000010db13db3 JavaScriptCore`JSC::ObjCCallbackFunctionImpl::call(JSContext*, OpaqueJSValue*, unsigned long, OpaqueJSValue const* const*, OpaqueJSValue const**) + 451
    frame facebook#13: 0x000000010db13926 JavaScriptCore`JSC::objCCallbackFunctionCallAsFunction(OpaqueJSContext const*, OpaqueJSValue*, OpaqueJSValue*, unsigned long, OpaqueJSValue const* const*, OpaqueJSValue const**) + 262
    frame facebook#14: 0x000000010db14bad JavaScriptCore`long long JSC::APICallbackFunction::call<JSC::ObjCCallbackFunction>(JSC::ExecState*) + 573
    frame facebook#15: 0x000000010dade340 JavaScriptCore`JSC::LLInt::setUpCall(JSC::ExecState*, JSC::Instruction*, JSC::CodeSpecializationKind, JSC::JSValue, JSC::LLIntCallLinkInfo*) + 528
    frame facebook#16: 0x000000010dae535d JavaScriptCore`llint_entry + 22900
    frame facebook#17: 0x000000010dadf7d9 JavaScriptCore`vmEntryToJavaScript + 326
    frame facebook#18: 0x000000010d9b1959 JavaScriptCore`JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 169
    frame facebook#19: 0x000000010d9985ad JavaScriptCore`JSC::Interpreter::executeCall(JSC::ExecState*, JSC::JSObject*, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 493
    frame facebook#20: 0x000000010d76cb7e JavaScriptCore`JSC::call(JSC::ExecState*, JSC::JSValue, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 62
    frame facebook#21: 0x000000010d929a55 JavaScriptCore`JSC::callGetter(JSC::ExecState*, JSC::JSValue, JSC::JSValue) + 149
    frame facebook#22: 0x000000010dad49fb JavaScriptCore`llint_slow_path_get_by_id + 2203
    frame facebook#23: 0x000000010dae22f0 JavaScriptCore`llint_entry + 10503
    frame facebook#24: 0x000000010dae5368 JavaScriptCore`llint_entry + 22911
    frame facebook#25: 0x000000010dae52fd JavaScriptCore`llint_entry + 22804
    frame facebook#26: 0x000000010dae5368 JavaScriptCore`llint_entry + 22911
    frame facebook#27: 0x000000010dae5368 JavaScriptCore`llint_entry + 22911
    frame facebook#28: 0x000000010dae52fd JavaScriptCore`llint_entry + 22804
    frame facebook#29: 0x000000010dae5368 JavaScriptCore`llint_entry + 22911
    frame facebook#30: 0x000000010dae5368 JavaScriptCore`llint_entry + 22911
    frame facebook#31: 0x000000010dae5368 JavaScriptCore`llint_entry + 22911
    frame facebook#32: 0x000000010dae552a JavaScriptCore`llint_entry + 23361
    frame facebook#33: 0x000000010dae5368 JavaScriptCore`llint_entry + 22911
    frame facebook#34: 0x000000010dae5368 JavaScriptCore`llint_entry + 22911
    frame facebook#35: 0x000000010dadf7d9 JavaScriptCore`vmEntryToJavaScript + 326
    frame facebook#36: 0x000000010d9b1959 JavaScriptCore`JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 169
    frame facebook#37: 0x000000010d998264 JavaScriptCore`JSC::Interpreter::execute(JSC::ProgramExecutable*, JSC::ExecState*, JSC::JSObject*) + 10404
    frame facebook#38: 0x000000010d7a8786 JavaScriptCore`JSC::evaluate(JSC::ExecState*, JSC::SourceCode const&, JSC::JSValue, WTF::NakedPtr<JSC::Exception>&) + 470
    frame facebook#39: 0x000000010d9f6fb8 JavaScriptCore`JSEvaluateScript + 424
    frame facebook#40: 0x000000010ab6379e imobii-waiqin`__68-[RCTContextExecutor executeApplicationScript:sourceURL:onComplete:]_block_invoke.264(.block_descriptor=<unavailable>) + 414 at RCTContextExecutor.m:589
    frame facebook#41: 0x000000010ab63262 imobii-waiqin`__68-[RCTContextExecutor executeApplicationScript:sourceURL:onComplete:]_block_invoke(.block_descriptor=<unavailable>) + 498 at RCTContextExecutor.m:589
    frame facebook#42: 0x000000010ab63df8 imobii-waiqin`-[RCTContextExecutor executeBlockOnJavaScriptQueue:](self=0x00007f9b832f6040, _cmd="executeBlockOnJavaScriptQueue:", block=0x00007f9b80c92970) + 248 at RCTContextExecutor.m:627
    frame facebook#43: 0x000000010eb1d7a7 Foundation`__NSThreadPerformPerform + 283
    frame facebook#44: 0x0000000113486301 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    frame facebook#45: 0x000000011347c22c CoreFoundation`__CFRunLoopDoSources0 + 556
    frame facebook#46: 0x000000011347b6e3 CoreFoundation`__CFRunLoopRun + 867
    frame facebook#47: 0x000000011347b0f8 CoreFoundation`CFRunLoopRunSpecific + 488
    frame facebook#48: 0x000000010ab5e41b imobii-waiqin`+[RCTContextExecutor runRunLoopThread](self=RCTContextExecutor, _cmd="runRunLoopThread") + 363 at RCTContextExecutor.m:284
    frame facebook#49: 0x000000010ebc012b Foundation`__NSThread__start__ + 1198
    frame facebook#50: 0x00000001140869b1 libsystem_pthread.dylib`_pthread_body + 131
    frame facebook#51: 0x000000011408692e libsystem_pthread.dylib`_pthread_start + 168
    frame facebook#52: 0x0000000114084385 libsystem_pthread.dylib`thread_start + 13
@sebringj
Copy link

I was able to get a hacked onBack for these types of things using an array as singleton that each component wanting to get there onBack method called would use. The idea is like below.

// singleton onBackStack
export default [];

// example component
class ExampleComponent extends Component {
  onBack() {
    // do something
  }
  componentWillMount() {
    onBackStack.push(this);
  }
  componentWillUnmount() {
   onBackStack.pop();
   if (onBackStack.length) onBackStack[onBackStack.length - 1].onBack();
  }
  render() {
    return <View>example</View>
  }
}

@BSN4
Copy link

BSN4 commented Mar 5, 2017

@sebringj thanks for sharing this can you please explain onBackStack

@sebringj
Copy link

sebringj commented Mar 6, 2017

@phpfalcon basically, there is a singleton that is imported to all components that are views needing to have "onBack" event. The singleton is named "onBackStack" which is just a simple array.

Each component needing an "onBack" would then push themselves into the onBackStack on their own componentWillMount. On componentWillUnmount, they remove themselves off the stack but then call the method of the last item in the list's onBack() so to fire the event of the component it is going back to. It's kind of like a cooperative chaining of components to accomplish this.

This can be put into a component class then inherited from which is probably a way better idea. I just made it very quickly as I don't care to make it more robust or friendly for what I am doing.

@BSN4
Copy link

BSN4 commented Mar 6, 2017

@sebringj your method is great but I couldn't understand it until your last comment I implanted a similar method which works for navigatorios :

constructor()
{
     super();
     this.state = {backapper:false}};
}
componentDidMount() {
    var currentRoute = this.props.navigator.navigationContext.currentRoute;
    this.props.navigator.navigationContext.addListener('willfocus', (event) => {
        //didfocus emit in componentDidMount
        if (currentRoute === event.data.route && this.state.backapper) {
            console.log("me didAppear");
            this.setState({backapper: false});
        }
        else if (currentRoute !== event.data.route)
        {
            this.setState({backapper: true});
            console.log("me didDisappear, other didAppear");
        }
        //console.log(event.data.route);
     });
}

@njt1982
Copy link

njt1982 commented Jul 18, 2017

@phpfalcon Hmm I dont have a navigationContext? Are you using React Navigation? This Google returns no results... navigationContext site:reactnavigation.org

@facebook facebook locked as resolved and limited conversation to collaborators May 29, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 23, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests

9 participants