来自组件的反应导航与博览会
Posted
技术标签:
【中文标题】来自组件的反应导航与博览会【英文标题】: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
【问题讨论】:
您好,先生,已更新错误日志。 【参考方案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 具有关闭标签,例如
"<View></View>"
或 "<Text></Text>",
但这是一个自定义组件,因为它只属于你,而不是所有反应原生开发者。另外,您导入的“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/
【讨论】:
以上是关于来自组件的反应导航与博览会的主要内容,如果未能解决你的问题,请参考以下文章