Я создаю приложение с использованием React Native, Expo и React Navigation, и я не знаю, как правильно передавать реквизиты и функции.
Я скопировал метод Expo для навигаторов, на которых я буду строить, но сейчас у меня просто App.js, вызывающий следующий
AppNavigator -> MainSwitchNavigator -> Домашний экран
Затем я обернул основное экспортируемое приложение, которое ожидает Expo, с Amazon AWS Amplify HOC с Authenticator. Теперь я могу войти в свое приложение и безопасно показать привет, используя сервис Amazon Cognito.
Если я хочу выйти из системы, я могу использовать приведенную ниже функцию выхода из системы, которую я сейчас использую для поддержки приложения.
class App extends React.Component {
constructor(props) {
super(props);
this.signOut = this.signOut.bind(this);
}
signOut() {
Auth.signOut().then(() => {
this.props.onStateChange('signedOut', null);
console.log("signed out");
}).catch(e => {
console.log(e);
});
}
render () {
return (
<View style={styles.container}>
<AppNavigator screenProps={{
signOut: () => {this.signOut}
}}/>
</View>
);
}
}
export default withAuthenticator(App)
Пока что я просто хочу передать эту функцию на домашний экран, чтобы добавить кнопку и выйти из системы.
AppNavigator
export default createAppContainer(
createSwitchNavigator({
// You could add another route here for authentication.
// Read more at https://reactnavigation.org/docs/en/auth-flow.html
Main: { screen: MainSwitchNavigator, params: { signOut: this.props.screenProps.signOut } },
},
{
initialRouteName: 'Main'
})
);
MainSwitchNavigator
export default createSwitchNavigator({
// Home: { screen: HomeScreen }
Home: { screen: HomeScreen, params: { signOut: this.props.navigation.params.signOut } }
},{
initialRouteName: 'Home'
});
HomeScreen
class HomeScreen extends Component {
render () {
return (
<View>
<Text>Main App Here</Text>
<Button
onPress={this.props.navigation.params.signOut()}
title="Sign Out"
/>
</View>
)};
}
export default HomeScreen;
В данный момент я получаю ошибку
undefined is not an object (evaluating 'this.props.navigation')
<unknown>
MainSwitchNavigator.js
8:62
Это ставит точку, в которой я пытаюсь прочитать реквизиты, переданные в MainSwitchNavigator.
Итак, мой вопрос: какова хорошая практика совместного использования функций и состояния на экранах под основным приложением и как передать функцию signOut остальным компонентам?
=============================================== ========================
EDIT
С тех пор я понял, как правильно использовать screenProps для переменных, но не для функций. screenProps автоматически передается через навигаторы на экран. Поэтому мне нужно только передать его компоненту AppNavigator один раз, и я могу получить к нему доступ на HomeScreen. Однако никакие функции не передаются.
E.g для переменных, если я изменю App.js, чтобы передать текст в переменную signOut и передать его в screenProps
class App extends React.Component {
constructor(props) {
super(props);
this.signOut = this.signOut.bind(this);
}
signOut() {
Auth.signOut().then(() => {
this.props.onStateChange('signedOut', null);
console.log("signed out");
}).catch(e => {
console.log(e);
});
}
render () {
return (
<View style={styles.container}>
<AppNavigator screenProps={{signOut: "some text"}}/>
</View>
);
}
}
HomeScreen отобразит это как часть объекта this.props.
class HomeScreen extends Component {
render () {
return (
<View>
<Text>Main App Here</Text>
<Button
onPress={console.log(JSON.stringify(this.props))}
// onPress={alert(this.props.screenProps.var3)}
title="Sign Out"
/>
</View>
)};
}
export default HomeScreen;
Однако, если я вместо этого передам функцию в AppNavigator и сделаю это
<AppNavigator screenProps={{signOut: () => {this.signOut}}}/>
screenProps не устанавливается, и я не могу получить доступ к функции signOut.
Единственное, что я могу заставить работать - это
<AppNavigator screenProps={this.signOut}/>
Но мне нужно создать свойство screenProps и передать его. Есть мысли?