0

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

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

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

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

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

难道我做错了什么?有没有人有任何提示可以更好地做到这一点?

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

4

2 回答 2

0

我似乎已经通过删除第 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}/>
  )
}

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

于 2021-10-21T12:58:25.863 回答
0

在不使用任何 3rd 方库的情况下,我有更好的解决方案。这是完全定制的并且易于理解。我使用了与您使用的相同格式的数据。

首先,我们有一个组件

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

于 2022-03-01T20:27:55.730 回答