首页 > 解决方案 > 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;

标签: reactjsreact-native

解决方案


您跟踪点击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.listClickedfalse没有点击。

现在,当您单击并且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在这种情况下),您都可以将其作为 props 传递并通过this.props. 更多信息:https ://reactjs.org/docs/components-and-props.html

由于您是新手,请查看 javascript 代码中的良好实践。我想指出一件事:在命名变量引用时使用 camelCase。对于名称开头的反应大写,应仅用于标签/组件名称。

我希望它对你有帮助。欢迎使用 React 和 React Native :)


推荐阅读