如何在React Native SectionList的每个部分中包含不同类型的组件?

dkqlctbz  于 2023-04-22  发布在  React
关注(0)|答案(2)|浏览(130)

我有一个SectionList,分为3个部分:
1.一般用户信息
1.用户车辆信息
1.其他选项
一般信息项需要TouchableOpacity组件,以便当用户单击它们时,它们会路由到更新页面以更新此数据。
车辆信息项只是文本组件,但我确实需要一个“添加车辆”按钮组件在本节结束时,无论有多少车辆已被添加。
Other Options部分都可以是重定向到应用程序内的不同页面的TouchableOpacity组件。
如何在SectionList的不同部分中呈现不同的组件,并将某些组件添加到某些部分而不是其他部分?

这就是我需要的

SectionList组件

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

const SECTIONS = [
  {
    title: 'General',
    data: [
      {
        key: '1',
        content: 'John Smith',
        desc: 'Full Name',
      },
      {
        key: '2',
        content: 'john.smith@gmail.com',
        desc: 'E-mail',
      },
      {
        key: '3',
        content: '(222)123-4567',
        desc: 'Phone Number'
      },
    ],
  },
  {
    title: 'Vehicles',
    data: [
      {
        key: '4',
        content: 'Honda Civic',
        desc: 'Black'
      },
      {
        key: '5',
        content: 'Jeep Wrangler',
        desc: 'White'
      },
    ],
  },
  {
    title: 'Other',
    data: [
      {
        key: '6',
        content: 'Support',
        desc: ''
      },
      {
        key: '7',
        content: 'Terms of Service',
        desc: ''
      },
      {
        key: '8',
        content: 'Deactivate Account',
        desc: ''
      },
    ],
  },
];

export default function Profile() {

  return (
    <SafeAreaView style={styles.container}>
    <SectionList
      stickySectionHeadersEnabled={false}
      sections={SECTIONS}
      // keyExtractor={(item, index) =>  item + index }
      renderSectionHeader={({section }) => (
          <Text style={styles.header}>{section.title}</Text>
      )}
      renderItem={({ item, index, section }) => (
        <View style={[
          styles.item,
          index === 0 && styles.itemFirst,
          index === section.data.length -1 && styles.itemLast
          ]}>
          <Text style={styles.title}>{item.content}</Text>
          <Text style={styles.description}>{item.desc}</Text>
        </View>
      )}
      
    />
  </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    marginHorizontal: 16,
  },
  item: {
    backgroundColor: '#fff',
    borderBottomColor: '#aaa',
    borderBottomWidth: 0.2,
    paddingVertical: 8,
    paddingHorizontal: 20,
    marginHorizontal: 10,
  },
  itemFirst: {
    borderTopLeftRadius: 8,
    borderTopRightRadius: 8
  },
  itemLast: {
    borderBottomLeftRadius: 8,
    borderBottomRightRadius: 8,
    borderBottomWidth: 0
  },
  header: {
    fontSize: 14,
    marginTop: 20,
    marginBottom: 10,
    marginHorizontal: 10,
    fontWeight: '400',
    color: '#333333',
    lineHeight: 24,
  },
  title: {
    fontWeight: '400',
    fontSize: 17,
    lineHeight: 22,
    color: '#000000',
    marginBottom: 1.85
  },
  description: {
    fontWeight: '400',
    fontSize: 12,
    lineHeight: 16,
    color: 'grey'
  },
  lineStyle:{
    borderWidth: 0.3,
    width: "100%",
    borderColor:'grey',
    marginTop: 7,
},
});
llmtgqce

llmtgqce1#

一种可能的方法是在SECTIONS中的每个定义中引入一个字段,指示要使用的渲染的type(例如extensibleTextListlinkList等),然后在组件之间切换。定义一个组件来进行切换是有意义的,但基本思想相当于:

renderItem={({ item, index, section }) => {
        if (section.type === "linkList")
          return <LinkItem item={item} />
        else if (section.type === "extensibleTextList")
          return <TextItem item={item} />
        // etc
      }

对于“add vehicle”按钮,您可以对SectionListrenderSectionFooter属性使用类似的技术。
this sandbox中有一个基本思想的粗略说明。

vlju58qv

vlju58qv2#

您可以在renderItem回调中添加switch语句,该语句根据您所在的节返回不同的元素。但是,假设:
1.您需要列表和项在每个部分中的行为都不同
1.这些部分似乎不太可能有超过5-10个项目
1.这些部分是提前知道的
我会将每个部分的逻辑分开,并简单地Map这些项。这将使您的SectionList免于承担太多的责任,并使每个部分更容易在以后更改和维护。
理想情况下,每个项目都有一个ID,可以用作键,而不是将键硬编码到列表中。此外,这纯粹是个人喜好,您可以设置节的容器的样式,而不是每个单独的项目。

const general = [
      {
        content: 'John Smith',
        desc: 'Full Name',
      },
      {
        content: 'john.smith@gmail.com',
        desc: 'E-mail',
      },
      {
        content: '(222)123-4567',
        desc: 'Phone Number'
      },
    ];
  const vehicles = [
    // ...
  ];
  const other = [
    // ...
  ];

  return (
    <SafeAreaView style={styles.container}>
      {/* general section here (not shown) */}

      <Text style={styles.header>Vehicles</Text>
      <View style={{ borderRadius: 8, overflow: 'hidden', backgroundColor: 'white' }}>
        {vehicles.map((item, index) => {
          return (
            <View key={item.id}>
              {index > 0 ? <View style={styles.separator} /> : null}
              {/* rest of the item */}         
            </View>
          );
        }
        {/* footer item */}
        <TouchableOpacity onPress={addVehicle}>
          <Text>Add Vehicle</Text>
        </TouchableOpacity>
      </View>

      {/* etc */}

相关问题