首页 > 解决方案 > React Native:点击 FlatList 项目时呈现项目细节的逻辑

问题描述

你好 React Native Devs ...我是 RN 的新手,并且停留在我正在开发的应用程序中的一个点上......在我正在开发的应用程序的一个屏幕中,我需要渲染项目,如下图所示。

在此处输入图像描述

类别在左列中,点击其中一个类别(例如汉堡)将显示该类别中的项目,这些项目显示在中间列中,点击中间列中的项目(例如牛肉汉堡)将显示该项目的详细信息是正确的列...问题是我无法弄清楚如何在点击时获取某个类别的项目...我正在使用 FlatList ...如果有人想检查,下面是我的代码。

export default class Menu extends Component {

    state = {
        categories: [
            {
                id: 1,
                name: 'Burgers',
                items: [
                    {
                        itemId: 1,
                        itemName: 'Beef Burger',
                        itemPrice: 2.89,
                        isAvailable: false,
                        addons: [
                            {
                                addonId: 1,
                                addonName: 'Extra Cheese',
                                addonPrice: 0.99,
                                isAddonAvailable: true
                            },
                            {
                                addonId: 2,
                                addonName: 'Extra Spicy',
                                addonPrice: 0.89,
                                isAddonAvailable: false
                            }
                        ]
                    },
                    {
                        itemId: 2,
                        itemName: 'Chicken Burger',
                        itemPrice: 1.89,
                        isAvailable: true,
                        addons: [
                            {
                                addonId: 1,
                                addonName: 'Extra Cheese',
                                addonPrice: 0.99,
                                isAddonAvailable: true
                            },
                            {
                                addonId: 2,
                                addonName: 'Extra Spicy',
                                addonPrice: 0.89,
                                isAddonAvailable: false
                            }
                        ]
                    }
                ]
            },
            {
                id: 2,
                name: 'Pizza',
                items: [
                    {
                        itemId: 1,
                        itemName: 'Pepperoni Pizza',
                        itemPrice: 2.89,
                        isAvailable: false,
                        addons: [
                            {
                                addonId: 1,
                                addonName: 'Extra Cheese',
                                addonPrice: 0.99,
                                isAddonAvailable: true
                            },
                            {
                                addonId: 2,
                                addonName: 'Extra Spicy',
                                addonPrice: 0.89,
                                isAddonAvailable: false
                            }
                        ]
                    },
                    {
                        itemId: 2,
                        itemName: 'Cheese Lovers Pizza',
                        itemPrice: 1.89,
                        isAvailable: false,
                        addons: [
                            {
                                addonId: 1,
                                addonName: 'Extra Cheese',
                                addonPrice: 0.99,
                                isAddonAvailable: true
                            },
                            {
                                addonId: 2,
                                addonName: 'Extra Spicy',
                                addonPrice: 0.89,
                                isAddonAvailable: false
                            }
                        ]
                    }
                ]
            },
            {
                id: 3,
                name: 'Beverages',
                items: [
                    {
                        itemId: 1,
                        itemName: 'Coca Cola',
                        itemPrice: 2.89,
                        isAvailable: false,
                        addons: [
                            {
                                addonId: 1,
                                addonName: 'Chilled',
                                addonPrice: 0.99,
                                isAddonAvailable: true
                            },
                            {
                                addonId: 2,
                                addonName: 'Normal',
                                addonPrice: 0.89,
                                isAddonAvailable: false
                            }
                        ]
                    },
                    {
                        itemId: 2,
                        itemName: 'Coffee',
                        itemPrice: 1.89,
                        isAvailable: false,
                        addons: [
                            {
                                addonId: 1,
                                addonName: 'Full Cream',
                                addonPrice: 0.99,
                                isAddonAvailable: true
                            },
                            {
                                addonId: 2,
                                addonName: 'Milk',
                                addonPrice: 0.89,
                                isAddonAvailable: false
                            }
                        ]
                    }
                ]
            }
        ],

        restCategories: [],
        itemListSectionVisible: false,
        itemDetailSectionVisible: false,
    }

    async componentDidMount() {
        await this.collectCategories(this.state.categories)
    }

    collectCategories = async (catArr) => {
        cats = []

        for (let catID in catArr) {
            let catInfo = {}

            catInfo['catId'] = catArr[catID]['id'];
            catInfo['catName'] = catArr[catID]['name'];
            catInfo['catItems'] = this.collectCategoryItems(catArr[catID]['items'])

            cats.push(catInfo)
        }
        this.setState({restCategories: cats})
        console.log(this.state.categories)
    }

    collectCategoryItems = (itemArr) => {
        catItems = [];
        for (let itemID in itemArr) {
            let itemInfo = {};

            itemInfo['itemId'] = itemArr[itemID]['itemId'];
            itemInfo['itemName'] = itemArr[itemID]['itemName'];
            itemInfo['itemPrice'] = itemArr[itemID]['itemPrice'];

            catItems.push(itemInfo)
        }

        return catItems;
    }

    renderCategoryListItem = (cat) => {
        return (
            <View style={menuStyles.categoryListItemView}>

                <View style={menuStyles.categoryNameView}>
                    <Text style={menuStyles.categoryNameText}>{cat.catName}</Text>
                </View>
                <View style={menuStyles.iconView}>
                    <Icon name='arrow-forward' style={menuStyles.categoryArrow}/>
                </View>

            </View>
        )
    }

    renderListItem = (item) => {
        return (
            <View style={menuStyles.itemView}>
                <View style={menuStyles.itemThumbView}>
                    <Image source={itemPlaceHolderThumb} style={menuStyles.itemThumb}/>
                </View>
                <View style={menuStyles.itemNameView}>
                    <Text style={menuStyles.itemName}>{item.itemName}</Text>
                    <Text style={menuStyles.itemPrice}>$&nbsp;{item.itemPrice}</Text>
                </View>
                <View style={menuStyles.itemToggleBtnView}>
                    <Switch
                        value={item.isAvailable ? true : false}
                        trackColor={{
                            false: 'red',
                            true: 'lime'
                        }}
                        ios_backgroundColor='red'
                        onValueChange={() => console.log('Changed')}
                        style={menuStyles.itemToggleBtn}
                    />
                </View>
            </View>
        )
    }

    renderAddonList = (addon) => {
        return (
            <View style={menuStyles.addonListView}>
                <View style={menuStyles.addonNameView}>
                    <Text style={menuStyles.addonNameText}>{addon.addonName}</Text>
                </View>
                <View style={menuStyles.addonPriceView}>
                    <Text style={menuStyles.addonPriceText}>+ $ {addon.addonPrice}</Text>
                </View>
                <View style={menuStyles.addonToggleBtnView}>
                    <Switch
                        value={addon.isAddonAvailable ? true : false}
                        trackColor={{
                            false: 'red',
                            true: 'lime'
                        }}
                        ios_backgroundColor='red'
                        onValueChange={() => console.log('Changed')}
                        style={menuStyles.itemToggleBtn}
                    />
                </View>
            </View>
        )
    }

    showItemListSection = (catIndex) => {
        this.setState({
            itemListSectionVisible: true,
        })
        console.log('index ', catIndex)
    }

    showItemDetailSection = () => {
        this.setState({itemDetailSectionVisible: true})
    }

    render() {
        const {itemListSectionVisible, itemDetailSectionVisible} = this.state;
        return (
            <View style={{flex: 1}}>
                <CustomHeader drawerAction={this.props.navigation.openDrawer.bind(this)}/>
                <View style={menuStyles.container}>
                    <View style={menuStyles.categorySection}>
                        <View style={menuStyles.headingView}>
                            <Text style={menuStyles.headingText}>{'Menu'.toUpperCase()}</Text>
                        </View>
                        <View style={menuStyles.categoryListView}>
                            <FlatList
                                data={this.state.restCategories}
                                keyExtractor={(item, index) => item.catId.toString()}
                                renderItem={({item, index}) => <TouchableOpacity
                                    onPress={() => this.showItemListSection(item.catId)}>{this.renderCategoryListItem(item)}</TouchableOpacity>}
                                ItemSeparatorComponent={() => <Hr/>}
                            />
                        </View>
                    </View>
                    <View style={menuStyles.itemsSection}>
                        <View style={menuStyles.headingView}>
                            <Text style={menuStyles.headingText}>Items</Text>
                        </View>

                        <View style={menuStyles.itemListView}>
                            <FlatList
                                data={this.state.categories[0].items}
                                keyExtractor={(item, index) => item.itemId.toString()}
                                renderItem={({item}) => <TouchableOpacity
                                    onPress={() => this.showItemDetailSection()}>{this.renderListItem(item)}</TouchableOpacity>}
                            />
                        </View>
                    </View>

                    <View style={menuStyles.itemDetailSection}>
                        <View style={menuStyles.itemDetailImageView}>

                            <Image source={itemPlaceholderImg} style={menuStyles.itemDetailImage}/>

                        </View>
                        <View style={menuStyles.itemDetailNameView}>
                            <Text style={menuStyles.itemDetailNameText}>{'Beef Burger'.toUpperCase()}</Text>
                            <Text style={menuStyles.itemDetailDescText}>Duotones are simply the combining of two colors
                                on an image, usually using very bright or contrasting colors. They require a bit of
                                design work but it is most definitely worth it.</Text>
                        </View>
                        <View style={menuStyles.itemDetailAddonsView}>
                            <View style={menuStyles.addonHeadingView}>
                                <Text style={menuStyles.addonHeadingText}>Addons</Text>
                            </View>
                            <FlatList
                                data={this.state.categories[0].items[0].addons}
                                keyExtractor={(item, index) => item.addonId.toString()}
                                renderItem={({item}) => this.renderAddonList(item)}
                                ItemSeparatorComponent={() => <Hr/>}
                            />
                        </View>
                    </View>

                </View>
            </View>
        )
    }
} 

如果有人能指出我正确的方向,我将不胜感激。TIA

标签: react-native

解决方案


正如您所描述的,您希望所有的东西都在一个屏幕上,为此,您可以做一件事,您必须制作多个平面屏幕并在 this.state 的平面屏幕中传递额外的数据,以便您可以在平面列表渲染功能通过放置可以显示和隐藏特定平面列表的条件,并且根据类别,您可以在平面列表中传递数据。


推荐阅读