我正在尝试向元素添加样式,但是样式适用于所有元素。如何获得仅单击元素而不是全部元素的样式?
我希望元素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;
答案 0 :(得分:1)
您需要区分不同的可触摸对象。您不应该为此使用数组索引(因为您的“键”道具当前为),如果它是一些唯一的ID,那就太好了。但是在这种情况下,为简单起见,我可以展示如何使用数组索引。
您的状态:
state = { ActiveDances: "your list", selectedDance: null }
在舞蹈中选择:
_showListItem = (index) => {
if(this.state.selectedDance === index) { // if the dance is selected, unselect it
this.setState({
selectedDance: null
});
} else { // if the dance is not selected, select it
this.setState({
selectedDance: index
});
}
}
您可触摸的
<TouchableOpacity
key={i}
style={this.state.selectedDance === i ? styles.listItemsDynamicOpen :
styles.listItemsDynamicClosed}
onPress={() => this._showListItem(i)}>
答案 1 :(得分:1)
您跟踪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
)的任何数据,都可以将其作为道具传递并通过this.props
接收。更多信息:https://reactjs.org/docs/components-and-props.html
由于您是新手,因此请查看javascript代码中的良好做法。我想指出的一件事:在命名变量引用时使用camelCase。对于首字母大写的情况,名称开头应仅用于标签/组件名称。
我希望它能对您有所帮助。欢迎使用React和React Native:)
答案 2 :(得分:0)
好吧,您可以使用此技巧。您可以使用TouchableHighlight
:
import React, { Component } from 'react';
import { View, StyleSheet, Text, TouchableOpacity, TouchableHighlight } 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"},
],
pressStatus:false,
};
_onHideUnderlay() {
this.setState({ onPressStatus: false });
}
_onShowUnderlay() {
this.setState({ pressStatus: true });
}
render() {
const activedance = this.state.ActiveDances.map((ActiveDance, i) => {
return (
<TouchableHighlight
activeOpacity={1}
style={
this.state.pressStatus
? styles.listClicked
: styles.listItemsDynamicOpen
}
onHideUnderlay={this._onHideUnderlay.bind(this)}
onShowUnderlay={this._onShowUnderlay.bind(this)}
>
<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>
</TouchableHighlight >
);
});
return (
<View style={styles.listItems}>{activedance}</View>
);
}
}