简体   繁体   English

导航时,React Navigation会转到初始路线

[英]React Navigation goes to initial route while navigating

I use expo, redux and react navigation. 我使用expo,redux并进行导航。

The following is my initial route Preloader.js 以下是我的初始路线Preloader.js

    class PreloaderScreen extends React.Component {
    constructor(props) {
        super(props);
    }

    componentWillMount() {
        console.log("CWM --", this.props.auth);
        this.props.getLocalToken();
    }

    componentWillReceiveProps(nextProps) {
        console.log("NXT props - PL", nextProps);
        if (nextProps.auth.localTokenStatus == 1) {
            console.log("Navigating to main");
            this.props.navigation.navigate('Main');
        }
        else if (nextProps.auth.localTokenStatus == -1) {
            console.log("Navigating to Login !!!!");
            this.props.navigation.navigate('Login');
        }
        else {
            console.log("Nothing is happening !");
        }

    }

    render() {
        const { navigate } = this.props.navigation;
        return (
            <View>
            </View>
        )

    }
}

function mapStateToProps(state) {
    return {
        auth: state.auth,
    };
}
function mapDispatchToProps(dispatch) {
    return bindActionCreators({ getLocalToken: getLocalToken, storeLocalToken: storeLocalToken }, dispatch)
}

export default connect(mapStateToProps, mapDispatchToProps)(PreloaderScreen)

I check for an AsyncStorage variable on this page and redirect accordingly. 我在此页面上检查AsyncStorage变量并进行相应的重定向。 I check the AsyncStorage in the following AuthAction. 我在以下AuthAction中检查AsyncStorage。

export function getLocalTokenSuccess(localStore) {
    console.log('Got Local Token', localStore);
    return {
        type: types.GET_LOCALTOKEN_SUCCESS,
        payload: localStore
    }

}

export function getLocalTokenFail(error) {
    return {
        type: types.GET_LOCALTOKEN_FAIL
    }
}


export const getLocalToken = (dispatch) => {
    return (dispatch) => {

        AsyncStorage.getItem('localToken')
            .then((localStore) => dispatch(getLocalTokenSuccess(localStore)))
            .catch((error) => dispatch(getLocalTokenFail(error)))
    }
}

The following is my reducer, reducer-auth.js 以下是我的减速器, reducer-auth.js

case types.GET_LOCALTOKEN_SUCCESS:
      localTokenJSON = JSON.parse(action.payload);
      console.log("localStore ", action.payload);
      return { ...state, key: localTokenJSON.key, mobileNumber: localTokenJSON.mobileNumber, localTokenStatus: 1 };
      break;

    case types.GET_LOCALTOKEN_FAIL:
      console.log("gltf --");
      return { ...state, localTokenStatus: -1 }
      break;

Following is my Login.js where I land if there's no local token found. 如果找不到本地令牌,以下是我登录的我的Login.js

class LoginScreen extends React.Component {

  constructor(props) {
    super(props);

  }

  submitButton(isValid) {
    return (
      <Button backgroundColor='#0000b2' style={LoginStyle.buttonStyle}
        onPress={() => { console.log("Pressed"); this.props.submitOTPMobileNumber(this.props.auth.mobileNumber) }}
        disabled={!isValid}
        title='Login' />
    );
  }

  state = {
    keyboardHeight: new Animated.Value(0)
  };

  animateKeyboardHeight = (toValue, duration) => {
    Animated.timing(
      this.state.keyboardHeight,
      { toValue, duration },
    ).start();
  };

  componentWillMount() {

    if (Platform.OS === "android") {
      this.keyboardShowListener = Keyboard.addListener("keyboardDidShow", ({ endCoordinates }) => {
        this.animateKeyboardHeight(endCoordinates.height, 0)
      });
      this.keyboardHideListener = Keyboard.addListener("keyboardDidHide", () => {
        this.animateKeyboardHeight(0, 300)
      })

    }
  }
  componentWillReceiveProps(nextProps) {
    if (nextProps.auth.OTPAPISubmissionSuccess)
      this.props.navigation.navigate('Otp');
  }

  scrollToInput = (reactNode) => {
    this.view.scrollToFocusedInput(reactNode)
  };

  handleOnFocus = (e) => {
    if (Platform.OS === "android") {
      this.scrollToInput(ReactNative.findNodeHandle(e.target))
    }
  };

  render() {

    const { navigate } = this.props.navigation;
    return (
      <KeyboardAwareScrollView
        ref={ref => this.view = ref}
        enableOnAndroid
        extraHeight={Platform.OS === "android" ? 10 : undefined}
      >
        <View>
          <Image style={LoginStyle.backgroundImage} source={require('../Images/Icons/login.jpeg')} />
        </View>
        <Card style={LoginStyle.loginBox}>
          <Text style={LoginStyle.subtitle}>India (+91)</Text>
          <TextInput
            onFocus={this.handleOnFocus}
            style={LoginStyle.textInput}
            keyboardType='numeric'
            placeholder="Mobile Number"
            maxLength={10} minLength={10}
            onChangeText={(mobileNumber) => { this.props.OTPMobileNumberEntered(mobileNumber) }}
            value={this.props.auth.mobileNumber}>
          </TextInput>
          <Text>{"\n"}</Text>
          <Text style={LoginStyle.subText}>We will send you a one time SMS message</Text>
          <Text>{"\n"}</Text>
          {this.submitButton(this.props.auth.mobileIsValid)}
        </Card>
        <Animated.View style={{ height: this.state.keyboardHeight }} />

      </KeyboardAwareScrollView>

    );
  }
}

function mapStateToProps(state) {
  return {
    auth: state.auth,
  };
}
function mapDispatchToProps(dispatch) {
  return bindActionCreators({
    OTPMobileNumberEntered: OTPMobileNumberEntered,
    submitOTPMobileNumber: submitOTPMobileNumber,
  }, dispatch)
}

export default connect(mapStateToProps, mapDispatchToProps)(LoginScreen)

But when I run this code. 但是当我运行这段代码时。 The app navigates like this Preloader > finding no localtoken goes to Login > On submit of phone number it goes to Preloader > then Login > then finally OTP 该应用程序的导航方式如下: 加载器>查找没有本地令牌去登录 >在提交电话号码时,它去加载器>然后登录 >最后是OTP

Why won't it navigate directly to OTP without going to Preloader page? 为什么不直接进入预加载器页面就不能直接导航到OTP

Following is the log on the expo console 以下是expo控制台上的日志

FB Initialized
21:23:51
CWM -- Object {
  "OTPAPISubmissionSuccess": false,
  "OTPIsValid": true,
  "OTPNumber": "9000",
  "firebaseToken": "",
  "key": "",
  "localToken": "",
  "localTokenStatus": 0,
  "loginSuccess": 0,
  "mobileIsValid": true,
  "mobileNumber": "8891468710",
  "store": "",
  "user": "",
}
21:23:51
Got Local Token null
21:23:51
localStore  null
21:23:51
gltf --
21:23:51
NXT props - PL Object {
  "auth": Object {
    "OTPAPISubmissionSuccess": false,
    "OTPIsValid": true,
    "OTPNumber": "9000",
    "firebaseToken": "",
    "key": "",
    "localToken": "",
    "localTokenStatus": -1,
    "loginSuccess": 0,
    "mobileIsValid": true,
    "mobileNumber": "8891468710",
    "store": "",
    "user": "",
  },
  "getLocalToken": [Function anonymous],
  "navigation": Object {
    "dispatch": [Function anonymous],
    "goBack": [Function goBack],
    "navigate": [Function navigate],
    "setParams": [Function setParams],
    "state": Object {
      "key": "Init-id-1507132425968-0",
      "routeName": "Preloader",
    },
  },
  "screenProps": undefined,
  "storeLocalToken": [Function anonymous],
}
21:23:51
Navigating to Login !!!!
21:23:51
Navigation Dispatch:
21:23:51
Action:  Object {
  "action": undefined,
  "params": undefined,
  "routeName": "Login",
  "type": "Navigation/NAVIGATE",
}
21:23:51
New State:  Object {
  "index": 1,
  "routes": Array [
    Object {
      "key": "Init-id-1507132425968-0",
      "routeName": "Preloader",
    },
    Object {
      "key": "id-1507132425968-1",
      "params": undefined,
      "routeName": "Login",
    },
  ],
}
21:23:51
Last State:  Object {
  "index": 0,
  "routes": Array [
    Object {
      "key": "Init-id-1507132425968-0",
      "routeName": "Preloader",
    },
  ],
}
21:23:51
21:34:09
Pressed
21:34:09
HTTP request =>  8891468710
21:34:09
Requesting HTTP
21:34:09
HTTP response, Object {
  "message": "OTP sent successfully",
  "status": "OK",
}
21:34:09
checkOTPAPIStatus OK
21:34:09
checkOTPAPIStatus OK
21:34:09
OTP SEND -- Reducer !
21:34:09
NXT props - PL Object {
  "auth": Object {
    "OTPAPISubmissionSuccess": true,
    "OTPIsValid": true,
    "OTPNumber": "9000",
    "firebaseToken": "",
    "key": "",
    "localToken": "",
    "localTokenStatus": -1,
    "loginSuccess": 0,
    "mobileIsValid": true,
    "mobileNumber": "8891468710",
    "store": "",
    "user": "",
  },
  "getLocalToken": [Function anonymous],
  "navigation": Object {
    "dispatch": [Function anonymous],
    "goBack": [Function goBack],
    "navigate": [Function navigate],
    "setParams": [Function setParams],
    "state": Object {
      "key": "Init-id-1507132425968-0",
      "routeName": "Preloader",
    },
  },
  "screenProps": undefined,
  "storeLocalToken": [Function anonymous],
}
21:34:09
Navigating to Login !!!!
21:34:09
Navigation Dispatch:
21:34:09
Action:  Object {
  "action": undefined,
  "params": undefined,
  "routeName": "Login",
  "type": "Navigation/NAVIGATE",
}
21:34:09
New State:  Object {
  "index": 2,
  "routes": Array [
    Object {
      "key": "Init-id-1507132425968-0",
      "routeName": "Preloader",
    },
    Object {
      "key": "id-1507132425968-1",
      "params": undefined,
      "routeName": "Login",
    },
    Object {
      "key": "id-1507132425968-2",
      "params": undefined,
      "routeName": "Login",
    },
  ],
}
21:34:09
Last State:  Object {
  "index": 1,
  "routes": Array [
    Object {
      "key": "Init-id-1507132425968-0",
      "routeName": "Preloader",
    },
    Object {
      "key": "id-1507132425968-1",
      "params": undefined,
      "routeName": "Login",
    },
  ],
}
21:34:09
21:34:09
Navigation Dispatch:
21:34:09
Action:  Object {
  "action": undefined,
  "params": undefined,
  "routeName": "Otp",
  "type": "Navigation/NAVIGATE",
}
21:34:09
New State:  Object {
  "index": 3,
  "routes": Array [
    Object {
      "key": "Init-id-1507132425968-0",
      "routeName": "Preloader",
    },
    Object {
      "key": "id-1507132425968-1",
      "params": undefined,
      "routeName": "Login",
    },
    Object {
      "key": "id-1507132425968-2",
      "params": undefined,
      "routeName": "Login",
    },
    Object {
      "key": "id-1507132425968-3",
      "params": undefined,
      "routeName": "Otp",
    },
  ],
}
21:34:09
Last State:  Object {
  "index": 2,
  "routes": Array [
    Object {
      "key": "Init-id-1507132425968-0",
      "routeName": "Preloader",
    },
    Object {
      "key": "id-1507132425968-1",
      "params": undefined,
      "routeName": "Login",
    },
    Object {
      "key": "id-1507132425968-2",
      "params": undefined,
      "routeName": "Login",
    },
  ],
}

It's because you're changing the props recieved by the Preloader (the navigation props), so you'll enter it's "ComponentWillRecieveProps", which will trigger the navigation to Login, you can fix this with: 这是因为您要更改预加载器收到的道具(导航道具),因此要输入“ ComponentWillRecieveProps”,它将触发导航到“登录”,您可以使用以下方法解决此问题:

componentWillReceiveProps(nextProps) {
            if(this.props.auth.localTokenStatus!=nextProps.auth.localTokenStatus){
               console.log("NXT props - PL", nextProps);
               if (nextProps.auth.localTokenStatus == 1) {
                   console.log("Navigating to main");
                   this.props.navigation.navigate('Main');
               }
               else if (nextProps.auth.localTokenStatus == -1) {
                   console.log("Navigating to Login !!!!");
                   this.props.navigation.navigate('Login');
               }
               else {
                console.log("Nothing is happening !");
               }
            }
        }

Which compares if the nextProps.localTokenStatus is different from your this.props.localTokenStatus before triggering the navigation again, so it won't happen unless the localTokenStatus from your redux changes. 相比之下,nextProps.localTokenStatus是否与this.props.localTokenStatus不同,然后再次触发导航,因此除非redux中的localTokenStatus更改,否则不会发生。

EDIT: This happens because preloader still exists since you didn't clear it's stack from the navigation, you can do so with this function: 编辑:发生这种情况是因为预加载器仍然存在,因为您没有从导航中清除它的堆栈,因此您可以使用以下功能:

import { NavigationActions } from 'react-navigation';
...
clearStack(route) {
    const resetAction = NavigationActions.reset({
      index: 0,
      actions: [
        NavigationActions.navigate({ routeName: route})
      ]
    })
    this.props.navigation.dispatch(resetAction)
  }

Which can be called where you're calling "this.props.navigate('routeName')" in the preloader 可以在预加载器中调用“ this.props.navigate('routeName')”的地方调用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 React Navigation SwitchNavigator的动态初始路线 - Dynamic initial Route for React Navigation SwitchNavigator 反应:私人路线不导航 - React: private route not navigating Wix React原生导航选项卡按钮在导航回屏幕时超出范围 - Wix React native navigation tab button goes out of bound on navigating back to screen React-Native-Navigation,通过 navigation.navigate(“routename”, {randomparams}) 导航到它时如何刷新路由 - React-Native-Navigation, how to refresh a route when navigating to it via navigation.navigate(“routename”, {randomparams}) 在异步函数中导航 - React Navigation - React Native - Navigating in Async function - React Navigation - React Native 为什么这个 React CRUD 会回到最初的 state? - Why this React CRUD goes back to initial state? 使用Android硬件导航时出现导航问题Back Press [react-native] - Navigation Issue while navigating using Android Hardware Back Press [react-native] 从Java脚本正确导航到React Route - Correctly Navigating to React Route from Javascript 反应本机导航并导航到另一个屏幕问题 - React Native Navigation and navigating to another Screen problem 导航startTabBasedApp时,React Native Navigation崩溃 - React Native Navigation crashes when navigating startTabBasedApp
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM