Передача функций React-Navigation в screenProps - PullRequest
0 голосов
/ 25 июня 2019

Я создаю приложение с использованием 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 и передать его. Есть мысли?

Ответы [ 2 ]

1 голос
/ 26 июня 2019

Передача функции в качестве screenProp должна быть

<AppNavigator screenProps={{signOut: this.signOut}} />

, затем использовать do

this.props.screenProps.signOut()
0 голосов
/ 25 июня 2019

MainSwitchNavigator

export default createSwitchNavigator({
    // Home: { screen: HomeScreen }
    Home: { screen: HomeScreen }
},{
    initialRouteName: 'Home'
});

для отправки данных по навигации

this.props.navigation.navigate('Signout' , { name: 'John Doe', email: 'john@doe.com' })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...