反应本机动态样式,将样式添加到一个元素

时间:2019-02-11 13:28:34

标签: 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;

3 个答案:

答案 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.listClickedtrue时,由于所有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>
        );
}

}