javascript - 在 React Native 中使用 Collapsible 创建手风琴
问题描述
我创建了一个手风琴,并为它创建了一些逻辑,但是当我查看我的代码时感觉不对。我不知道在哪里问所以我在这里问。
所以我创建了一个手风琴组件并在我的屏幕上实现了它。这款手风琴的特别之处在于,当一个手风琴打开时,另一个手风琴关闭。所以我用useState()
我转发作为手风琴的道具。我也想把useState()
手风琴放进去,但是当我点击另一个手风琴时,我不知道如何关闭它。所以我创造了这个。
我需要有关如何改进它或如何使其更清洁的提示,因为现在当我查看代码时它可以工作但看起来并不好。
//AccordionCompontent.js
import React from 'react'
import { StyleSheet, View, Text, Dimensions } from 'react-native';
import Collapsible from 'react-native-collapsible';
import { TouchableWithoutFeedback } from 'react-native-gesture-handler';
const Accordion = props => {
return (
<View>
<TouchableWithoutFeedback onPress={props.onPress}>
<View style={styles.accordionContainer}>
<Text style={styles.accordionContainerTitle} >{props.title}</Text>
</View>
</TouchableWithoutFeedback>
<Collapsible style={styles.accordionCollapsedContainer} collapsed={props.isCollapsed}>
{props.accordionRender}
</Collapsible>
</View>
);
}
export default Accordion;
const styles = StyleSheet.create({
accordionContainer: {
justifyContent:'center',
borderBottomWidth: 1,
borderBottomColor: '#fff',
minHeight: Dimensions.get('window').height / 15
},
accordionCollapsedContainer: {
borderBottomWidth: 1,
borderBottomColor: '#fff'
},
accordionContainerTitle: {
color: '#fff',
fontSize: 16,
marginLeft:10
},
})
//InformationScreen.js
import React, { useCallback, useLayoutEffect, useState } from 'react'
import { Text, View, StyleSheet, TouchableWithoutFeedback } from 'react-native';
import Icon from 'react-native-vector-icons/MaterialIcons'
import BodyText from '../components/Atomic/BodyText';
import Accordion from '../components/Accordion/Accordion';
const InformationScreen = props => {
const [isCollapsed, setIsCollapsed] = useState([true, true, true, true, true])
const collapse = (id) => {
let updatetIsCollapsed = [...isCollapsed]
updatetIsCollapsed[id] = !updatetIsCollapsed[id]
const filteredUpdateIsCollapse = updatetIsCollapsed.filter((value, index) => id !== index)
filteredUpdateIsCollapse.forEach(element => {
if (!element) {
const index = filteredUpdateIsCollapse.indexOf(element)
filteredUpdateIsCollapse[index] = true
}
});
filteredUpdateIsCollapse.splice(id, 0, updatetIsCollapsed[id])
setIsCollapsed(filteredUpdateIsCollapse)
}
useLayoutEffect(() => {
props.navigation.setOptions({
title: 'Information',
headerStyle: {
backgroundColor: '#000'
},
headerTitleStyle: {
fontSize: 22,
color: '#fff'
},
headerLeft: () => (
<View></View>
),
headerRight: () => (
<TouchableWithoutFeedback onPress={() => {
props.navigation.popToTop()
}}>
<View style={styles.iconContainer}>
<Icon name="home" size={30} color={'#fff'} />
</View>
</TouchableWithoutFeedback>
)
})
})
return (
<View style={styles.container}>
<Accordion onPress={useCallback(() => {
collapse(0)
},
[isCollapsed, setIsCollapsed],
)} title={"Lorem"} isCollapsed={isCollapsed[0]} accordionRender={
<View style={styles.accordionItemContainer}>
<View style={styles.accordionItemSpacing}>
<BodyText>Lorem Ipsum</BodyText>
<BodyText>Lorem Ipsum</BodyText>
</View>
<View>
<BodyText>Lorem ipsum</BodyText>
<BodyText>Lorem ipsum</BodyText>
</View>
</View>
} />
<Accordion onPress={useCallback(() => {
collapse(1)
},
[isCollapsed, setIsCollapsed],
)} title={"Bla bla"} isCollapsed={isCollapsed[1]} accordionRender={
<View>
<Text>Test</Text>
<Text>Test</Text>
</View>
} />
<Accordion onPress={useCallback(() => {
collapse(2)
},
[isCollapsed, setIsCollapsed],
)} title={"Bla bla"} isCollapsed={isCollapsed[2]} accordionRender={
<View>
<Text>Test</Text>
<Text>Test</Text>
</View>
} />
<Accordion onPress={useCallback(() => {
collapse(3)
},
[isCollapsed, setIsCollapsed],
)} title={"Bla bla"} isCollapsed={isCollapsed[3]} accordionRender={
<View>
<Text>Test</Text>
<Text>Test</Text>
</View>
} />
<Accordion onPress={useCallback(() => {
collapse(4)
},
[isCollapsed, setIsCollapsed],
)} title={"Lorem Ipsum"} isCollapsed={isCollapsed[4]} accordionRender={
<View style={styles.accordionItemContainer}>
<View style={styles.accordionItemSpacing}>
<BodyText>Lorem Ipsum</BodyText>
<BodyText>Lorem Ipsum</BodyText>
</View>
<View>
<BodyText>Lorem ipsum</BodyText>
<BodyText>Lorem ipsum</BodyText>
</View>
</View>
} />
</View>
);
}
const styles = StyleSheet.create({
container: {
backgroundColor: '#000',
flex: 1,
borderTopWidth: 2,
borderTopColor: '#fff'
}
,
iconContainer: {
height: 50,
width: 50,
borderLeftWidth: 2,
borderLeftColor: '#fff',
overflow: 'hidden',
justifyContent: 'center',
alignItems: 'flex-end'
},
accordionContainerTitle: {
color: '#000',
fontSize: 16,
},
accordionItemContainer: {
paddingVertical: 10,
},
accordionItemText: {
color: '#000',
fontSize: 16,
marginHorizontal: 10,
},
accordionItemSpacing: {
marginBottom: 10
}
})
export default InformationScreen;
解决方案
- 取下挂钩。JSX/多伦多证券交易所
- 按功能生成手风琴
- 使用地图索引道具来切换手风琴
import React, { useCallback, useLayoutEffect, useState } from 'react'
import { Text, View, StyleSheet, TouchableWithoutFeedback } from 'react-native';
import Icon from 'react-native-vector-icons/MaterialIcons'
import BodyText from '../components/Atomic/BodyText';
import Accordion from '../components/Accordion/Accordion';
const getaccordianItems = () => ([
<View style={styles.accordionItemSpacing}>
<BodyText>Lorem Ipsum</BodyText>
<BodyText>Lorem Ipsum</BodyText>
</View>
<View>
<BodyText>Lorem ipsum</BodyText>
<BodyText>Lorem ipsum</BodyText>
</View>,
<View>
<Text>Test</Text>
<Text>Test</Text>
</View>,
<View>
<Text>Test</Text>
<Text>Test</Text>
</View>,
<View>
<Text>Test</Text>
<Text>Test</Text>
</View>,
<View>
<Text>Test</Text>
<Text>Test</Text>
</View>
])
const InformationScreen = props => {
const [isExpandedIndex, setIsExpanded] = useState();
useLayoutEffect(() => {
props.navigation.setOptions({
title: 'Information',
headerStyle: {
backgroundColor: '#000'
},
headerTitleStyle: {
fontSize: 22,
color: '#fff'
},
headerLeft: () => (
<View></View>
),
headerRight: () => (
<TouchableWithoutFeedback onPress={() => {
props.navigation.popToTop()
}}>
<View style={styles.iconContainer}>
<Icon name="home" size={30} color={'#fff'} />
</View>
</TouchableWithoutFeedback>
)
})
})
return (
<View style={styles.container}>
{accordionList.map((item,index)=>(
<Accordion onPress={()=> { setIsExpanded(index) }} title={"Lorem"} isCollapsed={isExpanded !== index} accordionRender={
<View style={styles.accordionItemContainer}>
{item}
</View>
} />
)}
</View>
);
}
const styles = StyleSheet.create({
container: {
backgroundColor: '#000',
flex: 1,
borderTopWidth: 2,
borderTopColor: '#fff'
}
,
iconContainer: {
height: 50,
width: 50,
borderLeftWidth: 2,
borderLeftColor: '#fff',
overflow: 'hidden',
justifyContent: 'center',
alignItems: 'flex-end'
},
accordionContainerTitle: {
color: '#000',
fontSize: 16,
},
accordionItemContainer: {
paddingVertical: 10,
},
accordionItemText: {
color: '#000',
fontSize: 16,
marginHorizontal: 10,
},
accordionItemSpacing: {
marginBottom: 10
}
})
export default InformationScreen;
推荐阅读
- for-loop - For循环纯函数玩笑测试使用expect ...无法读取属性
- python-3.x - 行作为列行到二维数组中| Python
- python - Postgres(通过 sqlalchemy)不允许我替换表(如果存在)
- linux - 返回菜单选择文件是否相同
- html - SCSS - 在句子中间创建下划线的伪元素
- mysql - mysql 在 order by 上返回一个跳过的行,具有相同的日期和时间
- azure - 如何将 Application Insights 从一个区域迁移到另一个区域?
- c# - C# 无论如何要从 IQueryable 聚合(不是 AsEnumerable)
- python - 熊猫合并数据框从末尾移动新列
- python - 单个值的按位异或校验和?