繁体   English   中英

单击FlatList元素时如何打开带有项目信息的Modal?

[英]How to open Modal with item information when clicking a FlatList element?

我要实现的目标是,当用户按下FlatList组件之一时,打开一个模式对话框。 此列表的代码如下所示:

class MyItem extends React.Component { 
  _onPress = () => { 
    this.props.onPressItem(this.props.item); 
  }; 
  render() { 
    return(
        <TouchableOpacity 
            {...this.props}
            onPress={this._onPress}
            >
            <Text style={styles.itemText}> {this.props.item.name}</Text>
        </TouchableOpacity>
    ) 
  } 
}

export default class MyList extends React.PureComponent {
    constructor(props) {
        super(props);
        this.state = {
            data: {}, // some data correctly loaded
            isModalVisible: false
        };
    };

    _onPressItem = (item) => { 
        this._showModal;
    };

    _showModal = () => this.setState({ isModalVisible: true })

    _keyExtractor = (item, index) => item.id;

    _renderItem = ({item}) => (
        <MyItem 
            style={styles.row}
            item={item}
            onPressItem={this._onPressItem}
        />
    );

    render() {
      return(
        <KeyboardAvoidingView behavior="padding" style={styles.container}>
          <View style={styles.titleContainer}>
              <Text style={styles.title}>Tittle</Text>
          </View>
          <ScrollView style={styles.container}>
              <FlatList 
                  data={this.state.data}
                  ItemSeparatorComponent = {this._flatListItemSeparator}
                  renderItem={this._renderItem}
                  keyExtractor={this._keyExtractor}
              />
          </ScrollView>
          <MyModal modalVisible={this.state.isModalVisible}/>
        </KeyboardAvoidingView>
      );
    }
}

样式,FlatList数据和某些功能已删除,因为它们与此问题无关。

如您所见, MyModal组件在ScrollView组件之后声明。 该代码基于使用react-native Modal组件:

export default class MyModal extends Component {
  constructor(props) {
    super(props);
    this.state = {
        isModalVisible: props.modalVisible
    };
  };

  _setModalVisible(visible) {
    this.setState({modalVisible: visible});
  }

  render() {
    return (
        <View>
            <Modal
            animationType="slide"
            transparent={false}
            visible={this.state.modalVisible}
            onRequestClose={() => {alert("Modal has been closed.")}}
            >
                <View style={styles.container}>
                    <View style={styles.innerContainer}>
                        <Text>Item Detail</Text>
                        <TouchableHighlight
                            style={styles.buttonContainer}
                            onPress={() => { this._setModalVisible(false) }}>
                            <Text style={styles.buttonText}>Close</Text> 
                        </TouchableHighlight>
                    </View>
                </View>
            </Modal>
        </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    padding: 20,
    backgroundColor: 'transparent',
  },
  innerContainer: {
    borderRadius: 10,
    alignItems: 'center',
    backgroundColor: '#34495e',
 },
 buttonContainer: {
    paddingVertical: 15,
    marginTop: 20,
    backgroundColor: '#2c3e50',
    borderRadius: 15
 },
 buttonText: {
    textAlign: 'center',
    color: '#ecf0f1',
    fontWeight: '700'
 },
});

目前的行为是MyModal当我访问显示组件MyList组件的第一次,我可以关闭它,然后FlatList是存在的,但是当按下列表项, MyModal不显示组件。

仅在按下列表项时,如何才能隐藏Modal并打开它?

与此相关的另一个疑问是:

如何将按下的项目对象传递给MyModal组件?

提前致谢!

class MyItem extends React.Component { 
  _onPress = () => { 
    this.props.onPressItem(this.props.item); 
  }; 
  render() { 
    return(
        <TouchableOpacity 
            {...this.props}
            onPress={this._onPress}
            >
            <Text style={styles.itemText}> {this.props.item.name}</Text>
        </TouchableOpacity>
    ) 
  } 
}

export default class MyList extends React.PureComponent {
    constructor(props) {
        super(props);
        this.state = {
            data: {}, // some data correctly loaded
            isModalVisible: false,
            selectedItem: null
        };
    };

    _onPressItem = (item) => { 
        this._showModal(item);
    };

    _hideMyModal = () => {
        this.setState({isModalVisible: false})
    }

    _showModal = (item) => this.setState({ isModalVisible: true, 
    selectedItem: item })

    _keyExtractor = (item, index) => item.id;

    _renderItem = ({item}) => (
        <MyItem 
            style={styles.row}
            item={item}
            onPressItem={() => this._onPressItem(item)}
        />
    );

    render() {
      return(
        <KeyboardAvoidingView behavior="padding" style={styles.container}>
          <View style={styles.titleContainer}>
              <Text style={styles.title}>Tittle</Text>
          </View>
          <ScrollView style={styles.container}>
              <FlatList 
                  data={this.state.data}
                  ItemSeparatorComponent = {this._flatListItemSeparator}
                  renderItem={this._renderItem}
                  keyExtractor={this._keyExtractor}
              />
          </ScrollView>
          { this.state.isModalVisible && <MyModal selectedItem={this.state.selectedItem} modalVisible={this.state.isModalVisible} hideModal={this_hideMyModal} /> }
        </KeyboardAvoidingView>
      );
    }
}

当您在FlatList中按下该项目时,只需将其设置为状态,然后将其作为道具传递给MyModal组件即可。

export default class MyModal extends Component {
  constructor(props) {
    super(props);
    this.state = {
        isModalVisible: props.modalVisible
    };
  };

  _setModalVisible(visible) {
    this.setState({modalVisible: visible});
  }

  render() {
    return (
        <View>
            <Modal
            animationType="slide"
            transparent={false}
            visible={this.state.isModalVisible}
            onRequestClose={() => {alert("Modal has been closed.")}}
            >
                <View style={styles.container}>
                    <View style={styles.innerContainer}>
                        <Text>Item Detail</Text>
                        <TouchableHighlight
                            style={styles.buttonContainer}
                            onPress={() => { this.props.hideModal() }}>
                            <Text style={styles.buttonText}>Close</Text> 
                        </TouchableHighlight>
                    </View>
                </View>
            </Modal>
        </View>
    );
  }
}

在以前的代码MyModal你这样做- > onPress={() => { this._setModalVisible(false) }}>这将隐藏在该模式MyModal类,但MyModal仍然在呈现MyList类。 因此,您可能无法再次单击FlatList项目。 我通过一个道具hideModal这将删除MyModal从组件MyList 在我的修订代码中,您也不需要通过modalVisible ,但是这取决于您。

item传递给模态

要将所选项目传递给模态,您需要将其作为prop添加到Modal组件上。

您可以记住处于MyList状态的所选项目:

_onPressItem = (item) => { 
    this._showModal(item);
};

_showModal = (selectedItem) => this.setState({ isModalVisible: true, selectedItem })

然后从MyList render它时, render其传递给模态:

// ...
      </ScrollView>
      <MyModal 
        modalVisible={this.state.isModalVisible} 
        selectedItem={this.state.selectedItem} />
    </KeyboardAvoidingView>
// ...

控制模式的可见性

目前,你有两种模态的知名度布尔MyList的状态( isModalVisible ,这是通过传递给MyModal作为modalVisible道具)以及在MyModal的状态( modalVisible )。 不需要最后一个-它只会让您头疼,无法保持同步。 只需使用道具“ 控制MyModal ,保持真相的单一来源,并通过回调允许MyModal告诉MyList该模式应予以驳回。

// ...
      </ScrollView>
      <MyModal 
        modalVisible={this.state.isModalVisible} 
        selectedItem={this.state.selectedItem}
        onDismiss={this._hideModal} />
    </KeyboardAvoidingView>
// ...

一个新的无状态MyModal

export default class MyModal extends Component {    
  render() {
    return (
        <View>
            <Modal
            animationType="slide"
            transparent={false}
            visible={this.props.modalVisible}
            onRequestClose={() => { this.props.onDismiss() }}
            >
                <View style={styles.container}>
                    <View style={styles.innerContainer}>
                        <Text>Item Detail</Text>
                        <TouchableHighlight
                            style={styles.buttonContainer}
                            onPress={() => { this.props.onDismiss() }}>
                            <Text style={styles.buttonText}>Close</Text> 
                        </TouchableHighlight>
                    </View>
                </View>
            </Modal>
        </View>
    );
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM