我的主页上有 2 个listview
(TodoDetail.js
和TodoDetailChecked.js
),这listview
行中有TouchableOpacity
个。当我点击这个TouchableOpacity
时,我想转到Profile.js
页面。 但问题是当我点击时,它找不到props.navigation.navigate
。 我试图在componentDidMount
中捕捉日志,但对导航一无所知。
componentDidMount() {
console.log(this.props);
}
请帮帮我...
这是代码;
待办事项详细信息.js
import React, { Component } from 'react';
import { Card, Icon } from 'react-native-elements';
// import Checkbox from '../components/Checkbox';
import { Text, View, TouchableOpacity } from 'react-native';
import * as firebase from 'firebase';
import {
Menu,
MenuOptions,
MenuOption,
MenuTrigger,
} from 'react-native-popup-menu';
class TodoDetail extends Component {
componentDidMount() {
console.log(this.props.navigation.navigate('TodoDetail'));
}
clickText() {
const { todo } = this.props.todos;
// const { navigate } = this.props.navigation;
return (
<TouchableOpacity onPress={this.seeDetail.bind(this)} >
<Text numberOfLines={1}> {todo} </Text>
</TouchableOpacity>
);
}
seeDetail() {
const { navigate } = this.props.navigation;
navigate("Profile", { name: "Jane" });
console.log('click');
}
render() {
//Serverdan çekilenler
const uid = this.props.todos.uid;
const success = this.props.todos.success;
//Tarih olayları
const date = new Date();
const day = date.getDate();
const tomorrow = day + 1;
const year = date.getFullYear();
const month = date.getMonth();
//Style tanımlama
const { container, iconContainer, subContainer } = styles;
if (success === 0) {
return (
<Card>
<View style={container}>
<View style={iconContainer}>
<TouchableOpacity onPress={() => firebase.database().ref(`todos/personal/${uid}/success`).set(1)} >
<Icon name='check-box-outline-blank' />
</TouchableOpacity>
<View style={subContainer}>
{this.clickText()}
</View>
<View style={iconContainer}>
<Menu>
<MenuTrigger>
<Icon name='keyboard-arrow-down' />
</MenuTrigger>
<MenuOptions>
<MenuOption onSelect={() => firebase.database().ref(`todos/personal/${uid}/date`).set({ day, year, month })} >
<Text style={{ color: 'black' }} > Son Tarihi Bugün </Text>
</MenuOption>
<MenuOption onSelect={() => firebase.database().ref(`todos/personal/${uid}/date`).set({ day: tomorrow, year, month })} >
<Text style={{ color: 'black' }} > Son Tarihi Yarın </Text>
</MenuOption>
<MenuOption onSelect={() => firebase.database().ref(`todos/personal/${uid}/date`).remove()} >
<Text style={{ color: 'black' }} > Son Tarihi Kaldır </Text>
</MenuOption>
<MenuOption onSelect={() => firebase.database().ref(`todos/personal/${uid}`).remove()} >
<Text style={{ color: 'red' }} > Yapılacak İşi Sil </Text>
</MenuOption>
</MenuOptions>
</Menu>
</View>
</View>
</View>
</Card>
);
} else
if (success === 1) {
return (
null
);
}
}
}
待办事项列表.js
createDataSource({ studentsArray }) {
const ds = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2
});
this.dataSource = ds.cloneWithRows(studentsArray.reverse());
}
changeScreen() {
this.setState({ screenSize: false });
}
changeScreenBack() {
this.setState({ screenSize: true });
}
renderRow(todos) {
return <TodoDetail todos={todos} />;
}
renderRow2(todos) {
return <TodoDetailChecked todos={todos} />;
}
render() {
// const { navigate } = this.props.navigation;
const { container, inputContainer, inputText } = styles;
if (!this.state.screenSize) {
return (
<View style={container} >
<View style={inputContainer} >
<Icon name={'add'} />
<TextInput
style={inputText}
underlineColorAndroid='transparent'
placeholder="Yapılacak iş ekle..."
placeholderTextColor="#FFFFFF"
value={this.props.todo}
onChangeText={todo => this.props.todoChanged(todo)}
/>
<Button
onPress={this.addToDo.bind(this)}
title="Ekle"
color="#841584"
accessibilityLabel="Learn more about this purple button"
/>
</View>
<View style={{ flex: 1 }}>
<View style={{ flex: 1 }}>
<ListView
enableEmptySections
dataSource={this.dataSource}
renderRow={this.renderRow}
/>
</View>
<View style={{ flex: 1 }}>
<View style={{ height: 1, backgroundColor: 'gray' }} />
<ListView
enableEmptySections
dataSource={this.dataSource}
renderRow={this.renderRow2}
/>
</View>
</View>
<Button
onPress={this.changeScreenBack.bind(this)}
title="Tamamlananları Gizle"
color="#841584"
/>
</View>
);
} else
if (this.state.screenSize) {
return (
<View style={container} >
<View style={inputContainer} >
<Icon name={'add'} />
<TextInput
style={inputText}
underlineColorAndroid='transparent'
placeholder="Yapılacak iş ekle..."
placeholderTextColor="#FFFFFF"
value={this.props.todo}
onChangeText={todo => this.props.todoChanged(todo)}
/>
<Button
onPress={this.addToDo.bind(this)}
title="Ekle"
color="#841584"
/>
</View>
<View style={{ flex: 1 }}>
<ListView
enableEmptySections
dataSource={this.dataSource}
renderRow={this.renderRow}
/>
<Button
onPress={this.changeScreen.bind(this)}
title="Tamamlananları Göster"
color="#841584"
/>
</View>
</View>
);
}
}
}
路由器.js
import { StackNavigator } from 'react-navigation';
import Todolist from './src/Todolist';
import Profile from './src/Profile';
import TodoDetail from './components/TodoDetail';
import TodoDetailChecked from './components/TodoDetailChecked';
import TodoPage from './components/TodoPage';
const Router = StackNavigator({
Todolist: { screen: Todolist },
TodoDetail: { screen: TodoDetail },
Profile: { screen: Profile },
TodoDetailChecked: { screen: TodoDetailChecked },
TodoPage: { screen: TodoPage }
});
export default Router;
这个问题关于父子问题。
让我们引用文档:
重要的是要注意,这仅在屏幕 通过 React 导航呈现为路由(例如,响应
this.props.navigation.navigate
)。例如,如果我们渲染DetailsScreen
作为HomeScreen
的孩子,那么DetailsScreen
就不会 提供导航道具,当您按下"Go to Details... again"
主屏幕上的按钮,应用程序将抛出以下之一 典型的JavaScript例外"undefined is not an object"
。
要解决您的问题,请将this.props.navigation
从更高组件传递到子组件。
让我们举个例子:
应用.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import MyView from './MyView';
import { StackNavigator } from 'react-navigation';
import DetailsScreen from './DetailsScreen';
class App extends React.Component {
render() {
return (
<View style={styles.container}>
<MyView navigation={this.props.navigation} />
<Text>Open up App.js to start working on your app!</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
export default StackNavigator({
Home: {
screen: App,
},
Details: {
screen: DetailsScreen,
}
});
我的视图.js
import React from 'react';
import { StyleSheet, Text, ListView } from 'react-native';
import TodoDetail from './TodoDetail';
export default class MyView extends React.Component {
constructor() {
super();
const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
this.state = {
dataSource: ds.cloneWithRows(['todo 1', 'todo 2']),
};
}
renderRow(todos) {
return <TodoDetail todos={todos} navigation={this.props.navigation} />;
}
render() {
return (
<ListView
enableEmptySections
dataSource={this.state.dataSource}
renderRow={(rowData) => this.renderRow(rowData)}
/>
);
}
}
待办事项详细信息.js
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
export default class TodoDetail extends React.Component {
componentDidMount() {
// console.log(this.props.navigation.navigate('Details'));
}
render() {
return (
<View>
<Text>Todo detail</Text>
<Text>{this.props.todos}</Text>
<Button
title="Go to Details"
onPress={() => this.props.navigation.navigate('Details', { itemDetail: this.props.todos })}
/>
</View>
);
}
}
详细信息屏幕.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
export default class DetailsScreen extends React.Component {
componentDidMount() {
console.log(this.props.navigation);
}
render() {
const { params } = this.props.navigation.state;
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
<Text>{ params.itemDetail }</Text>
</View>
);
}
}
所以在这里,你需要传递navigation={this.props.navigation}
每个子渲染。如果您看到组件传递MyView
navigation
道具<MyView navigation={this.props.navigation} />
.
在它里面<TodoDetail todos={todos} navigation={this.props.navigation} />
,最后TodoDetail
将可用this.props.navigation
访问this.props.navigation.navigate
。