![](/img/trans.png)
[英]How to use `this` in react-native-collapsible accordion component?
[英]Creating an Accordion in React Native with 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;
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;
好的,在Michael Bahl的帮助下,我能够编写一些更好的代码。 他的代码很好,但我对它做了一些调整。 现在一切正常,我可以把我需要的所有东西放在我的手风琴里。
我对accordionCompontent.js 进行了一个小改动,在屏幕上,我应用了Michael 展示的代码,并进行了一些小调整,使其对我来说更加灵活。
//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}
//The small change is at collapsed
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
},
})
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 getAccordionItems = (version, expiresDate, scriptSize, packageSize) => ([
['General Information',
<View>
<View style={styles.accordionItemSpacing}>
<BodyText>Version {version}</BodyText>
<BodyText>License expires on {expiresDate}</BodyText>
</View>
<View>
<BodyText>Size of scripts folder: {scriptSize} MB</BodyText>
<BodyText>Size of packages folder: {packageSize} MB</BodyText>
</View>
</View>],
['lorem',
<View>
<View style={styles.accordionItemSpacing}>
<BodyText>Lorem Ipsum</BodyText>
<BodyText>Lorem Ipsum</BodyText>
</View>
<View>
<BodyText>Lorem ipsum</BodyText>
<BodyText>Lorem ipsum</BodyText>
</View>
</View>],
['lorem',
<View>
<View style={styles.accordionItemSpacing}>
<BodyText>Lorem Ipsum</BodyText>
<BodyText>Lorem Ipsum</BodyText>
</View>
<View>
<BodyText>Lorem ipsum</BodyText>
<BodyText>Lorem ipsum</BodyText>
</View>
</View>],
])
const InformationScreen = props => {
const accordionList = getAccordionItems('1.0', '2021/10/20', 1.00, 0.00)
const [isExpanded, 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>
)
})
})
accordionList.map((item, index) => {
console.log(item)
console.log(index)
})
return (
<View style={styles.container}>
{accordionList.map((item, index) => (
<Accordion onPress={() => {
if (isExpanded === index){
setIsExpanded(accordionList.size)
} else{
setIsExpanded(index)
}
}} title={item[0]} isCollapsed={isExpanded === index} accordionRender={
<View style={styles.accordionItemContainer}>
{item[1]}
</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: '#fff',
fontSize: 16,
},
accordionItemContainer: {
paddingVertical: 10,
},
accordionItemText: {
color:'#fff',
fontSize: 16,
marginHorizontal: 10,
},
accordionItemSpacing: {
marginBottom: 10
}
})
export default InformationScreen;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.