Неопределенная функция onClick в contentComponent

Я пытаюсь получить доступ к функции внутри кнопки на contentComponent, которая находится внутри createDrawerNavigator. Проблема в том, что «props», переданный в contentComponent, не имеет функции, к которой я пытаюсь получить доступ, и я продолжаю получать «undefined». Вот код:

const MainDrawer = createDrawerNavigator(
  {
    Home: {
    screen: HomeScreen,
  },
  }, {
    contentComponent: (props) => (
      <View style = {{ flex: 1 }}>
        <SafeAreaView forceInset = {{ top: 'always', horizontal: 'never' }}>
          <DrawerItems {...props} />
          <Button
            color='red'
            title='Logout'
            onPress = {() => { props.logoutCurrentUser() }}
          />
        </SafeAreaView>
      </View>
    ),
})


const RootNavigator = createStackNavigator({
  MainDrawer: { screen: MainDrawer},
})

class AppNavigation extends Component {
  constructor(props) {
    super(props);
  }

  logoutCurrentUser = () => {
    console.info("LOGOUT PRESSED")
  }

  render() {
    return <RootNavigator logoutCurrentUser = {this.logoutCurrentUser}/>
  }
}

onPress = {() => {props.logoutCurrentUser ()}} - это то место, где я получаю ошибку. Как правильно вызвать эту функцию?

Заранее спасибо.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
667
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

class AppNavigation extends Component {
  constructor(props) {
    super(props);
    this.logoutCurrentUser = this.logoutCurrentUser.bind(this);
  }

  logoutCurrentUser = () => {
    console.info("LOGOUT PRESSED")
  }

  render() {
    return <MainDrawer logoutCurrentUser = {this.logoutCurrentUser}/>
  }
}

Свойства - это в основном «аргументы», которые вы передаете компоненту, поэтому предположим, что у вас есть

<Component something = "abcd" anotherThing = "efg"></Component>

внутри этого компонента, если вы получаете доступ к this.props у вас будет это

{
    something: "abcd",
    anotherThing: "efg",
}

так что вы можете сделать this.props.something или this.props.anotherThing и получить доступ к этим значениям.

Вы также можете сделать что-то подобное в своем методе

const { something, anotherThing} = this.props;

console.info(something);
console.info(anotherThing);

Итак, что не так с вашим кодом, так это то, что вы не передаете функцию logoutCurrentUser в качестве опоры.

вам нужно передать его компоненту

const MainDrawer = createDrawerNavigator(
  {
    Home: {
    screen: HomeScreen,
  },
  }, {
    contentComponent: (props) => (
      <View style = {{ flex: 1 }}>
        <SafeAreaView forceInset = {{ top: 'always', horizontal: 'never' }}>
          <DrawerItems {...props} />
          <Button
            color='red'
            title='Logout'
            onPress = {() => { props.logoutCurrentUser() }}
          />
        </SafeAreaView>
      </View>
    ),
})

class AppNavigation extends Component {
  constructor(props) {
    super(props);
  }

  logoutCurrentUser = () => {
    console.info("LOGOUT PRESSED")
  }

  render() {
    return <MainDrawer logoutCurrentUser = {this.logoutCurrentUser} />
  }
}

Если вы хотите передать опору с помощью HOC, просто передайте опору в HOC, HOC это похоже, например, на навигатор стека.

const SomeStack = createStackNavigator({
  // config
});

<SomeStack
  screenProps = {/* this prop will get passed to the screen components as this.props.screenProps */}
/>

последний вопрос, если у меня есть мой MainDrawer внутри stackNavigator (я обновлю вопрос), как я передам этот реквизит? Потому что я возвращаю только stackNavigator в render ()

kivul 22.11.2018 10:30

Обновил мой ответ

Cristian Gomez 22.11.2018 10:34

так что это будет выглядеть так: render () {return <RootNavigator screenProps = {this.logoutCurrentUser} />} Но я все еще не могу получить доступ к 'props.logoutCurrentUser ()' на моем MainDrawer

kivul 22.11.2018 10:54

нет screenProps, это просто образец имени, в вашем случае это будет logoutCurrentUser = {this.logoutCurrentUser}

Cristian Gomez 22.11.2018 10:58

все еще безуспешно, извините, такая же ошибка: props.logoutCurrentUser не является функцией ~ undefined (я обновил вопрос тем, что у меня есть прямо сейчас)

kivul 22.11.2018 11:00

если я помещаю console.info (props) внутри onClick (), logoutCurrentUser также не отображается

kivul 22.11.2018 11:05
Ответ принят как подходящий

Итак, я нашел обходной путь, я добавил mapDispatchToProps с функцией, которую хочу вызывать при нажатии кнопки:

const mapDispatchToProps = (dispatch) => {
  return {
    dispatch,
    logoutCurrentUser: () => {
      console.info("LOGOUT PRESSED")
    }
  }
}

Затем на моем класс AppNavigation я сделал это:

render() {
  return <RootNavigator screenProps = {this.props} />
}

А свой Главный ящик я поменял на этот

const MainDrawer = createDrawerNavigator(
{
  Home: { screen: HomeScreen },
}, {
  contentComponent: (props) => (
    <View style = {{ flex: 1 }}>
      <SafeAreaView forceInset = {{ top: 'always', horizontal: 'never' }}>
        <DrawerItems {...props} />
        <Button
          color='red'
          title='Logout'
          onPress = {() => { props.screenProps.logoutCurrentUser() }}
        />
      </SafeAreaView>
    </View>
  ),
})

Оставьте ответ здесь на случай, если у кого-то еще возникнет такая же проблема.

Другие вопросы по теме