React导航在导航时转到初始路线



我使用Expo,Redux和React导航。

以下是我的初始路由 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)

我在此页面上检查一个异步变量,并相应地重定向。我在以下验证中检查异步。

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)))
    }
}

以下是我的还原器, 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;

以下是我的 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)

但是,当我运行此代码时。该应用像这样导航预加载器>查找没有localToken的登录>在提交电话号码上,它将转到 preloader >然后 login 最后 OTP

为什么不直接到 otp 而无需进入 preloader 页面?

以下是Expo Console的日志

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",
    },
  ],
}

这是因为您正在更改预加载器(导航道具)收到的道具,因此您将输入它的" 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 !");
               }
            }
        }

在再次触发导航之前,比较了nextProps.localtokenstatus是否与您的this.props.localtokenstatus不同,因此,除非您的redux localtokenstatus更改。

,它不会发生。

编辑:发生这种情况是因为预加载器仍然存在,因为您没有清楚地清除导航中的堆栈,因此您可以使用此功能这样做:

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

可以称为" this.props.navigate('rutename')"的位置

最新更新