在反应导航中传递ID与传递对象

时间:2020-05-11 14:38:07

标签: javascript reactjs react-native react-navigation

我正在上react-native的在线课程,并对老师使用的参数传递练习感到好奇。

讲师具有一个内容为DATA的数组,每个元素都是SomeModel类的一个实例。从AScreen导航到BScreen时,他通过将有效SomeModel对象的ID作为参数提供给BScreen方法,将其传递为参数props.navigation.navigate()。然后,他将相同的DATA数组导入定义BScreen的文件中,并在find()上使用DATA方法检索相关对象。 (即使用通过props.navigation.getParam()方法获得的ID)

AScreen一样,触发导航的特定按钮也可以访问DATA以及特定对象(即,有一个按钮对应于每个有效对象,并且按钮在FlatList)我想知道为什么他选择仅将id而不是整个对象作为参数传递给导航。然后,可以使用用于获取ID的同一BScreen调用在getParam()中获取整个相关对象,而无需调用find()方法,从而节省了一些时间。我认为JavaScript将通过引用传递相关的SomeModel实例,并且将ID传递给更大的对象作为参数将不会产生额外的开销。

我认为这是不正确的吗?我有没有忽略的间接费用来源?如果不是,出于某种原因单独传递ID是否是最佳做法,如果是,为什么?这对react-navigation的机制来说是特殊的吗?

我在下面提供了示例代码片段,以帮助提供我上面描述的用例的更具体的图片。

SomeModel.js:

class SomeModel {
    constructor(id, val1, val2, ...) {
        this.id = id;
        this.val1 = val1;
        this.val2 = val2;
        ...
    }
}

data.js:

import SomeModel from 'SomeModel'

export const DATA = [
    new SomeModel('d1', '1234', '5678',...),
    new SomeModel('d2', '1234', '5678',...),
    ...
]

SomeNavigator.js:

import { createAppContainer } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';

import AScreen from 'AScreen';
import BScreen from 'BScreen';

const SomeNavigator = createStackNavigator({
        AScreen: AScreen,
        BScreen: BScreen
});

export default createAppContainer(SomeNavigator);

AScreen.js:

import React from 'react';
import { View, FlatList, Button } from 'react-native';
import {DATA} from 'data';

const AScreen = props => {
    return (
        <View>
            <FlatList data={DATA} renderItem={itemData => {
                <Button
                    title='Go to Screen B!'
                    onPress={() => {
                        // There are actual buttons corresponding to SomeClass instances,
                        // but let's assume there is a single button passes a valid ID to an existing object
                        props.navigation.navigate('ScreenB', {dataID: itemData.item.id});
                    }}
                />
            }} />
        </View>
    );
}

BScreen.js:

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

const BScreen = props => {
    const dataID = props.navigation.getParam('dataID');
    const selectedItem = DATA.find(datum => datum.id === dataID);
    return (
        <View>
            <Text> {selectedItem.val1} </Text>
        </View>
    );
}

1 个答案:

答案 0 :(得分:0)

简短答案是您的想法是正确的,但是当您仔细研究细节时,您会发现所建议的方法在涉及API的实际示例中不起作用。

  • 场景1:您有一个本地对象数组,这些对象显示在一个平面列表中,并且您有一个onpress,它将带您进入下一个屏幕并传递ID。讲师可能会采用这种方法来解释您在现实世界中的应用程序中要做的事情,即在下一个屏幕中获取所需的数据。
  • 方案2:您将对象作为一个整体传递,这具有优势,因为下一个屏幕将是一个愚蠢的组件,该组件仅根据传递的数据显示内容。就像您所要求的那样,它将在本地阵列上很好地工作。
  • 场景3:您使用api获取项目列表并在单独的页面中显示单个项目的详细信息。如果您带走第二个屏幕所需的所有数据,则将需要更多的网络带宽和更多的处理能力服务器,它将更多内容加载到移动设备的内存中。用户可能根本不单击所有项目,因此您带来的字段很浪费。因此,下一个屏幕将获取ID并从服务器请求更多数据。
  • 场景4:考虑一个小型类对象的列表,该对象仅包含您从API获得的两个或三个字段,在这种情况下,如果第二个屏幕不需要更多数据,我们可以像场景2一样传递对象。

这一切都取决于应用程序的设计,要处理的数据类型以及组件需要多少数据。 正如您提到的,您的讲师采用了这条路径,向您展示了如何完成事情的示例。如果他向您展示了您建议的方式,并且为您提供了获取更多数据的方案,那么您将必须找到一种方法来实现此目的。他可能使用他的本地数组表示API。您将必须决定所采用的方法。