react-navigation / rfcs

RFCs for changes to React Navigation
Other
88 stars 16 forks source link

Implement more `backBehavior` options for SwitchRouter #2

Closed satya164 closed 5 years ago

ericvicenti commented 6 years ago

This is good so far!

Lets some bikeshedding out of the way. Heres an idea for the names, feel free to suggest alternatives: (bold means its already in the API)

spencercarli commented 6 years ago

Alternative names:

I think those align well with the key you're using to define the behavior. It feels natural/descriptive when you look at just the config

satya164 commented 6 years ago

Let's settle on the following:

I haven't added the infinite history pattern since it doesn't sound useful.

satya164 commented 6 years ago

@brentvatne @ericvicenti @spencercarli would you like any changes?

ericvicenti commented 6 years ago

Those options look great to me!

brentvatne commented 6 years ago

:+1: lgtm

brentvatne commented 6 years ago

@satya164 - can you update rfc according to template? then we can proceed with this

satya164 commented 6 years ago

I'm working on a PR

gameunite commented 6 years ago

I really need this feature. Is there any workaround to make the history works? I want to go back to the previous screen instead of going back to the initialroute. Or do I have to implement my own stack and do the back manually?

ericvicenti commented 6 years ago

@gameunite, you can customize the TabRouter for your app using the following technique:

https://next.reactnavigation.org/docs/custom-navigators.html#extending-navigators

By overriding Navigator.router.getStateForAction, you can customize the back behavior. Or you can fork the router yourself if you prefer.

ericvicenti commented 6 years ago

Looking forward to seeing this go forward! If somebody steps up to help, we may have this feature in time for the v2 release!

sangupandi commented 6 years ago

Waiting for v2 release. When we can expect this amazing release.?

Gloix commented 6 years ago

I tested the Youtube app (version 13.15.55) and it falls within the Keep a history of tabs, and de-duplicate bucket, as opposed to the PR stating that it doesn't handle the back button.

satya164 commented 6 years ago

They probably changed it. This was tested way long ago. Anyway, we want to provide options, so people can change it if they want.

m1ck2 commented 6 years ago

Wouldn’t you implement a Ethereum or bitcoin router with block chain technology and it’s api I call as its road map. With react/navigation and machine learning it would have all you require but the serverless

Taylor123 commented 6 years ago

Is there a branch or conversation surrounding this proposal I could follow? Looking forward to it's implementation!

brentvatne commented 6 years ago

all conversation is here, we need to finalize this RFC and then start implementation. volunteers to help with this would be very welcome

technoplato commented 6 years ago

@satya164 Need any help?

Here's a video with this working: https://youtu.be/7SA6EHpS3EU

I'm not quite sure what the most 'official' way of doing this would be, but I got my preferred 'back' functionality (history as named above) by just modifying getStateForAction. Here's the code. Let me know if you want to use it or go in a different direction than this approach:

import React from 'react'
import { createBottomTabNavigator, NavigationActions } from 'react-navigation'
import { ProfileStack, AddPost } from '../Misc'
import FeedStack from '../Feed'
import MyCustomSillyDrawerComponent from '../MyCustomSillyDrawerComponent'
this.previousRoute = 'Main'
this.currentRoute = 'Main'
const TabNavigation = createBottomTabNavigator(
  {
    Main: FeedStack,
    AddPost: {
      screen: AddPost,
      navigationOptions: {
        tabBarVisible: false
      }
    },
    Profile: ProfileStack
  },
  {
    initialRouteName: 'Main',
    contentComponent: MyCustomSillyDrawerComponent
  }
)
const defaultGetStateForAction = TabNavigation.router.getStateForAction
TabNavigation.router.getStateForAction = (action, state) => {
  switch (action.type) {
    case 'Navigation/INIT':
      this.currentRoute = 'Main'
      this.nextRoute = 'Main'
      break
    case 'Navigation/NAVIGATE':
      this.previousRoute = this.currentRoute
      this.currentRoute = action.routeName
      this.nextRoute = action.routeName
      break
    case 'Navigation/BACK':
      this.nextRoute = this.previousRoute
      this.currentRoute = this.nextRoute
      this.previousRoute = this.currentRoute
      const index = state.routes.map(route => route.key).indexOf(this.nextRoute)
      const newState = {
        routes: state.routes,
        index: index
      }
      return newState
  }
  return defaultGetStateForAction(action, state)
}
export default () => <TabNavigation />
brentvatne commented 5 years ago

I'll fix this to match the template soon

Er-rchydy commented 5 years ago

@technoplato is there a workaround incase we use DrawerNavigator instead of createBottomTabNavigator , this is my code:

const MyDrawerNavigator = DrawerNavigator({
  Screen1: {
    screen: Screen1
  },
  Screen2: {
    screen: Screen2
  },
  Screen3: {
    screen: Screen3
  }
},
  {
    initialRouteName: 'Screen1',
    drawerPosition: 'left',
    backBehaviour: 'none',
    drawerOpenRoute: 'DrawerOpen',
    drawerCloseRoute: 'DrawerClose',
    drawerToggleRoute: 'DrawerToggle'
  });

i added your code like this:

  const defaultGetStateForAction = MyDrawerNavigator.router.getStateForAction
  MyDrawerNavigator.router.getStateForAction = (action, state) => {
    switch (action.type) {
      case 'Navigation/INIT':
        this.currentRoute = 'Main'
        this.nextRoute = 'Main'
        break
      case 'Navigation/NAVIGATE':
        this.previousRoute = this.currentRoute
        this.currentRoute = action.routeName
        this.nextRoute = action.routeName
        break
      case 'Navigation/BACK':
        this.nextRoute = this.previousRoute
        this.currentRoute = this.nextRoute
        this.previousRoute = this.currentRoute
        const index = state.routes.map(route => route.key).indexOf(this.nextRoute)
        const newState = {
          routes: state.routes,
          index: index
        }
        return newState
    }
    return defaultGetStateForAction(action, state)
  }

but it didn't work, it messed the DrawerNavigator. i hope you can find a way to make it work with DrawerNavigator too. thanks

slorber commented 5 years ago

Hi,

I'd like to contribute this feature. Is someone already working on it?

brentvatne commented 5 years ago

@slorber - don't think so! this would be awesome if you could help!

slorber commented 5 years ago

here is a PR: https://github.com/react-navigation/react-navigation-core/pull/31