[英]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.