动态填充嵌套的 react-native-collapsible

Dynamically populating nested react-native-collapsible

我需要用 api 请求中的项目填充菜单。 我做了一些样品; const items。有些菜单项有子项,子项也可以有子项,所以我需要嵌套几级菜单项。

我用 react-native-collapsible 制作了一个 Accordion() 和一个 AccordionItem() 用于没有子项的项目。

function App() 渲染菜单项两次。一次通过手动添加 Accordions 和 AccordionItems,一次通过映射 items[]RootMenuItem() 为每个顶级项目调用并通过递归呈现该项目及其子项目。

当手动添加每个项目时,它按照我想要的方式工作。我需要以编程方式填充菜单,但 RootMenuItem() 呈现的嵌套手风琴在 android 和 iOS 上表现不佳。在 snack.io 上进行 Web 测试时,它似乎工作正常。

这是我完整的零食App.js: https://snack.expo.dev/@dissar/nested-collapsibles

我是不是做错了什么? 有人有更好的方法来做这件事吗?

PS:在 snack.io 上测试时,动态呈现的项目具有奇怪的宽度,但请不要担心。

我似乎已经通过删除第 46 和 56 行的视图自行修复了它;

function RootMenuItem({item}){
  if(item.children.length > 0) {
    return(
      <View style={{flex: 1}} key={item.id}>    // <---- I removed this
        <Accordion item={item} style={styles.menuItemView}>
          {
            item.children.map(child => (
              <View style={{paddingLeft: 18}} key={child.id}>
                <RootMenuItem item={child} style={{paddingLeft: 10}}/>
              </View>
            ))
          }
        </Accordion>
      </View> // <---- Also removed this
    )
  }
  else return (
    <AccordionItem item={item}/>
  )
}

不太确定为什么该视图使嵌套手风琴无法正常工作。如果您有答案,请告诉我。

我有一个更好的解决方案,无需使用任何第 3 方库。这是完全定制的并且易于理解。我使用的数据格式与您使用的相同。

首先,我们有一个组件

const [active, setActive] = useState(null);
return (
<ScrollView
  style={{ marginTop: 50 }}
  contentContainerStyle={styles.container}>
  {arr.map((x, i) => (
    <Item
      key={x.name}
      active={active}
      i={i}
      setActive={setActive}
      child={x.child}
    />
  ))}
</ScrollView>

);

然后是列表项及其子项

function Item({ i, active, setActive, child }) {
  const onPress = () => {
    LayoutAnimation.easeInEaseOut();
    setActive(i == active ? null : I);
  };
  const [childActive, setChildActive] = useState(null);
  const open = active == I;
  return (
<TouchableOpacity style={styles.item} onPress={onPress} activeOpacity={1}>
  <View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
    <Text>Header - {i + 1}</Text>
    {child.length ? <Text>{open ? 'close' : 'open'}</Text> : null}
  </View>
  {open &&
    child.map((x, i) => {
      if (x.child.length) {
        return (
          <Item
            key={x}
            active={childActive}
            i={i}
            setActive={setChildActive}
            child={x.child}
          />
        );
      }
      return (
        <Text key={x} style={styles.subItem}>
          - SOME DATA
        </Text>
      );
    })}
</TouchableOpacity>
);
}

这是一个完全动态的过程,您可以根据需要延长链条。您还可以查看博览会以查看其作品。 https://snack.expo.dev/@akash0208/forlorn-popsicle