React Native:FlatList点击传参至Modal时ID报错求助
Let's walk through the key issues in your code and fix them step by step:
1. Immediate Problems Causing Errors
A. Incorrect onPress Handler in FlatList Item
You're calling _onPressItem immediately when rendering the item (instead of on tap). This leads to unexpected state updates and crashes.
Fix: Wrap the call in an arrow function to ensure it only runs when pressed.
B. State Variable Mismatch
Your Details component uses showModal in state but tries to update modalVisible—this creates a new state property instead of controlling the modal.
C. Missing setModalVisible Function
You pass setModalVisible to AddModal but never define it in Details.
D. Prop/State Sync Issues in AddModal
You copy props to state but use the wrong variable names, plus componentWillReceiveProps is deprecated. It's simpler to use props directly instead of syncing to state.
Corrected Code Snippets
Details.js
import React, { Component } from 'react'; import { Text, TouchableHighlight, View, StyleSheet, FlatList, Dimensions, Modal, TouchableWithoutFeedback, Keyboard } from 'react-native'; import AddModal from '../Modal/AddModal'; var screen = Dimensions.get('window'); const DismissKeyboard = ({ children }) => ( <TouchableWithoutFeedback onPress={() => Keyboard.dismiss()}> {children} </TouchableWithoutFeedback> ); export default class Details extends Component { static navigationOptions = { title: '' }; constructor() { super(); this.state = { data: [], modalVisible: false, // Fixed state variable name id: null, refreshing: false }; } fetchData = async () => { const { params } = this.props.navigation.state; const response_Cat = await fetch(`http://192.168.254.101:3307/categories/${params.id}`); const category_Cat = await response_Cat.json(); this.setState({ data: category_Cat }); }; componentDidMount() { this.fetchData(); }; _onRefresh = () => { this.setState({ refreshing: true }); this.fetchData().then(() => { this.setState({ refreshing: false }); }); }; // Arrow function to avoid binding issues _onPressItem = (id) => { this.setState({ modalVisible: true, id: id }); }; _renderItem = ({ item }) => { return ( <TouchableHighlight onPress={() => this._onPressItem(item.menu_desc)}> <View style={styles.listItem}> <Text>{item.menu_desc}</Text> {/* Show actual item text instead of state.id */} </View> </TouchableHighlight> ); }; // Define the missing setModalVisible function setModalVisible = (vis) => { this.setState({ modalVisible: vis }); }; render() { return ( <DismissKeyboard> <View style={styles.container}> <AddModal modalVisible={this.state.modalVisible} setModalVisible={this.setModalVisible} id={this.state.id} /> <FlatList data={this.state.data} renderItem={this._renderItem} keyExtractor={(item, index) => index.toString()} refreshControl={ <RefreshControl refreshing={this.state.refreshing} onRefresh={this._onRefresh} /> } /> </View> </DismissKeyboard> ); } } const styles = StyleSheet.create({ container: { flex: 1, paddingTop: 20 }, listItem: { padding: 15, borderBottomWidth: 1, borderBottomColor: '#eee' } });
AddModal.js
import React, { Component } from 'react'; import { Text, TouchableHighlight, View, StyleSheet, Modal } from 'react-native'; export default class AddModal extends Component { render() { return ( <Modal animationType="slide" transparent={true} visible={this.props.modalVisible} onRequestClose={() => this.props.setModalVisible(false)} > <View style={styles.modalOverlay}> <View style={styles.modalContent}> <Text style={styles.modalText}>Item ID: {this.props.id}</Text> <TouchableHighlight onPress={() => this.props.setModalVisible(false)} style={styles.closeButton} > <Text>Hide Modal</Text> </TouchableHighlight> </View> </View> </Modal> ); } } const styles = StyleSheet.create({ modalOverlay: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: 'rgba(0,0,0,0.5)' // Dark overlay for better visibility }, modalContent: { backgroundColor: 'white', padding: 25, borderRadius: 10, alignItems: 'center' }, modalText: { fontSize: 16, marginBottom: 20 }, closeButton: { padding: 10, backgroundColor: '#f0f0f0', borderRadius: 5 } });
Key Improvements Explained
- Arrow Functions: Used for
_onPressItemand_onRefreshto avoidthisbinding issues. - Direct Prop Usage:
AddModalnow uses props directly instead of syncing to state, eliminating lifecycle bugs. - Fixed State Variables: Ensured consistent use of
modalVisibleacross components. - Basic Styles: Added styles to make the modal visible and user-friendly.
- Cleaned Imports: Removed unused imports to reduce clutter.
内容的提问来源于stack exchange,提问作者Violet

