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

时间:2017-10-04 16:12:21

标签: javascript react-native redux react-redux react-navigation

我使用expo,redux和反应导航。

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

我在此页面上检查AsyncStorage变量并相应地重定向。我检查以下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)))
    }
}

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

但是当我运行这段代码时。该应用程序导航如下 Preloader &gt;找不到localtoken转到登录&gt;提交电话号码后,会转到 Preloader &gt;然后登录&gt;然后终于 OTP

为什么不直接导航到 OTP 而不转到 Preloader 页面?

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

1 个答案:

答案 0 :(得分:1)

这是因为你正在更改Preloader(导航道具)收到的道具,所以你将输入它的“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('routeName')”的地方调用