undefined не является объектом (оценка this.props.navigation.navigate)

Пытаюсь научиться реагировать на родной впервые. Я попытался ввести навигатор по стеку, но строка const {navigate} = this.props.navigation; вызывает ошибку:

undefined не является объектом (оценка this.props.navigation.navigate)

Вот мой код:

import React, { Component } from "react";
import { StackNavigator } from "react-navigation";
import { AppRegistry, Text, View } from "react-native";

export default class App extends Component {
  static navigationOptions = {
    title: "Login",
    headerStyle: {
      backgroundColor: "#000000"
    },
    headerTitleStyle: {
      color: "#fff"
    }
  };

  constructor(props) {
    super(props);
  }
  render() {
    console.log(this.props);

    const { navigate } = this.props.navigation;
    return (
      <View>
        <Text>Hello</Text>
      </View>
    );
  }
}

const myscreens = StackNavigator({
  Home: { screen: App }
});
AppRegistry.registerComponent("app", () => myscreens);

Что я делаю не так и как это исправить?

Я также должен упомянуть, что props пуст в функции рендеринга и в конструкторе.

вот мой package.json на всякий случай

{
  "name": "myapp",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start",
    "test": "jest"
  },
  "dependencies": {
    "react": "16.0.0-alpha.12",
    "react-native": "0.48.3",
    "react-navigation": "git+https://github.com/react-community/react-navigation.git"
  },
  "devDependencies": {
    "babel-jest": "21.0.2",
    "babel-preset-react-native": "4.0.0",
    "jest": "21.1.0",
    "react-test-renderer": "16.0.0-alpha.12"
  },
  "jest": {
    "preset": "react-native"
  }
}

А вот и мой index.android.js

import React, { Component } from 'react';
import App from './components/app';
import {
  AppRegistry,
  View
} from 'react-native';

export default class myapp extends Component {
  render() {
    return (
        <App />
    );
  }
}


AppRegistry.registerComponent('myapp', () => myapp);

person John    schedule 18.09.2017    source источник
comment
Я только что создал новый проект с установленным react-navigation и не получил ошибок. Может выложить свой package.json?   -  person Michael Cheng    schedule 18.09.2017
comment
@MichaelCheng, хорошо, спасибо, я только что добавил свои package.json и index.android.js. Надеюсь, это поможет?   -  person John    schedule 18.09.2017


Ответы (1)


Две ошибки:

  1. Тебе не следует так звонить AppRegistry дважды. Вы можете удалить его из своего app.js файла.

  2. Вы неправильно понимаете, как работают роутеры react-navigation. StackNavigator (а также вкладка и ящик) - это компоненты, которые необходимо визуализировать либо напрямую (например, то, что вы передаете в AppRegistry [A]), либо в какой-то момент вашего приложения [B].

Итак, чтобы исправить это, вы захотите экспортировать myscreens вместо App. Чтобы проиллюстрировать оба способа сделать это:

A. Вы можете увидеть пример этого в документации, но поскольку вы разбиваете свой код на два файла, это будет выглядеть так:

./components/app.js

import React, { Component } from 'react';
import { StackNavigator } from 'react-navigation';
import { Text, View } from 'react-native';

class App extends Component {
  static navigationOptions = {
    title: 'Login',
    headerStyle: {
      backgroundColor: '#000000',
    },
    headerTitleStyle: {
      color: '#fff',
    },
  };

  constructor(props) {
    super(props);
  }
  render() {
    console.log(this.props);

    const { navigate } = this.props.navigation;
    return (
      <View>
        <Text>Hello</Text>
      </View>
    );
  }
}

const myscreens = StackNavigator({
  Home: { screen: App },
});

export default myscreens;

index.android.js

import { AppRegistry } from 'react-native';
import myscreens from './components/app';

AppRegistry.registerComponent('myapp', () => myscreens);

Б. Вы визуализируете StackNavigator в другом классе, а затем экспортируете класс, который его визуализирует. Это больше соответствует тому, что вы уже делаете, и является более гибким в долгосрочной перспективе (например, вам нужно будет сделать это, если вы используете redux в какой-то момент), поэтому вам, вероятно, следует сделать это следующим образом:

./components/app.js. Обратите внимание на изменение регистра с myscreens на MyScreens. Это необходимо, поскольку React Native будет пожаловаться на это как строчные JSX-теги считаются HTML. Использование AppRegistry напрямую не привело к возникновению этой ошибки, поскольку вы не используете myscreens в JSX.

import React, { Component } from 'react';
import { StackNavigator } from 'react-navigation';
import { Text, View } from 'react-native';

class App extends Component {
  static navigationOptions = {
    title: 'Login',
    headerStyle: {
      backgroundColor: '#000000',
    },
    headerTitleStyle: {
      color: '#fff',
    },
  };

  constructor(props) {
    super(props);
  }
  render() {
    console.log(this.props);

    const { navigate } = this.props.navigation;
    return (
      <View>
        <Text>Hello</Text>
      </View>
    );
  }
}

const MyScreens = StackNavigator({
  Home: { screen: App },
});

export default MyScreens;

index.android.js

import React, { Component } from 'react';
import { AppRegistry } from 'react-native';
import MyScreens from './components/app';

export default class myapp extends Component {
  render() {
    return <MyScreens />;
  }
}

AppRegistry.registerComponent('myapp', () => myapp);
person Michael Cheng    schedule 18.09.2017