【问题标题】:React native navigation in flatlist在平面列表中反应原生导航
【发布时间】:2020-04-14 13:15:40
【问题描述】:

我使用 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 中的操作无法工作。有人知道吗?或其他更好的方式导航到平面列表的详细信息?

【问题讨论】:

  • 您能告诉我们路由器代码吗?我的意思是,您可以指定所有要导航的屏幕、堆栈等。您想通过 onPress 到达哪个屏幕?最后但同样重要的是,定义是使用react-navigation 还是router-flux,因为两者都不是一个好主意。
  • @IanVasco 更新了问题。抱歉,我是 react-native 的新手,所以我只是按照在线教程进行操作。现在我不知道如何继续它。我想将平面列表中的项目带入显示详细信息的详细页面
  • @IanVasco 先生,您知道吗?
  • 您能否将您的代码上传到博览会小吃或代码沙箱,以便我更详细地检查它
  • @IanVasco 无法获取这些工具中的依赖项。你能检查我的代码并给出一些添加导航的建议吗?

标签: javascript react-native react-navigation react-native-flatlist react-native-router-flux


【解决方案1】:

首先,我将重构所有代码以仅使用一种导航器(在本例中,使用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 对象

//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> },
});

我希望它会有所帮助,至少作为指南。我没有对其进行测试,这就是为什么我要求您将代码上传到博览会。

【讨论】:

    【解决方案2】:

    我使用react-navigation 并且非常高兴。所有需要的导航都可以通过一个简单的方式完成:

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

    然后,当需要在屏幕上时,获取参数:

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

    更多详情here

    当然,如果使用函数组件就更容易了。

    【讨论】:

    • 我更新了有问题的代码,我不明白如何将它插入到我的代码中。你能再指出一些吗?
    【解决方案3】:

    这个例子是我的第一个 react-native-expo 项目,但我希望它会对你有所帮助。

    底部代码用于两个堆栈屏幕,其中我有 PlayersTab 屏幕和 Player,因此主要重点是使用来自 的参数访问 Player >PlayersTab 使用react-navigation

    导航位于 props 对象中,您只需在组件 const PlayersList = ({ navigation }) =&gt; {//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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-10
      • 1970-01-01
      相关资源
      最近更新 更多