[英]react native - Passing navigation props from parent to child
I'm trying to create a simple-ish mobile app, but I'm pretty new to this.我正在尝试创建一个简单的移动应用程序,但我对此很陌生。 I've spent some time searching about the errors I'm getting.
我花了一些时间搜索我遇到的错误。 It seems like a common problem, but they all had the same/similar solutions but the solutions didn't work for me.
这似乎是一个常见问题,但他们都有相同/相似的解决方案,但这些解决方案对我不起作用。
What is I'm trying to do?我想做什么? Right now the app is two pages, the home screen (Overview Cards) and the Add Card screen.
现在该应用程序有两个页面,主屏幕(概览卡)和添加卡屏幕。
However, I am getting stuck at Step 3. I am trying to make the Save button navigate the user back to Overview Cards, but there are simply errors instead.但是,我被困在第 3 步。我试图让“保存”按钮将用户导航回概览卡,但只是出现了错误。
Below is my code, the errors I'm getting, and then what I've tried.下面是我的代码,我得到的错误,然后是我尝试过的。
App.js应用程序.js
import React from 'react';
import { StyleSheet, Text, TextInput, View, Button, TouchableOpacity, ShadowPropTypesIOS } from 'react-native';
import AddCard from './components/AddCard.js';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { useNavigation } from '@react-navigation/native';
function HomeScreen({ navigation }) {
return (
<View style={styles.homeContainer}>
<Button title="Add Card" onPress={() => navigation.navigate('Add Card')}/>
{/* <Text value={this.props.inputValFT}/> */}
<Text style={styles.textStyle} >VISA xxxx</Text>
<Text style={styles.textStyle}>MASTERCARD xxxx</Text>
<Text style={styles.textStyle}>AMEX xxxx</Text>
</View>
);
}
function AddCardScreen() {
return (
<View style={styles.addCardContainer}>
<AddCard navigation={this.props.navigation} /> // **HERE**
</View>
);
}
const Stack = createStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} options={{ title: 'Overview Cards' }} />
<Stack.Screen name="Add Card" component={AddCardScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
// function AddCardButton(){
// return (
// <View style={styles.buttonContainer}>
// <TouchableOpacity>
// <Text style={styles.button}>Add Card</Text>
// </TouchableOpacity>
// </View>
// );
// }
export default App;
const styles = StyleSheet.create({
homeContainer: {
flex: 1,
backgroundColor: '#ef95b1',
alignItems: 'center',
justifyContent: 'flex-start',
},
addCardContainer: {
flex: 1,
backgroundColor: '#28cdf0',
justifyContent: 'flex-start',
},
buttonContainer: {
flexDirection: 'row',
alignSelf: 'flex-end',
marginTop: 15,
},
button: {
flexDirection: 'row',
alignSelf: 'flex-end',
marginTop: 15,
right: 10,
backgroundColor: '#2565ae',
borderWidth: 1,
borderRadius: 12,
color: 'white',
fontSize: 15,
fontWeight: 'bold',
overflow: 'hidden',
padding: 10,
textAlign:'center',
},
textStyle: {
padding: 10,
}
});
Navigation.js导航.js
import React, { Component } from 'react';
import { View, Text } from 'react-native';
import { createAppContainer } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
import AddCardScreen from './AddCard';
const RootStack = createStackNavigator(
{
Home: HomeScreen,
AddCard: AddCardScreen,
},
{
initialRouteName: 'Home',
}
);
const AppContainer = createAppContainer(RootStack);
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#ef95b1',
alignItems: 'center',
justifyContent: 'flex-start',
},
textStyle: {
padding: 10,
}
});
export default createAppContainer(Navigation);
AddCard.js AddCard.js
import React, { Component } from 'react';
import { StyleSheet, View, Text, TextInput, TouchableOpacity } from 'react-native';
import { Input } from 'react-native-elements'
import { ScrollView } from 'react-native-gesture-handler';
// import { loadSettings, saveSettings } from '../storage/settingsStorage';
class AddCardScreen extends Component {
constructor(props) {
super(props);
this.state = {
firstTwo : '',
lastFour : '',
recentAmt : ''
};
this.addFT = this.addFT.bind(this)
this.addLF = this.addLF.bind(this)
this.addRecAmt = this.addRecAmt.bind(this)
}
static navigationOptions = {
title: 'Add Card'
};
addFT(firstTwo) {
this.setState(Object.assign({}, this.state.firstTwo, { firstTwo }));
}
addLF(lastFour) {
this.setState(Object.assign({}, this.state.lastFour, { lastFour }));
}
addRecAmt(recentAmt) {
this.setState(Object.assign({}, this.state.recentAmt, { recentAmt }));
}
// handleSubmit() {
// alert('New card saved. Returning to Home to view addition.');
// navigation.navigate('Home')
// } // firstTwo, lastFour, recentAmt
render() {
const {navigation} = this.props;
return (
<ScrollView>
<View style={styles.inputContainer}>
<Text h1> "Add a new card!" </Text>
<TextInput
style={styles.textInput}
placeholder="First two digits of card"
placeholderTextColor="#000000"
keyboardType={'number-pad'}
maxLength = {2}
onChangeText={this.addFT}
inputValFT={this.state.firstTwo}
/>
<TextInput
style={styles.textInput}
placeholder="Last four digits of card"
placeholderTextColor="#000000"
keyboardType={'number-pad'}
maxLength = {4}
onChangeText={this.addLF}
inputValLF={this.state.lastFour}
/>
<TextInput
style={styles.textInput}
placeholder="Most recent dollar amount"
placeholderTextColor="#000000"
keyboardType={'decimal-pad'}
onChangeText={this.addRecAmt}
inputValRA={this.state.recentAmt}
/>
</View>
<View style={styles.inputContainer}>
<TouchableOpacity
style={styles.saveButton}
onPress={() => navigation.navigate('Home')}> // ** HERE 2 **
<Text style={styles.saveButtonText}>Save</Text>
</TouchableOpacity>
</View>
</ScrollView>
);
}
}
// this.handleSubmit.bind(this)
export default AddCardScreen;
const styles = StyleSheet.create({
inputContainer: {
paddingTop: 15
},
textInput: {
borderColor: '#FFFFFF',
textAlign: 'center',
borderTopWidth: 1,
borderBottomWidth: 1,
height: 50,
fontSize: 17,
paddingLeft: 20,
paddingRight: 20
},
saveButton: {
borderWidth: 1,
borderColor: '#007BFF',
backgroundColor: '#007BFF',
padding: 15,
margin: 5
},
saveButtonText: {
color: '#FFFFFF',
fontSize: 20,
textAlign: 'center'
}
});
The errors I'm getting:我得到的错误:
In App.js you can see the ** HERE ** that I put in. When I try to run this, the app loads fine until I click the "Add Card" button.在 App.js 中,您可以看到我输入的 ** HERE **。当我尝试运行它时,应用程序加载正常,直到我单击“添加卡”按钮。 I get this error:
undefined is not an object (evaluating 'this.props.navigation')
.我收到此错误:
undefined is not an object (evaluating 'this.props.navigation')
。
If I take the navigate={this.props.navigation}
part out from App.js, the app loads as it's meant to again, but this time I can click the "Add Card" button and reach the next screen with no issue.如果我从 App.js 中取出
navigate={this.props.navigation}
部分,应用程序会再次按预期加载,但这次我可以单击“添加卡”按钮并毫无问题地进入下一个屏幕。 I fill out the form (TextInput parts in AddCard.js), but when I click the "Save" button, the app crashes.我填写了表单(AddCard.js 中的 TextInput 部分),但是当我单击“保存”按钮时,应用程序崩溃了。 The error is:
TypeError: undefined is not an object (evaluating 'navigation.navigate')
.错误是:
TypeError: undefined is not an object (evaluating 'navigation.navigate')
。 Most likely because of what I'm doing with onPress where it says ** HERE 2 ** in AddCard.js.很可能是因为我在 onPress 上所做的事情,它在 AddCard.js 中显示 ** HERE 2 **。 handleSubmit() is currently commented out, but it used to be inside the onPress.
handleSubmit() 目前已被注释掉,但它曾经在 onPress 内部。
What I've tried:我试过的:
Some of the answers I saw were that I need to pass in navigation from the parent to the child and that will make it work.我看到的一些答案是我需要将导航从父级传递给子级,这将使它起作用。 By trying that, I get the errors I mentioned earlier.
通过尝试,我得到了我之前提到的错误。 I also saw that someone mentioned using "withNavigation" or "useNavigation" which was supposed to allow the child to access navigation, but that didn't work for me either.
我还看到有人提到使用“withNavigation”或“useNavigation”应该允许孩子访问导航,但这对我也不起作用。 Below are some of the links that I was trying to follow.
以下是我尝试关注的一些链接。
How do I pass navigation props from parent component to header? 如何将导航道具从父组件传递到 header?
Pass navigation.navigate to Child Component 将 navigation.navigate 传递给子组件
https://reactnavigation.org/docs/use-navigation/ https://reactnavigation.org/docs/use-navigation/
Thank you for reading, hopefully my explanation is clear enough.感谢您的阅读,希望我的解释足够清楚。
I think your problem is somewhere here:我认为您的问题出在此处:
function AddCardScreen({ navigation }) {
return (
<View style={styles.addCardContainer}>
<AddCard navigation={navigation} />
</View>
);
}
this
, you're not in a class component, therefore this
doesn't existsthis
,你不在 class 组件中,因此this
不存在navigation
and not navigate
, since that's how you try to access it in the child component.navigation
而不是navigate
,因为这就是您尝试在子组件中访问它的方式。navigation
prop needs to be destructured inside the function argument function AddCardScreen({ navigation })
, same as you already do for HomeScreen
. navigation
道具需要在 function 参数function AddCardScreen({ navigation })
中进行解构,就像您已经为HomeScreen
所做的一样。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.