react-navigation / web

Tools for react-navigation on web browsers and servers
https://reactnavigation.org
MIT License
94 stars 28 forks source link

navigation.dispatch in case StackActions.reset not working for web #20

Closed soroushm closed 5 years ago

soroushm commented 5 years ago

Dear Friends,

I have a react-native web and recently i`m start migrate to web application (with react-navigation for web) but i have a problem navigation.dispatch not working just in web in react-native working as well

in Luanch page in some case i will be reset AuthNavigator for navigat to Join page NavigationService.reset(['AuthNavigator'])

here is data of resetAction: Screenshot from 2019-04-06 13-02-19

Current Behavior

index.js

// @flow

import React, { Component } from 'react'
import { View } from 'react-native'
import { createSwitchNavigator } from '@react-navigation/core'
import { createBrowserApp } from '@react-navigation/web'
// import Launch from 'src/components/init/launch/Launch'
import AuthNavigator from 'src/navigators/AuthNavigator'
// import MainTabNavigator from 'src/navigators/MainTabNavigator'

const MainNavigator = createSwitchNavigator(
  {
    Launch: { screen: Launch },
    AuthNavigator: { screen: AuthNavigator },
    // MainTabNavigator: { screen: MainTabNavigator },

  },
  {
    initialRouteName: 'Launch',
  }
)

type Props = {
  lastSupportedVersion: string,
  lastStableVersion: string,
  needForceUpdate: string,
  needOptionalUpdate: boolean
}

const AppContainer = createBrowserApp(MainNavigator)

class MainNavigatorWithMeta extends Component<Props, void> {
  _onBackPress: Function
  _getActiveRouteName: Function

  constructor(props) {
    super(props)
    this._getActiveRouteName = this._getActiveRouteName.bind(this)
    this._onBackPress = this._onBackPress.bind(this)
  }
  componentDidMount() {
    // BackHandler.addEventListener('hardwareBackPress', this._onBackPress)
  }

  componentWillUnmount() {
    // BackHandler.removeEventListener('hardwareBackPress', this._onBackPress)
  }

  _onBackPress() {
    // analytics().logEvent('back_hardware')
  }
  // gets the current screen from navigation state
  _getActiveRouteName(navigationState) {
    if (!navigationState) {
      return null
    }
    const route = navigationState.routes[navigationState.index]
    // dive into nested navigators
    if (route.routes) {
      return this._getActiveRouteName(route)
    }
    return route.routeName
  }

  render() {
    return (
        <AppContainer
          screenProps={{ ...this.props }}
          ref={(navigatorRef) => {
            NavigationService.setTopLevelNavigator(navigatorRef)
          }}
        />
    )
  }
}

export default Metadata.providers.metadata(MainNavigatorWithMeta)

NavigationService.js

// @flow

import { NavigationActions, StackActions } from '@react-navigation/core'

let _navigator

function setTopLevelNavigator(navigatorRef: any): any {
  _navigator = navigatorRef
}

function navigate(routeName: string, params: any): void {
  const navigateAction = NavigationActions.navigate({
    routeName,
    params
  })
  _navigator._navigation.dispatch(navigateAction)
}

function reset(routeNames: Array<string>): void {
  let actions = null
  for (let i = routeNames.length - 1; i >= 0; i--) {
    let params: any = { routeName: routeNames[i] }
    if (i !== routeNames.length - 1) {
      params.action = actions
    }
    actions = NavigationActions.navigate(params)
  }
  const resetAction = StackActions.reset({
    index: 1,
    key: null,
    actions: [actions]
  })
  console.log('resetAction', resetAction)
  _navigator._navigation.dispatch(resetAction)
}

export default {
  navigate,
  reset,
  setTopLevelNavigator
}

AuthNavigator

// @flow

import { createSwitchNavigator } from '@react-navigation/core'
import Join from 'src/components/init/auth/Join'
import Login from 'src/components/init/auth/Login'
import { COLOR_WHITE } from 'src/shared/styles/colors'

const AuthNavigator = createSwitchNavigator(
  {
    Join: { screen: Join },
    Login: { screen: Login }
  },
  {
    initialRouteName: 'Join',
    headerMode: 'none',
    navigationOptions: {
      gesturesEnabled: false
    },
    cardStyle: { backgroundColor: COLOR_WHITE }
  }
)

export default AuthNavigator

Expected Behavior

navigate to Join page same as react-native

Your Environment

software version
react-navigation core "3.2.0"
react-navigation web "1.0.0-alpha.7"
react-native-web "0.11.2"
node 8
npm or yarn yarn
slorber commented 5 years ago

hi, what does it mean "not working"?

There has been a recent PR, which fixed an issue with the dispatch method being prefixed with a _. As you are using a ref on the navigation container like in the issue, it's probably the same error if you got "dispatch is not a function" or some error like that

https://github.com/react-navigation/react-navigation-web/pull/19

slorber commented 5 years ago

It seems it has not yet been released however (cc @brentvatne @ericvicenti) so you can try calling _dispatch

soroushm commented 5 years ago

@slorber not working mins not happen when i dispatch StackActions.reset noting happen

I`m already try _dispatch but not different in fact and after check test speck released the correct one is "ref._navigation.dispatch" and its working as well on when i dispatch navigateAction

soroushm commented 5 years ago

Hey guys, @brentvatne @ericvicenti i Have few issue on this repo when try for working on web can you take a look

actualy navigation goBack and this issue and some more little thinks not working if you need more information or a sample i can make it take hands on this issue

appreciate that

brentvatne commented 5 years ago

@soroushm - please create a new issue and provide a runnable example that we can use on https://snack.expo.io, thanks!

brentvatne commented 5 years ago

tips on how to create a good reproducible example: https://stackoverflow.com/help/mcve