reactjs - React Native 动态样式,给一个元素添加样式
问题描述
我正在尝试为元素添加样式,但样式会出现在所有元素上。如何为单击的元素而不是所有元素获取样式?
我希望元素 TouchableOpacity 在单击时添加 listItemsDynmaicOpen 的样式,女巫确实如此,但问题是它将样式添加到我的所有 TouchableOpacity 元素中。
那么我该怎么做才能在按下的 TouchableOpacity 上获得样式呢?
顺便说一句,我是 React 和 React-Native 的新手
import React, { Component } from 'react';
import { View, StyleSheet, Text, TouchableOpacity } from 'react-native';
import ListItemHeart from './ListItemHeart/ListItemHeart';
class ListItems extends Component {
state = {
ActiveDances: [
{"name":"Agneta & Peter","month":"Jan","day":27,"weekday":"Söndag","place":"Kulturens hus Bollnäs","time":"18.00-21.30","city":"Bollnäs"},
{"name":"Agneta & Peter","month":"Feb","day":23,"weekday":"Fredag","place":"Kulturens hus Bollnäs","time":"18.00-21.30","city":"Bollnäs"},
{"name":"Agneta & Peter","month":"Apr","day":3,"weekday":"Måndag","place":"Kulturens hus Bollnäs","time":"18.00-21.30","city":"Bollnäs"},
{"name":"Agneta & Peter","month":"Aug","day":1,"weekday":"Lördag","place":"Kulturens hus Bollnäs","time":"18.00-21.30","city":"Bollnäs"},
{"name":"Agneta & Peter","month":"Aug","day":1,"weekday":"Lördag","place":"Kulturens hus Bollnäs","time":"18.00-21.30","city":"Bollnäs"},
{"name":"Agneta & Peter","month":"Aug","day":1,"weekday":"Lördag","place":"Kulturens hus Bollnäs","time":"18.00-21.30","city":"Bollnäs"},
{"name":"Agneta & Peter","month":"Aug","day":1,"weekday":"Lördag","place":"Kulturens hus Bollnäs","time":"18.00-21.30","city":"Bollnäs"},
{"name":"Agneta & Peter","month":"Aug","day":1,"weekday":"Lördag","place":"Kulturens hus Bollnäs","time":"18.00-21.30","city":"Bollnäs"},
{"name":"Agneta & Peter","month":"Aug","day":1,"weekday":"Lördag","place":"Kulturens hus Bollnäs","time":"18.00-21.30","city":"Bollnäs"},
],
listClicked: false
};
_showListItem = () => {
if(this.state.listClicked) {
this.setState({
listClicked: false
});
}else{
this.setState({
listClicked: true
});
}
}
render() {
const activedance = this.state.ActiveDances.map((ActiveDance, i) => {
return (
<TouchableOpacity key={i} style={this.state.listClicked ? styles.listItemsDynamicOpen : styles.listItemsDynamicClosed} onPress={this._showListItem}>
<View style={styles.listItemsDate}>
<Text style={styles.listItemsDaytext}>{ActiveDance.day}</Text>
<Text style={styles.listItemsBoldtext}>{ActiveDance.month}</Text>
</View>
<View style={styles.listItemsInfo}>
<Text style={styles.nametext}>{ActiveDance.name}</Text>
<View style={styles.listItemsInfoDayTime}>
<Text style={styles.normaltext}>{ActiveDance.weekday}</Text>
<Text style={styles.normaltext}>{ActiveDance.time}</Text>
</View>
<Text style={styles.normaltext}>{ActiveDance.place}</Text>
<Text style={styles.normaltext}>{ActiveDance.city}</Text>
</View>
<View style={styles.heart}>
<ListItemHeart />
</View>
</TouchableOpacity>
);
});
return (
<View style={styles.listItems}>{activedance}</View>
);
}
}
const styles = StyleSheet.create({
listItems: {
width: "100%",
backgroundColor:"#f2f2f2",
paddingTop:15
},
listItemsDynamicClosed: {
width:"100%",
height:110,
marginBottom: 10,
flexDirection: 'row',
backgroundColor: "white",
},
listItemsDynamicOpen: {
width: "100%",
height: 200,
marginBottom: 10,
flexDirection: "row",
backgroundColor: "white"
},
listItemsDate: {
width:"15%",
height: 50,
alignItems:"center",
marginTop:10
},
heart: {
width:"10%",
alignItems:"center",
justifyContent:"center"
},
listItemsInfo: {
marginLeft:10,
width:"65%"
},
listItemsInfoDayTime: {
width:"60%",
flexDirection:'row',
justifyContent:'space-between'
},
listItemsDaytext:{
fontSize: 20,
color:"#39B54A"
},
listItemsBoldtext: {
fontSize: 19
},
nametext:{
paddingTop:5,
paddingBottom:5,
fontSize:19,
color:"#808080"
},
normaltext: {
fontSize: 16,
paddingTop:1,
paddingBottom:1,
color:"#4d4d4d"
}
});
export default ListItems;
解决方案
您跟踪点击listClicked
的状态正在通过所有TouchableOpacity
项目共享。如果我们尝试模拟执行时发生this.state.ActiveDances.map
的情况,它会返回所有ActiveDances
项目,例如:
<TouchableOpacity key=0 style={styles.listItemsDynamicClosed> </TouchableOpacity>
<TouchableOpacity key=1 style={styles.listItemsDynamicClosed> </TouchableOpacity>
<TouchableOpacity key=2 style={styles.listItemsDynamicClosed> </TouchableOpacity>
......
注意这里styles.listItemsDynamicClosed
是因为这个表达式this.state.listClicked ? styles.listItemsDynamicOpen : styles.listItemsDynamicClosed}
,因为你this.state.listClicked
还false
没有点击。
现在,当您单击并且this.state.listClicked
是true
并且由于所有人都在TouchableOpacity
共享它时,所有这些都呈现为:
<TouchableOpacity key=0 style={styles.listItemsDynamicOpen> </TouchableOpacity>
<TouchableOpacity key=1 style={styles.listItemsDynamicOpen> </TouchableOpacity>
<TouchableOpacity key=2 style={styles.listItemsDynamicOpen> </TouchableOpacity>
......
这就是将其分解为小组件的地方。想象一下,如果您有一个只返回一个的组件,TouchableOpacity
那么您可以listClicked
只应用一个TouchableOpacity
并且只有点击的那个会更新。
//ClickableItem.js
class ClickableItem extends Component {
state = {
listClicked = false,
}
_showListItem = () => {
this.setState({
listClicked: !this.state.listClicked
})
render() {
return(
<TouchableOpacity style={this.state.listClicked ? syles.listItemsDynamicOpen : styles.listItemsDynamicClosed} onPress={this._showListItem}>
...
</TouchableOpacity>
)
}
}
export default ClickableItem
然后在主/父组件中:
//List.js
import ClickableItem from './ClickableItem.js'
class List extends Component {
state = {
ActiveDances: [
{"name":"Agneta & Peter","month":"Jan","day":27,"weekday":"Söndag","place":"Kulturens hus Bollnäs","time":"18.00-21.30","city":"Bollnäs"},
{"name":"Agneta & Peter","month":"Feb","day":23,"weekday":"Fredag","place":"Kulturens hus Bollnäs","time":"18.00-21.30","city":"Bollnäs"},
{"name":"Agneta & Peter","month":"Apr","day":3,"weekday":"Måndag","place":"Kulturens hus Bollnäs","time":"18.00-21.30","city":"Bollnäs"},
{"name":"Agneta & Peter","month":"Aug","day":1,"weekday":"Lördag","place":"Kulturens hus Bollnäs","time":"18.00-21.30","city":"Bollnäs"},
{"name":"Agneta & Peter","month":"Aug","day":1,"weekday":"Lördag","place":"Kulturens hus Bollnäs","time":"18.00-21.30","city":"Bollnäs"},
{"name":"Agneta & Peter","month":"Aug","day":1,"weekday":"Lördag","place":"Kulturens hus Bollnäs","time":"18.00-21.30","city":"Bollnäs"},
{"name":"Agneta & Peter","month":"Aug","day":1,"weekday":"Lördag","place":"Kulturens hus Bollnäs","time":"18.00-21.30","city":"Bollnäs"},
{"name":"Agneta & Peter","month":"Aug","day":1,"weekday":"Lördag","place":"Kulturens hus Bollnäs","time":"18.00-21.30","city":"Bollnäs"},
{"name":"Agneta & Peter","month":"Aug","day":1,"weekday":"Lördag","place":"Kulturens hus Bollnäs","time":"18.00-21.30","city":"Bollnäs"},
]
}
render() {
return(
this.state.ActiveDances.map((ActiveDance, i) => <ClickableItem key={i}>)
)
}
}
您需要传递给子组件的任何数据(ClickableItem
在这种情况下),您都可以将其作为 props 传递并通过this.props
. 更多信息:https ://reactjs.org/docs/components-and-props.html
由于您是新手,请查看 javascript 代码中的良好实践。我想指出一件事:在命名变量引用时使用 camelCase。对于名称开头的反应大写,应仅用于标签/组件名称。
我希望它对你有帮助。欢迎使用 React 和 React Native :)