如何在 React Native 中通过 TouchableOpacity 更新 onPress 状态?

How can I update state once onPress via TouchableOpacity in React Native?

所以我正在渲染一个包含两列项目的 ListView。以下函数呈现行,renderRow(rowData):

对于每个项目,如果单击,我希望将其更改为 0.5 的不透明度,如果再次单击,希望它返回以清除不透明度,所以我想将其设置为 1.0 的不透明度.

我尝试了以下方法,但由于某种原因不更新不透明度:

  constructor(props){
    super(props);

    this.state = {
      opacity: 1.0,
      selected: false,
    }
  }

  renderRow(rowData){
    return (
          <View style={styles.item}>
            <TouchableHighlight onPress={()=>this._selected() underlayColor='transparent'}>
              <View style={{opacity:this.state.opacity}}>
                <Text>{rowData.firstName}</Text>
                <Text>{rowData.lastName}</Text>
              </View>
            </TouchableHighlight>
          </View>
    )
  }

  _selected(){
    if(this.state.selected){
      console.log('ITEM HAS BEEN UNSELECTED')
      this.setState({
        opacity: 1.0,
        selected: false
      })
    }else{
      console.log('ITEM HAS BEEN SELECTED')
      this.setState({
        opacity: 0.5,
        selected: true
      })
    }
  }

为什么在单击并重新呈现 TouchableHighlight 内的视图后不更新不透明度?另外,我该如何处理单个项目,每个项目的 'opacity' 和 'selected' 状态?

**完整代码

'use strict';

import React, { Component } from 'react';
import {
  StyleSheet,
  Text,
  View,
  ListView,
  Image,
  TouchableHighlight,
  TouchableOpacity
} from 'react-native';

class Interest extends Component {
  constructor(props){
    super(props);

    var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});

    this.state = {
      selected: false,
      dataSource: ds.cloneWithRows([
      {firstName: 'Johnny', lastName: 'Boy'},
      {firstName: 'Shawn', lastName: 'Ke'},
      {firstName: 'An', lastName: 'Twon'}
    };
  }

  renderRow(rowData){
    return (
          <View style={this.state.selected ? styles.transItem : styles.opacItem}>
            <TouchableHighlight
              onPress={ () => { this.setState({selected: !this.state.selected})}} underlayColor='transparent'>
              <View>
                <Text>{rowData.firstName}</Text>
                <Text>{rowData.lastName}</Text>
              </View>
            </TouchableHighlight>
          </View>
    )
  }

  render() {
    return (
      <View style={styles.container}>
        <ListView contentContainerStyle={styles.list} dataSource={this.state.dataSource} renderRow={this.renderRow.bind(this)}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1
  },
  list: {
    flexDirection: 'row',
    flexWrap: 'wrap',
  },
  opacItem: {
    margin: 15,
    width: 155,
    height: 175,
    opacity: 1.0
  },
  transItem: {
    margin: 15,
    width: 155,
    height: 175,
    opacity: 0.5
  }
});

export default Interest

我认为您设置了非预期的 selected 状态。

在上面的代码中,selected 是整个应用程序的状态 - 而不仅仅是 selected 行。对于 select 单行,您应该为每个项目保持 selected 状态。对于更简洁的代码,建议为该项目使用另一个模块,并将状态保留在那里而不是在父模块中。

代码:

'use strict';

import React, { Component } from 'react';
import {
  StyleSheet,
  Text,
  View,
  ListView,
  Image,
  TouchableHighlight,
  TouchableOpacity
} from 'react-native';

class Interest extends Component {
  constructor(){
    super();
    this._renderRow = this._renderRow.bind(this);
    var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});

    this.state = {
      dataSource: ds.cloneWithRows([
        {firstName: 'Johnny', lastName: 'Boy'},
        {firstName: 'Shawn', lastName: 'Ke'},
        {firstName: 'An', lastName: 'Twon'}
      ])};
    }

    render() {
      return (
        <View style={styles.container}>
          <ListView
            contentContainerStyle={styles.list}
            dataSource={this.state.dataSource}
            renderRow={this._renderRow}
          />
        </View>
      );
    }

    _renderRow(rowData) {
      return(
        <InterestItem rowData={rowData} />);
    }
  }

  class InterestItem extends Component {
    constructor(props){
      super(props);
      this.state = {
        selected: false
      }
    }

    render(){
      const { rowData } = this.props;
      return (
        <View style={this.state.selected ? styles.transItem : styles.opacItem}>
          <TouchableHighlight
            onPress={ () => { this.setState({selected: !this.state.selected})}}
            underlayColor='transparent'
          >
            <View>
              <Text>{rowData.firstName}</Text>
              <Text>{rowData.lastName}</Text>
            </View>
          </TouchableHighlight>
        </View>
      )
    }
  }

  const styles = StyleSheet.create({
    container: {
      flex: 1
    },
    list: {
      flexDirection: 'row',
      flexWrap: 'wrap',
    },
    opacItem: {
      margin: 15,
      width: 155,
      height: 175,
      opacity: 1.0
    },
    transItem: {
      margin: 15,
      width: 155,
      height: 175,
      opacity: 0.5
    }
  });

  export default Interest