【问题标题】:React Navigation from Component with expo来自组件的反应导航与博览会
【发布时间】:2020-04-23 06:09:24
【问题描述】:

我正在尝试从另一个主要从屏幕调用的组件内部使用 React Navigation。 层次结构:登录屏幕有一个按钮组件,该组件设计了一个 TouchableOpacity 组件,并且该登录按钮应该调用另一个屏幕 Home。

login.js

import React, { Component } from "react";
import { StyleSheet, View, Text, Button } from "react-native";
import { withNavigation } from 'react-navigation';
import CupertinoButtonSuccess from "../components/CupertinoButtonSuccess";
import CupertinoButtonWarning1 from "../components/CupertinoButtonWarning1";
import MaterialIconTextbox from "../components/MaterialIconTextbox";

//function Login(props) {
  export default class Login extends Component {
    static navigationOptions = {
      headerShown: false
    };

    render() {
  return (
    <View style={styles.container}>
      <Text style={styles.coMproTech1}>COMproTECH</Text>
      <View style={styles.rectStack}>
        <View style={styles.rect}>
          <CupertinoButtonSuccess
            Navigation={this.props.navigation}
            text1="Login"
            style={styles.cupertinoButtonSuccess}
          ></CupertinoButtonSuccess>
          <CupertinoButtonWarning1
            text1="Forgot Password"
            style={styles.cupertinoButtonWarning1}
          ></CupertinoButtonWarning1>
          <Button  title='test' onPress={this.handleClick}></Button>
        </View>
        <View style={styles.rect2}></View>
        <MaterialIconTextbox
          textInput1="Enter email"
          icon1Name="account"
          style={styles.materialIconTextbox}
        ></MaterialIconTextbox>
        <MaterialIconTextbox
          icon1Name="account-key"
          textInput1="Password"
          style={styles.materialIconTextbox2}
        ></MaterialIconTextbox>
      </View>
      <Text style={styles.services1}>Services</Text>
    </View>
  );
}
  }

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "rgba(74,144,226,1)"
  },
  coMproTech1: {
    color: "rgba(247,242,242,1)",
    fontSize: 36,
    fontFamily: "Cochin-BoldItalic",
    marginTop: 110,
    marginLeft: 16
  },
  rect: {
    top: 19,
    left: 0,
    width: 342,
    height: 319,
    backgroundColor: "rgba(255,255,255,1)",
    position: "absolute",
    borderRadius: 20,
    borderBottomRightRadius: 20
  },
  cupertinoButtonSuccess: {
    width: 65,
    height: 39,
    borderRadius: 6,
    marginTop: 200,
    marginLeft: 261
  },
  cupertinoButtonWarning1: {
    width: 167,
    height: 44,
    borderRadius: 10,
    marginTop: 9,
    marginLeft: 159
  },
  rect2: {
    top: 0,
    left: 48,
    width: 42,
    height: 42,
    backgroundColor: "rgba(255,255,255,1)",
    position: "absolute",
    transform: [
      {
        rotate: "45.00deg"
      }
    ],
    borderRadius: 7
  },
  materialIconTextbox: {
    top: 59,
    left: 0,
    width: 343,
    height: 48,
    position: "absolute"
  },
  materialIconTextbox2: {
    top: 141,
    left: 0,
    width: 343,
    height: 48,
    position: "absolute"
  },
  rectStack: {
    width: 343,
    height: 338,
    marginTop: 125,
    marginLeft: 16
  },
  services1: {
    color: "rgba(247,242,242,1)",
    fontSize: 36,
    fontFamily: "Cochin-BoldItalic",
    marginTop: -450,
    marginLeft: 18
  }
});

//export default Login;

CupertinoSuccess.js

import React, { Component } from "react";
import { StyleSheet, TouchableOpacity, Text, Button } from "react-native";
import { withNavigation } from 'react-navigation';
import { NavigationInjectedProps } from 'react-navigation';
import { createStackNavigator } from "react-navigation-stack";


function CupertinoButtonSuccess(props) {
  return (
    <TouchableOpacity
    onPress={() => this.props.navigation.goBack()}
    style={[styles.container, props.style]}>
      <Text style={styles.caption}>{props.text1 || "Button"}</Text>
    </TouchableOpacity>
  );
}

const styles = StyleSheet.create({
  container: {
    backgroundColor: "#4CD964",
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "center",
    paddingRight: 12,
    paddingLeft: 12,
    borderRadius: 5
  },
  caption: {
    color: "#fff",
    fontSize: 17,
    //fontFamily: "Cochin-BoldItalic"
  }
});

export default CupertinoButtonSuccess;

得到错误/异常:

undefined object 'this.props'

TypeError: undefined is not an object (evaluating '_this.props')

createReactClass$argument_0.touchableHandlePress
    D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Components\Touchable\TouchableOpacity.js:264:45
touchableHandlePress
    [native code]:0
TouchableMixin._performSideEffectsForTransition
    D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Components\Touchable\Touchable.js:880:34
_performSideEffectsForTransition
    [native code]:0
TouchableMixin._receiveSignal
    D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Components\Touchable\Touchable.js:779:44
_receiveSignal
    [native code]:0
TouchableMixin.touchableHandleResponderRelease
    D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Components\Touchable\Touchable.js:490:24
touchableHandleResponderRelease
    [native code]:0
invokeGuardedCallbackImpl
    D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:307:15
invokeGuardedCallback
    D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:531:36
invokeGuardedCallbackAndCatchFirstError
    D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:555:30
executeDispatch
    D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:722:42
executeDispatchesInOrder
    D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:744:20
executeDispatchesAndRelease
    D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:907:29
forEach
    [native code]:0
forEachAccumulated
    D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:887:16
runEventsInBatch
    D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:932:21
runExtractedPluginEventsInBatch
    D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:1096:19
batchedUpdates$argument_0
    D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:2796:6
batchedUpdates$1
    D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:18791:14
batchedUpdates
    D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:2709:30
batchedUpdates$argument_0
    D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:2794:17
receiveTouches
    D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:2870:28
__callFunction
    D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:436:47
__guard$argument_0
    D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:111:26
__guard
    D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:384:10
__guard$argument_0
    D:\Android Projects\React_Projects\SplashNav\snav\node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:110:17
callFunctionReturnFlushedQueue
    [native code]:0

【问题讨论】:

  • 您好,先生,已更新错误日志。

标签: components undefined react-navigation expo react-props


【解决方案1】:

您有一个带有props 参数的函数组件:

function CupertinoButtonSuccess(props) {
  // ...
}

在里面,你正在使用this.props.navigation.goBack()。但是this.props在函数组件中不可用。您需要将其更改为使用props.navigation.goBack()(不带this)。

【讨论】:

  • 嗨,先生,我是新来的本地人,你能帮我解决这个问题吗?我试过没有“这个”。但也没有工作,我如何将函数 CupertinoButtonSuccess(props) 更改为类 CupertinoButton 因为当我尝试时,它说未定义的道具。
  • 如果你是 React Native 新手,你应该阅读官方 React 文档并熟悉 React
【解决方案2】:

关于反应导航,尤其是您正在使用的堆栈导航,您需要了解一些事情。当前版本是导航5。

它允许您在作为组件传递的屏幕之间导航 下到反应导航的文件,让我们调用那个配置文件 应用程序.js。在您的情况下,您的屏幕是“主页”和“登录”,其中 意味着您应该拥有 Home.js 和 Login.js 组件或 在你的项目中设置的函数。

//这是 App.js 的最低配置 // 注意,'@' 对导航很重要 5

import React from 'react';
import { createStackNavigator } from '@react-navigation/stack';
import { NavigationContainer } from '@react-navigation/native';
import Home from './Home';
import Login from './Login';

const Stack  = createStackNavigator();

export default class App extends React.Component {

 render() {
    return (
      <NavigationContainer>
        <Stack.Navigator initialRouteName='Home'>
           <Stack.Screen name='Home'    component={Home} />
           <Stack.Screen name='Login' }  component={Login} />
        </Stack.Navigator>
      </NavigationContainer>
    );
  }
}

你的 Login.js 组件和你做的一样,但是你应该将导航道具传递给 CupertinoButtonSuccess 和 CupertinoButtonWarnings,否则它们无法自动访问导航道具,因为你没有在导航配置文件中将它们定义为屏幕。为此,您只需在 Login.js 的 render 方法中使用它

render(){ 
  return(
 <CupertinoButtonSuccess navigation={navigation} /> 
 <CupertinoButtonWarning1 navigation={navigation} /> 
);
}

而不是

render(){
return(
<CupertinoButtonSuccess Navigation={this.props.navigation}
           ... > </CupertinoButtonSuccess>
<cupertinoButtonWarning1 Navigation={this.props.navigation}
           ... >
</cupertinoButtonWarning1> 
);
}

(您甚至永远不会在 react native 中关闭像这样的自定义组件。只有内置​​的 react native 组件,例如我们的 View,Text 具有关闭标签,例如 "&lt;View&gt;&lt;/View&gt;""&lt;Text&gt;&lt;/Text&gt;", 但这是一个自定义组件,因为它只属于你,而不是所有反应原生开发者。另外,您导入的“CupertinoButtonWarning1”以大写字母“C”开头,现在将其称为“cupertinoButtonWarning1”是另一个错误,但我希望这只是输入错误。

现在关于如何制作 CupertinoButtonSuccess 类组件而不是基于函数的组件,您将需要创建两个基于类的组件,一个用于 CupertinoButtonSuccess.js,第二个用于 CupertinoButtonWarning1.js,因为您无法从相同的单个组件。

// 所以对于 CupertinoButtonSuccess.js

import React, { Component } from "react";
import { StyleSheet, TouchableOpacity, Text, Button } from "react-native";
//You never need to be calling { createStackNavigator } here again because //CupertinoButtonSuccess.js is not a screen
 export default class CupertinoButtonSuccess extends Component {
   render(){
       return (
    <TouchableOpacity
    onPress={() => this.props.navigation.goBack('Home')}
    style={[styles.container, props.style]}>
      <Text style={styles.caption}>{props.text1 || "Button"}</Text>
    </TouchableOpacity>
  );
}
}
const styles = StyleSheet.create({
   //Your style here
});

//对于 CupertinoButtonWarning1.js 你也这样做。

最后,为了完整起见,还有另一种方法可以直接在 CupertinoButtonSuccess.js 和 CupertinoButtonWarning1 中使用导航道具,而无需等待 Loging.js 将其传递给它们,它是通过像这样导入“useNavigation” CupertinoButtonSuccess.js 和 CupertinoButtonWarning1.js :

import { useNavigation } from '@react-navigation/native';

这样,您甚至可以从 CupertinoButtonSuccess.js 和 CupertinoButtonWarning1.js 访问导航道具。 关于这个的文档在这里https://reactnavigation.org/docs/connecting-navigation-prop/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-01
    • 2022-10-23
    • 2022-08-19
    • 1970-01-01
    • 1970-01-01
    • 2021-11-08
    • 1970-01-01
    • 2021-10-17
    相关资源
    最近更新 更多