如何在React Native中访问父组件中的子组件值(在ListView中)

时间:2016-11-27 11:20:39

标签: reactjs react-native react-jsx

我的应用有一个列表视图,可以呈现项目列表。

Screenshot

每次点击我的子组件都会触发状态值的更改

{ selected: !this.state.selected }

在上图中,我选择了2个子项,如何在父组件中访问它们的值?

例如,

Big Data: true
IoT: true

这是我的父代码段Hosted on Github too

import InterestItem from './InterestItem';

class AddInterest extends Component {

  componentWillMount() {
    this.createDataSource(this.props);
  }

  componentWillReceiveProps(nextProps) {
    this.createDataSource(nextProps);
  }

  createDataSource({ items }) {
    const ds = new ListView.DataSource({
      rowHasChanged: (r1, r2) => r1 !== r2
    });
    this.dataSource = ds.cloneWithRows(items);
  }

  //return arrays of event from events
  renderRow(item) {
    return <InterestItem item={item} icon={computer} />;
  }

  render() {
    const { centerEverything, skeleton, container, textContainer, contentContainer, listViewContainer,
      titleContainer, descContainer, title, desc, submitContainer, submitTitle } = styles;
    return (
      <View style={[container]}>
        <View style={[centerEverything, textContainer]}>
          <View style={titleContainer}>
            <Text style={[title]}>What kind of events are you interest in?</Text>
          </View>
          <View style={descContainer}>
            <Text style={[desc]}>You'll see more events from the categories you choose.</Text>
          </View>
        </View>

        <View style={[contentContainer]}>
          <ListView
            enableEmptySections
            contentContainerStyle={listViewContainer}
            dataSource={this.dataSource}
            renderRow={this.renderRow}
          />
        </View>

        <View style={[centerEverything, {paddingBottom: 10}]}>
          <View style={[centerEverything, submitContainer]}>
            <Text style={submitTitle}>Submit</Text>
          </View>
        </View>

      </View>
    )
  }
}

这是我的子组件Hosted on GitHub too

class InterestItem extends Component {

  state = {
    selected: false
  }

  render() {
    const { skeleton, centerEverything, container, textStyle } = styles;
    return(
      <TouchableWithoutFeedback onPress={() => this.setState({ selected: !this.state.selected })}>
        <View style={[centerEverything, container, { backgroundColor: this.state.selected ? '#635eb4' : '#e7e7e7'}]}>
          {this.props.icon}
          <Text style={textStyle}>{this.props.item[0]}</Text>
        </View>
      </TouchableWithoutFeedback>
    )
  }
}

根据@freesoul的要求,这是儿童实例(考虑到我有8个孩子) enter image description here

1 个答案:

答案 0 :(得分:2)

跟进@ free-soul,我会对你的代码进行以下修改:

constructor(){
    this.state = {
    //...
        rowStates: {} // Holds the state for each row, identified by the uid property (I'm assuming it is unique, otherwise use some other value)
    }
    this.renderRow = this.renderRow.bind(this);
    this.rowUpdated = this.rowUpdated.bind(this);
}
renderRow(item) {
   // Adds a callback so that we know when an element has been pressed
    return <InterestItem item={item} icon={computer} onPress={() => this.rowUpdated(item)}/>;
}

rowUpdated(item){
     let rowStates = {...this.state.rowStates}; // Make a copy of the object
     rowStates[item.uid] = !rowStates[item.uid];  // If the item is not in the object, !undefined will be evaluated, which results in true, so the operation is safe
     this.setState({rowStates});
}

然后,您的子组件应如下所示:

class InterestItem extends Component {

  state = {
    selected: false
  }

  render() {
    const { skeleton, centerEverything, container, textStyle } = styles;
    return(
      <TouchableWithoutFeedback onPress={() => {this.setState({ selected: !this.state.selected }); if(this.props.onPress) this.props.onPress(this.props.item)}}>
        <View style={[centerEverything, container, { backgroundColor: this.state.selected ? '#635eb4' : '#e7e7e7'}]}>
          {this.props.icon}
          <Text style={textStyle}>{this.props.item[0]}</Text>
        </View>
      </TouchableWithoutFeedback>
    )
  }
}

希望有所帮助