通过 DrawerNavigator 中的 StackNavigator 将数据从一个页面传递到另一个页面
对于一个业余项目,我正在构建一个应用程序,我的朋友可以查看我们计划的小组活动。每当有人点击某个活动时,我都希望显示一个包含该特定活动详细信息的屏幕。因此,我想从显示带有事件的 FlatList 的 EventScreen 转到 EventDetailScreen。它需要显示一个特定事件。
到目前为止,我已经让导航部分正常工作,但我无法将任何数据传递到下一个屏幕...
我尝试过以多种方式将事件作为参数发送。但我不知道下一步该怎么做。我读过一些关于需要将数据从 DrawerNavigator 传递到 StackNavigator 的内容,但当我尝试这样做时,我收到一条错误消息,提示我需要在 AppContainer 中定义导航。
MenuNavigator.js
//Navigation Drawer Structure for all screen
class NavigationDrawerStructure extends Component {
//Top Navigation Header with Donute Button
toggleDrawer = () => {
//Props to open/close the drawer
this.props.navigationProps.toggleDrawer();
};
render() {
return (
<View style={{ flexDirection: 'row' }}>
<TouchableOpacity onPress={this.toggleDrawer.bind(this)}>
<Ionicons
name="md-menu"
color="white"
size={32}
style={styles.menuIcon}
/>
</TouchableOpacity>
</View>
);
}
}
//Stack Navigator for the First Option of Navigation Drawer
const HomeScreen_StackNavigator = createStackNavigator({
//All the screen from the First Option will be indexed here
HomeScreen: {
screen: HomeScreen,
navigationOptions: ({ navigation }) => ({
headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
headerStyle: {
backgroundColor: '#000',
},
}),
},
});
//Stack Navigator for the Second Option of Navigation Drawer
const EventsScreen_StackNavigator = createStackNavigator({
//All the screen from the Second Option will be indexed here
EventsScreen: {
screen: EventsScreen,
navigationOptions: ({ navigation }) => ({
headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
headerStyle: {
backgroundColor: '#000',
},
}),
},
});
//Stack Navigator for the Third Option of Navigation Drawer
const CalendarScreen_StackNavigator = createStackNavigator({
//All the screen from the Third Option will be indexed here
CalendarScreen: {
screen: CalendarScreen,
navigationOptions: ({ navigation }) => ({
headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
headerStyle: {
backgroundColor: '#000',
},
}),
},
});
//Stack Navigator for the Fourth Option of Navigation Drawer
const PollScreen_StackNavigator = createStackNavigator({
//All the screen from the Third Option will be indexed here
PollScreen: {
screen: PollScreen,
navigationOptions: ({ navigation }) => ({
headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
headerStyle: {
backgroundColor: '#000',
},
}),
},
});
//Stack Navigator for the Fifth Option of Navigation Drawer
const InfoScreen_StackNavigator = createStackNavigator({
//All the screen from the Third Option will be indexed here
InfoScreen: {
screen: InfoScreen,
navigationOptions: ({ navigation }) => ({
headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
headerStyle: {
backgroundColor: '#000',
},
}),
},
});
//Stack Navigator for the EventDetailScreen of Navigation Drawer
const EventDetailScreen_StackNavigator = createStackNavigator({
//All the screen from the Third Option will be indexed here
EventDetailScreen: {
screen: EventDetailScreen,
navigationOptions: ({ navigation }) => ({
headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
headerStyle: {
backgroundColor: '#000',
},
}),
},
});
const DrawerMenu = createDrawerNavigator(
{
HomeScreen: {
screen: HomeScreen_StackNavigator,
},
EventsScreen: {
screen: EventsScreen_StackNavigator,
},
CalendarScreen: {
screen: CalendarScreen_StackNavigator,
},
PollScreen: {
screen: PollScreen_StackNavigator,
},
InfoScreen: {
screen: InfoScreen_StackNavigator,
},
EventDetailScreen: {
screen: EventDetailScreen_StackNavigator,
},
},
{
// define customComponent here
contentComponent: CustomSidebarMenu,
drawerWidth: 300,
drawerBackgroundColor: 'rgba(0,0,0,0.6)', // or 'rgba(0,0,0,0)'
}
);
const styles = StyleSheet.create({
menuIcon: {
marginLeft: 15,
},
});
export default createAppContainer(DrawerMenu);
Events.js
class EventsScreen extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
dataSource: null,
refreshing: false,
};
}
async componentDidMount() {
const events = await ajax.FetchEvents();
this.setState({
isLoading: false,
dataSource: events,
refreshing: false,
});
}
handleRefresh = () => {
this.setState(
{
refreshing: false,
},
() => {
this.componentDidMount();
}
);
};
itemCard({ item }) {
const { navigate } = this.props.navigation;
return (
<TouchableWithoutFeedback
onPress={() =>
navigate('EventDetailScreen', {
data: 'test',
})
}>
<View style={styles.card}>
<View style={styles.item}>
<Text style={styles.title}>{item.title}</Text>
<Text numberOfLines={1} style={styles.desc}>
{item.description}
</Text>
<View style={styles.row}>
<View style={styles.iconColumn}>
<Ionicons name="md-home" color="white" size={24} />
</View>
<View style={styles.textColumn}>
<Text style={styles.location}>location</Text>
</View>
</View>
<View style={styles.row}>
<View style={styles.iconColumn}>
<Ionicons name="md-calendar" color="white" size={24} />
</View>
<View style={styles.textColumn}>
<Text style={styles.date}>{item.date}</Text>
</View>
</View>
</View>
</View>
</TouchableWithoutFeedback>
);
}
render() {
if (this.state.isLoading) {
return (
<View style={styles.container}>
<ActivityIndicator />
</View>
);
} else {
return (
<View style={styles.container}>
<FlatList
data={this.state.dataSource}
renderItem={({ item }) => this.itemCard({ item })}
keyExtractor={item => item.id.toString()}
onRefresh={() => this.handleRefresh()}
refreshing={this.state.refreshing}
/>
</View>
);
}
}
}
EventDetailScreen.js
class EventDetailScreen extends Component {
render() {
let item = this.props.navigation.getParam('data', 'NO-DATA');
return (
<View>
<Text>{item}</Text>
</View>
);
}
}
export default EventDetailScreen;
每当我单击某个事件时,EventDetailScreen 都会显示“NO-DATA”,因为该项目未定义。我的目的是将用户单击的事件传递到下一个屏幕。因此,我可以使用来自该特定事件的标题、描述等。
是的,我知道代码有点乱。我是 React-Native 的新手,这是我的第一个应用程序(也是第一篇文章),所以还有很多需要改进的地方 :)
提前谢谢您!
我发现我应该使用 this.props.navigation.push 而不是 navigation。这样我就可以将参数传递到下一个屏幕。谢谢!
用于传递参数
this.props.navigation.navigate('Filter', {
uri: this.state.uri,
});
用于获取参数
const { navigation } = this.props;
const uri = navigation.getParam('uri');
console.log('url', uri);
this.setState({ uri: uri });
当您调用 setState() 时,它会重新渲染组件。当组件渲染时,它会调用组件的生命周期(例如
componentWillUpdate
或
componentDidUpdate
)。
您可能会收到错误,因为您可能在任何生命周期方法中设置状态。因此,它会创建递归函数调用,并且您会达到
超出最大更新深度
错误。
Rahul Jograna 的答案是正确的。
请参阅此链接以了解 react-native 组件生命周期。 https://reactjs.org/docs/react-component.html