动态填充嵌套的 react-native-collapsible
Dynamically populating nested react-native-collapsible
我需要用 api 请求中的项目填充菜单。
我做了一些样品; const items
。有些菜单项有子项,子项也可以有子项,所以我需要嵌套几级菜单项。
我用 react-native-collapsible 制作了一个 Accordion()
和一个 AccordionItem()
用于没有子项的项目。
function App()
渲染菜单项两次。一次通过手动添加 Accordion
s 和 AccordionItem
s,一次通过映射 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
我需要用 api 请求中的项目填充菜单。
我做了一些样品; const items
。有些菜单项有子项,子项也可以有子项,所以我需要嵌套几级菜单项。
我用 react-native-collapsible 制作了一个 Accordion()
和一个 AccordionItem()
用于没有子项的项目。
function App()
渲染菜单项两次。一次通过手动添加 Accordion
s 和 AccordionItem
s,一次通过映射 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