react-native - 将导航道具传递给外部组件
问题描述
我正在尝试从组件内部导航,但我一生都无法弄清楚。
这是我的 App.tsx 代码:
import * as React from 'react';
import { Image, ScrollView, RefreshControl, Text} from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { DashboardView } from './views/Dashboard';
import { MessagesView } from './views/Messages';
import { WisdomReplays } from './views/WisdomReplays';
import { TodoView } from './views/Todo';
import { MoreOptionsView } from './views/MoreOptions';
import { AuthView } from './views/Auth';
import { Header, ListItem, Icon, ThemeProvider } from 'react-native-elements';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import Ionicons from 'react-native-vector-icons/Ionicons';
import config from './core/Config.json';
function DashboardScreen() {
return (
<ScrollView>
<DashboardView/>
</ScrollView>
);
}
function MessagesScreen() {
return (
<ScrollView>
<MessagesView/>
</ScrollView>
);
}
function TodoScreen() {
return (
<ScrollView>
<TodoView/>
</ScrollView>
);
}
function SocialScreen({ navigation }) {
return (
<>
<Text onPress={() => navigation.navigate('Todo')}> Test </Text>
<WisdomReplays/>
</>
);
}
function MoreOptionsScreen() {
return (
<MoreOptionsView/>
);
}
const Tab = createBottomTabNavigator();
export default function App() {
if (config.access_token != null) {
return (
<NavigationContainer>
<ThemeProvider>
<Header
statusBarProps={{ barStyle: 'light-content' }}
barStyle="light-content"
centerComponent={<Image style={{ height: 35 }} source={require('./images/bms_logo_light.png')}
resizeMode="contain"/>}
containerStyle={{
backgroundColor: '#343434',
justifyContent: 'space-around',
borderBottomColor: "#323232",
}}
/>
</ThemeProvider>
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
let iconName;
if (route.name === 'Home') {
iconName = focused
? 'ios-home'
: 'ios-home';
} else if (route.name === 'Messages') {
iconName = focused ? 'ios-paper-plane' : 'ios-paper-plane';
} else if (route.name === 'Todo') {
iconName = focused ? 'ios-list-box' : 'ios-list';
} else if (route.name === 'More') {
iconName = focused ? 'ios-more' : 'ios-more';
} else if (route.name === 'Videos') {
iconName = focused ? 'ios-videocam' : 'ios-videocam';
}
// You can return any component that you like here!
return <Ionicons name={iconName} size={size} color={color} />;
},
})}
tabBarOptions={{
activeTintColor: '#ffcc07',
inactiveTintColor: 'gray',
}}
>
<Tab.Screen name="Home" component={DashboardScreen} />
<Tab.Screen name="Messages" component={MessagesScreen} />
<Tab.Screen name="Todo" component={TodoScreen} />
<Tab.Screen name="Videos" component={SocialScreen} />
<Tab.Screen name="More" component={MoreOptionsScreen} />
</Tab.Navigator>
</NavigationContainer>
);
} else {
return (
<AuthView/>
);
}
}
导航在上面的测试中完美运行。
我想做它,这样我就可以navigation.navigate('Todo')}
从WisdomReplays组件内部运行。智慧重播如下:
import React, { Component } from 'react'
import { StyleSheet, Image, ActivityIndicator, FlatList, TouchableOpacity, View, Text, RefreshControl } from 'react-native';
import { Title, Paragraph, Card } from 'react-native-paper';
import { Icon } from 'react-native-elements';
import config from '../core/Config.json';
const LeftContent = props => <Image style={{ width: 45, height: 45, borderRadius: 45 / 2 }} {...props} source={require('../images/rik-icon.jpg')} resizeMode="contain"/>
const LeftContentSocialHeader = props => <Icon name='ios-videocam' type='ionicon' size="43" color="#ffcc07" />
const styles = StyleSheet.create({
contentItem: {
marginTop: 20,
marginHorizontal: 15,
borderRadius: 10,
},
socialCardPost: {
marginBottom: 10,
borderRadius: 0
},
CardHeader: {
marginBottom: 10,
borderRadius: 0
},
Loader: {
marginTop: 250,
},
container: {
flex: 1,
},
player: {
flex: 1,
},
});
export class WisdomReplays extends Component {
constructor(props){
super(props);
this.state = {
videoList: [],
loading: true,
page: 1,
isFetching: false
}
}
async componentDidMount() {
this.fetchRecords('1');
}
onRefresh() {
this.setState({ isFetching: true }, function() { this.refreshRecords() });
}
onScrollHandler = () => {
this.setState({
page: this.state.page + 1
}, () => {
this.fetchRecords(this.state.page);
});
}
fetchRecords = (page) => {
fetch('http://######/api/replays/index.php?page='+page+'&ac='+config.access_token)
.then(res => res.json())
.then(response => {
this.setState({
videoList: [...this.state.videoList, ...response.results], loading: false
});
});
}
refreshRecords() {
fetch('http://######/api/replays/index.php?page=1&ac='+config.access_token)
.then(res => res.json())
.then(response => {
this.setState({
page: 1, videoList: response.results, isFetching: false
});
});
}
headerItem() {
return (
<Card style={styles.CardHeader}>
<Card.Title title="Wisdom Replays" subtitle="A collection of over 60 hours of video content!" left={LeftContentSocialHeader} />
</Card>
)}
renderItem(data) {
return (
<Card style={styles.socialCardPost}>
<Card.Title title="Rik Courntey" subtitle={data.item.h2} left={LeftContent} />
<Card.Cover source={{ uri: 'https://bemoresocial.co.uk/images/'+data.item.image }} style={{height: 225}} />
<Card.Content>
<Title style={{marginTop: 10}}>{data.item.h1}</Title>
<Paragraph>{data.item.text}</Paragraph>
</Card.Content>
</Card>
)}
render() {
const { videoList, loading } = this.state;
if(!loading) {
return (
<>
<FlatList
data={videoList}
onRefresh={() => this.onRefresh()}
refreshing={this.state.isFetching}
ListHeaderComponent = {this.headerItem}
renderItem={this.renderItem}
onEndReached={this.onScrollHandler}
onEndReachedThreshold={1.5}
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}
/>
</>
)
} else {
return (
<View
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}}>
<ActivityIndicator/>
</View>
)
}
}
}
我希望导航功能出现在 WisdomReplays 组件中的以下元素中:
renderItem(data) {
return (
<Card style={styles.socialCardPost}>
<Card.Title title="Rik Courntey" subtitle={data.item.h2} left={LeftContent} />
<Card.Cover source={{ uri: 'https://bemoresocial.co.uk/images/'+data.item.image }} style={{height: 225}} />
<Card.Content>
<Title style={{marginTop: 10}}>{data.item.h1}</Title>
<Paragraph>{data.item.text}</Paragraph>
</Card.Content>
</Card>
)}
我尝试了许多资源,但没有一个对我有用:
https://medium.com/@shovonroy/how-to-properly-navigate-with-react-navigation-e38fe3bf7381
https://reactnavigation.org/docs/navigation-prop/
任何帮助将非常感激 :)
解决方案
据我了解 - 导航道具并未传递给所有组件;只有屏幕组件会自动接收此道具。
我认为您可以尝试直接传递导航道具:
function SocialScreen({ navigation }) {
return (
<>
<Text onPress={() => navigation.navigate('Todo')}> Test </Text>
<WisdomReplays navigation={navigation}/>
</>
);
}
然后在WisdomReplays 中使用它:
navigateToSomeWhere = () => {
this.props.navigation.navigate('Todo');
}
希望它会有所帮助
推荐阅读
- azure - 使用 c# 检索要存储到 Cosmos 中的 Blob 存储文件名
- bash - 用于删除整个 csv 文件的自动换行的 Linux 命令
- python - Python日期时间和函数
- reactjs - React Redux Connect DefaultRootState 输入
- php - 在 PHP 中多次返回
- javascript - 我可以在创建后立即获取文档密钥吗?
- javascript - 抓取网站时在 NodeJs 上获取 POST 请求并将结果转换为 DOM
- reactjs - 如何用反应替换代理 API url?
- silverstripe - 在 SilverStripe 后端,有没有办法用模板呈现列?
- laravel - Laravel 中止()与返回响应()-> json()