我正在开发React Native应用。我看到一个问题,可以导航到使用Apollo graphql查询适配器生成的屏幕。当我导航到该屏幕时,我无权访问导航对象。该应用程序包装在StackNavigator中,导航似乎工作正常。知道要访问导航对象该怎么做吗?
下面是App.js文件中的配置:
const RootStack = createStackNavigator(
{
Login: LoginScreen,
Main: MainScreen,
Crews: CrewsScreen,
Customer: CustomerScreen,
Reports: ReportsScreen,
Signup: SignupScreen,
Customers: CustomersScreen,
Tasks: TasksScreen,
Task: TaskScreen,
Test: TestScreen,
NewCrew: NewCrewScreen,
SkipTask: SkipTaskScreen
},
{
initialRouteName: 'Main',
}
);
const AppContainer = createAppContainer(RootStack);
export class App extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<ApolloProvider client={client}>
<Rehydrated>
<AppContainer screenProps={{...this.props}}/>
</Rehydrated>
</ApolloProvider>
);
}
}
问题出在SkipTask屏幕上。以下是“跳过屏幕”页面:
..
render() {
const {
navigation
} = this.props;
return ( <
View style = {
{
flexDirection: 'column',
marginHorizontal: 5,
marginVertical: 5,
height: 200,
borderWidth: 1,
borderColor: '#1abc9c'
}
} >
<
View style = {
{
flex: 1,
flexDirection: 'row',
padding: 1,
backgroundColor: '#B1EAC6',
alignItems: 'center'
}
} >
<
View style = {
[{
flex: 1,
height: 15,
marginVertical: 1,
marginHorizontal: 4,
alignItems: 'center'
}]
} >
<
Text style = {
{
fontSize: 14,
fontWeight: 'bold'
}
} > {
this.props.scheduledDate
} < /Text> <
/View> <
/View> <
View style = {
{
flex: 1,
flexDirection: 'row',
padding: 4
}
} >
<
View style = {
{
flex: 0.70,
marginTop: 12,
flexGrow: 0.7,
width: 0,
flexDirection: 'column'
}
} >
<
Text style = {
{
fontSize: 20,
fontWeight: 'bold',
flexShrink: 0.7,
width: 'auto',
color: 'red'
}
} > {
this.props.customerName
} < /Text> <
/View> <
View style = {
[{
flex: 0.30,
height: 35,
marginVertical: 1,
marginHorizontal: 4,
alignItems: 'center',
backgroundColor: '#1abc9c',
borderRadius: 15
}]
} >
<
Button title = "Start"
color = "white"
onPress = {
() => {
return false
}
}
/> <
/View> <
/View> <
View style = {
{
flex: 1,
flexDirection: 'row',
padding: 4
}
} >
<
View style = {
{
flex: 0.70,
marginTop: 12
}
} >
<
Text style = {
{
fontSize: 14,
fontWeight: 'bold'
}
} > {
this.props.address
} < /Text> <
/View> <
View style = {
[{
flex: 0.30,
height: 35,
marginVertical: 1,
marginHorizontal: 4,
alignItems: 'center',
backgroundColor: '#1abc9c',
borderRadius: 15
}]
} >
<
Button title = "Skip"
color = "white"
onPress = {
() => {
this.props.navigation.navigate("Tasks")
}
}
/> <
/View> <
/View> <
View style = {
{
flex: 1,
flexDirection: 'row',
padding: 4
}
} >
<
View style = {
{
flex: 0.70,
marginTop: 12
}
} >
<
Text style = {
{
fontSize: 14,
fontWeight: 'bold'
}
} > {
this.props.phoneNumber
} < /Text> <
/View> <
View style = {
[{
flex: 0.30,
height: 35,
marginVertical: 1,
marginHorizontal: 4,
alignItems: 'center',
backgroundColor: '#1abc9c',
borderRadius: 15
}]
} >
<
Button title = "Call"
color = "white"
onPress = {
() => this.makeCall(this.props.phoneNumber)
}
/> <
/View> <
/View>
<
/View>
);
}
..
下面是我要导航到skipTask屏幕的页面的片段:
..
const TaskAdapter = props => {
if (props.data.loading) {
return <View > < Text > Loading tasks < /Text></View >
}
if (props.data.getAllTasks) {
return ( <
ScrollView > {
props.data.getAllTasks.map(task =>
<
Task key = {
task.id
}
customerName = {
task.customer.customerName
}
phoneNumber = {
task.customer.phoneNumber
}
scheduledDate = {
task.scheduledDate
}
address = {
getCustomerAddress(task.customer.streetAddress, task.customer.city, task.customer.state, task.customer.zipCode)
}
/>
)
} <
/ScrollView>
);
}
return <View > < Text > No tasks found < /Text></View >
};
const AllTasks = graphql(tasksList, {
options: (props => ({
variables: {
crewID: props.crewID,
date: props.date
},
fetchPolicy: "network-only"
}))
})(TaskAdapter);
..
..
render() {
console.log("********************* " + JSON.stringify(this.props.navigation))
return ( <
SafeAreaView style = {
{
flex: 1
}
} >
<
ToolBar / >
<
View style = {
styles.top
} > < Text style = {
styles.title
} > Task List < /Text></View >
<
CrewsDropdown stateHandler = {
this.stateHandler
}
/> <
AllTasks navigation = {
{ ...this.props.navigation
}
}
crewID = {
this.state.crew.id
}
date = {
this.state.date
}
/> <
TasksListFooter navProps = {
{ ...this.props
}
}
crew = {
this.state.crew
}
/> <
/SafeAreaView>
);
}
}
..
任务屏幕的导出如下:
import React, {
Component
} from 'react';
import {
View,
Text,
Button,
TextInput,
StyleSheet
} from 'react-native';
import call from 'react-native-phone-call';
import {
Linking
} from 'react-native';
export default class Task extends Component {
constructor(props) {
super(props);
}
makeCall = (number) => {
const args = {
number: number, // String value with the number to call
prompt: true // Optional boolean property. Determines if the user should be prompt prior to the call
}
call(args).catch(console.error)
}
我能够通过以下操作解决此问题:
render() {
return (
<SafeAreaView style={{flex: 1}}>
<ToolBar/>
<View style={styles.top}><Text style={styles.title}>Task List</Text></View>
<CrewsDropdown stateHandler={this.stateHandler}/>
<AllTasks navigation={this.props.navigation} crewID={this.state.crew.id} date={this.state.date}/>
<TasksListFooter navProps={{...this.props}} crew={this.state.crew}/>
</SafeAreaView>
);
}
我基本上将导航属性从主要组件添加到AllTasks适配器,如以下行所示:
<AllTasks navigation={this.props.navigation} crewID={this.state.crew.id} date={this.state.date}/>
然后我将该属性添加到任务组件,在其中我要启用导航,如下所示:
<ScrollView>
{
props.data.getAllTasks.map(task =>
<Task key={task.id} customerName={task.customer.customerName}
phoneNumber={task.customer.phoneNumber}
scheduledDate={task.scheduledDate}
navigation={props.navigation}
address={getCustomerAddress(task.customer.streetAddress, task.customer.city, task.customer.state, task.customer.zipCode)}
/>
)
}
</ScrollView>
我的错误是我使用this.props.navigation而不是props.navigation。