Я настраиваю поток аутентификации в своем приложении React Native, и я в значительной степени могу заставить все работать, кроме того, что я не могу определить фактическое правильное место, чтобы перейти к стеку входа в систему с помощью this.props.navigation.navigate("Main");
.
У меня в верхней части моего приложения есть Навигатор коммутаторов, отображающий стек авторизации (собственный переключатель Switch) и основной стек:
// App.js
const AppContainer = createAppContainer(
createSwitchNavigator({
Auth: AuthNavigator,
Main: MainTabNavigator,
})
);
export default class App extends Component {
render() {
return (
<Provider store={store}>
<View style={styles.container}>
<AppContainer />
</View>
</Provider>
);
}
}
Экран входа в систему на данный момент является полной фиктивной настройкой(он вызывает локальный API и успешно, несмотря ни на что). Примечание условие в начале метода рендеринга:
// LoginView.js
class LoginView extends Component {
state = { username: "", password: "" };
handleLogin() {
this.props.login.call(this);
}
render() {
if (this.props.user) {
this.props.navigation.navigate("Main");
return null;
}
return (
<View style={styles.container}>
<Overlay>
<View style={styles.modalContainer}>
<DotIndicator color={"darkgrey"} />
<Text>Logging in...</Text>
</View>
</Overlay>
// ... input components ...
<Button
title="Login"
onPress={this.handleLogin.bind(this)}
/>
</View>
);
}
}
export default connect(
state => ({
isLoading: state.auth.isLoading,
user: state.auth.user,
error: state.auth.error
}),
{ login }
)(LoginView);
Теперь это технически работает, но я получаю ошибку Warning: Cannot update during an existing state transition (such as within
рендер ). Render methods should be a pure function of props and state.
.
Я понимаю, что это брошено, потому что я звоню navigate
внутри render
.Имеет смысл.
Я пытался перейти от моего действия входа в систему:
export function login() {
return dispatch => {
dispatch({ type: "LOGIN_START" });
fetch(url) // this will need to be a POST session (not a GET user)
.then(res => res.json())
.then(users => {
dispatch({ type: "LOGIN_SUCCESS", payload: users[0] });
console.log("Login succeeded");
this.props.navigation.navigate("Main");
})
.catch(error => {
console.warn("login failed");
dispatch({ type: "LOGIN_FAILURE", payload: error });
});
};
}
И это работает, но, конечно, очень неправильно с точки зрения разделения интересов, и этот вид решения такжена самом деле не тянется так долго, когда я пытаюсь использовать его для обработки ошибки входа в систему.
Я также думал о том, чтобы сделать это в моей функции handleLogin()
(вызываемой моей кнопкой входа в систему), с и без async /await:
async handleLogin() {
await this.props.login.call(this);
console.log("Navigating to main screen");
this.props.navigation.navigate("Main");
}
Но навигация происходит до того, как действие завершается, и пользователь входит в систему, что, конечно, недопустимо, когда поток аутентификации является реальным.(Плюс, когда я делаю это с помощью async / await, «Login Succeeded» регистрируется дважды! Ударяет меня).Такое ощущение, что я на правильном пути, выполняя это в своей функции handleLogin()
.
Куда мне направить мой вызов navigate
?