簡體   English   中英

在平面列表中反應原生導航

[英]React native navigation in flatlist

我使用 flatlist 來顯示數據列表。 我希望將數據傳遞到另一個頁面,但我不知道我使用哪種導航。

import Routes from './src/Routes';


export default class App extends Component<Props> {
  render() {

    return (
      <View style={styles.container}>
        <StatusBar 
          backgroundColor="#1c313a"
          arStyle="light-content" 
        />
        <Routes/>
      </View>
    );
  }
}
import React, { Component } from 'react';
import {StyleSheet, View, StatusBar,Text} from 'react-native';

import { NavigationContainer } from '@react-navigation/native';
import { createDrawerNavigator } from '@react-navigation/drawer';

import HomeScreen from '../pages/HomeScreen'
import YourActivitiesScreen from '../pages/YourActivitiesScreen'
import YourFavouriteScreen from '../pages/YourFavouriteScreen'


const Drawer = createDrawerNavigator();

function MyDrawer() {
  return (
    <Drawer.Navigator initialRouteName="Home">
      <Drawer.Screen 
        name="Home"
        component={HomeScreen}
        options={{ drawerLabel: 'Home' }}
      />
      <Drawer.Screen
        name="Your Activities"
        component={YourActivitiesScreen}
        options={{ drawerLabel: 'Your Activities' }}
      />
      <Drawer.Screen
        name="Your Favourite"
        component={YourFavouriteScreen}
        options={{ drawerLabel: 'Your Favourite' }}
      />
    </Drawer.Navigator>
  );
}

export default function SideMenu() {

  return (
    <NavigationContainer>
      <MyDrawer />
    </NavigationContainer>
  );
}
import React, { Component } from 'react';
import {Router, Stack, Scene} from 'react-native-router-flux';
import Login from './pages/Login';
import Signup from './pages/Signup';
import SideMenu from './components/SideMenu'


export default class Routes extends Component {
    render() {
        return(
            <Router>
                <Stack key="root" hideNavBar>
                    <Scene key="login" component={Login} title="Login" initial/>
                    <Scene key="signup" component={Signup} title="Signup" />
                    <Scene key="home" component={SideMenu} title="HomeScreen" />
                </Stack>
            </Router>
        );
    }
}
import React, { Component } from 'react';
import {
    StyleSheet,
    View,
    Text,
    AsyncStorage,
    TouchableOpacity,
    FlatList,
    Button,
} from 'react-native';
import DetailsScreen from './Details';

import { createDrawerNavigator, SafeAreaView } from 'react-navigation';
class HomeScreen extends Component{

    constructor(props) {
        super(props);
        this.state = {
            activitiesList: [],   
        }
    };
    renderItem = (item) => {
       return (
         <TouchableOpacity
           onPress={() => {

           console.log('test')

          }}
          >
                <View style={styles.item}>
                  <Text style={styles.title}>{item.name}</Text>
                </View>
              </TouchableOpacity>
            );
          }

    render(){
        const listActivities = this.state.activitiesList

        return (
            <View>
                <View style={styles.container}>
                    <Text style={styles.heading}>UPCOMING ACTIVITIES</Text>
                </View>
                <View>
                    <SafeAreaView>
                        <FlatList
                            data = {listActivities}
                            renderItem={({ item }) => this.renderItem(item)}
                            keyExtractor={item => item.id}
                        />
                    </SafeAreaView>
                </View>
            </View>
        )
    }
}

我在系統的早期部分使用了 react-native-router-flux,即登錄、注冊和主頁。 現在主頁顯示平面列表,從平面列表中我必須制作一個 onPress 導航到另一個頁面,我之前使用的 router-flux 中的操作無法工作。 有人知道嗎? 或另一種更好的方式導航到平面列表的詳細信息?

首先,我將重構所有代碼以僅使用一種導航器(在這種情況下,使用react-navigation )。 因此,我們會將您的 router-flux 代碼與您的

//Your routes screen
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
//... add missing imports

const Stack = createStackNavigator();

//this will be your old router-flux
const Root = () => {
  return (
  <Stack.Navigator>
    <Stack.Screen name="login" component={Login} title="Login" initial/>
    <Stack.Screen name="signup" component={Signup} title="Signup" />
    <Stack.Screen name="home" component={SideMenu} title="HomeScreen" />
  </Stack.Navigator>
 )
} 

const Drawer = () => {
  return (
  <Drawer.Screen 
        name="Home"
        component={HomeScreen}
        options={{ drawerLabel: 'Home' }}
      />
  <Drawer.Screen
        name="Your Activities"
        component={YourActivitiesScreen}
        options={{ drawerLabel: 'Your Activities' }}
      />
  <Drawer.Screen
        name="Your Favourite"
        component={YourFavouriteScreen}
        options={{ drawerLabel: 'Your Favourite' }}
      />
  </Drawer.Navigator>
 )
}

const AppContainer = () => {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen name="Root" component={Root} />
        <Stack.Screen name="Drawer" component={Drawer} />
        //import your Details screen to use inside component
        <Stack.Screen name="Details" component={Details} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

export default AppContainer

您將使用此 AppContainer 包裝您的App.js組件。 我們剛剛做的是嵌套導航,您的Home將首先到達,您的抽屜將全部相同。 此外,您的代碼中缺少一個堆棧,即Details堆棧。

在此之后,您將使用react-navigation中的所有操作。 所有的屏幕都會收到一個navigation道具。 一旦你想從你的Root導航,你會像props.navigation.navigate("Home")一樣調用導航。

這同樣適用於從 FlatList 導航到您的詳細信息屏幕。

//Your Home Screen
import React, { Component } from 'react';
import {
    StyleSheet,
    View,
    Text,
    AsyncStorage,
    TouchableOpacity,
    FlatList,
    Button,
    SafeAreaView
} from 'react-native';

class HomeScreen extends Component{

    constructor(props) {
        super(props);
        this.state = {
            activitiesList: [],   
        }
    };
    renderItem = (item) => {
       return (
         <TouchableOpacity
           onPress={() => {
           props.navigation.navigate("Details", { data: item })
           console.log('test')

          }}
          >
                <View style={styles.item}>
                  <Text style={styles.title}>{item.name}</Text>
                </View>
              </TouchableOpacity>
            );
          }

    render(){
        const listActivities = this.state.activitiesList

        return (
            <View>
                <View style={styles.container}>
                    <Text style={styles.heading}>UPCOMING ACTIVITIES</Text>
                </View>
                <View>
                    <SafeAreaView>
                        <FlatList
                            data = {listActivities}
                            renderItem={({ item }) => this.renderItem(item)}
                            keyExtractor={item => item.id}
                        />
                    </SafeAreaView>
                </View>
            </View>
        )
    }
}

剛剛將導航操作添加到上面的代碼中。 您必須在詳細信息屏幕中訪問params object

//Details Screen
class DetailsScreen extends React.Component {
  render() {
    const { routes } = this.props;
    return (
      <View>
      //Your component
        <Text>{routes.data.name}</Text>
      </View>
    );
  }
}

只是一個旁注。 如果您在導航到嵌套堆棧時遇到問題,您可以使用 params 以這種方式導航

navigation.navigate(<YourParent>, {
  screen: <YourDesiredScreen>,
  params: { <YourObject> },
});

我希望它有所幫助,至少作為指南。 我沒有測試它,這就是為什么我要求您將代碼上傳到 expo。

我使用react-navigation並且非常高興。 所有需要的導航都可以通過一個簡單的方式完成:

this.props.navigation.navigate('ScreenName', {param1: 'Hello', param2: 'World'})

然后,當需要在屏幕上時,獲取參數:

const { param1, param2 } = this.props.route.params;

更多細節在這里

當然,如果使用 function 組件,那就更容易了。

這個例子是我的第一個 react-native-expo 項目,但我希望它會對你有所幫助。

底部代碼用於兩個堆棧屏幕,其中我有PlayersTab屏幕和Player ,因此主要重點是使用react-navigationPlayersTab訪問具有參數的Player

Navigation 在 props object 中,您只需在組件const PlayersList = ({ navigation }) => {//your code}中對其進行析構即可

import { View, Text } from 'react-native';
import React from 'react';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import PlayersList from '../personal_data_screen/PlayersList';
import PersonalDataScreenPlayer from'../personal_data_screen/PersonalDataScreenPlayer';

const Stack = createNativeStackNavigator();

const PersonalPlayerDataNavigator = ({ loginDataObject }) => {
return (
  <Stack.Navigator>
   <Stack.Screen options={{ headerShown: false }} name='PlayersTab'>
     {(props) => (
      <PlayersList {...props} loginDataObject={loginDataObject} />
     )}
   </Stack.Screen>
   <Stack.Screen options={{ headerShown: false }} name='Player'>
    {(props) => <PersonalDataScreenPlayer {...props} />}
   </Stack.Screen>
  </Stack.Navigator>
 );
};

export default PersonalPlayerDataNavigator;

FlatList 女巫在PlayersTab中看起來像這樣

<FlatList
   data={Object.keys(friendList.data)}
   renderItem={renderItem}
   keyExtractor={keyExtractor}
   navigation={navigation}
 />

const renderItem = ({ item }) => (
<Item
  navigation={navigation}
  account_id={friendList.data[item].account_id}
  nickname={friendList.data[item].nickname}
/>

const Item = ({ nickname, account_id, navigation }) => (
<TouchableOpacity
  onPress={() => navigation.navigate('Player', { account_id: account_id })}>
  <View style={styles.itemView}>
    <Text style={styles.playerNicknameText}>{nickname}</Text>
  </View> 
</TouchableOpacity>

播放器屏幕的代碼

import React from 'react';
import { View, Text } from 'react-native';

const PersonalDataScreenPlayer = ({ route }) => {

return (
  <View
   style={{
    flex: 1,
    flexDirection: 'column',
    alignItems: 'center',
    justifyContent: 'center',
   }}>
   <Text>{route.params.account_id}</Text>
 </View>
 );
};

export default PersonalDataScreenPlayer;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM