You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native:FlatList点击传参至Modal时ID报错求助

Fixing ID Passing & Modal Issues in Your React Native App

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 _onPressItem and _onRefresh to avoid this binding issues.
  • Direct Prop Usage: AddModal now uses props directly instead of syncing to state, eliminating lifecycle bugs.
  • Fixed State Variables: Ensured consistent use of modalVisible across components.
  • Basic Styles: Added styles to make the modal visible and user-friendly.
  • Cleaned Imports: Removed unused imports to reduce clutter.

内容的提问来源于stack exchange,提问作者Violet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:42:10