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

React Native Modal如何正确获取并显示滑块对应月份数据

问题根因

  • 你在map遍历月份数组时为每个月份都渲染了一个Modal组件,所有Modal共用同一个isModalVisible显隐状态,触发弹窗时所有Modal会同时显示,用户最终看到的是第一个渲染的Modal,所以永远只显示第一个月份
  • 没有单独存储当前滑块选中月份的状态,Modal无法匹配当前选中的月份
  • React Native的TextInput组件不支持web端的e.target.value取值方式,现有预算输入逻辑无法正常拿到输入值
  • 数据保存逻辑缺少对应月份字段,后续查询数据会无法对应到月份

修复后的完整代码

import React, { useContext, useState } from 'react';
import { AuthenticatedUserContext } from '../AuthenticatedUserProvider';
import { Swiper } from 'react-native-swiper';
import Modal from 'react-native-modal';
import { db } from '../firebase';
import FontAwesome from 'react-native-vector-icons/FontAwesome';
import { View, Text, TouchableHighlight, StyleSheet, Button, TextInput, TouchableOpacity } from 'react-native';

const data = [
    { id: 1, name: 'Month1' },
    { id: 2, name: 'Month2' },
    { id: 3, name: 'Month3' }
];

export default function HomeScreen() {

    const { user } = useContext(AuthenticatedUserContext);

    const [ isModalVisible, setModalVisible ] = useState(false);
    const [ months, setMonths ] = useState(data);
    // 新增选中月份状态
    const [ selectedMonth, setSelectedMonth ] = useState('');
    const [ values, setValues ] = useState({
        budget: '',
        month: '',
    });

    // 修改弹窗方法,接收选中的月份参数
    const toggleModal = (monthName = '') => {
        setSelectedMonth(monthName);
        setValues(prev => ({
            ...prev,
            month: monthName,
            budget: '' // 每次打开弹窗清空上次输入的预算
        }));
        setModalVisible(!isModalVisible);
    };

    const onSave = () => {
        setValues({ ...values, userId: user.uid });
        setModalVisible(!isModalVisible);
        db.collection('Budget').add({
            userId: user.uid,
            budget: values.budget,
            month: values.month // 补全存入的月份字段
        });
    };

    return (
        <View style={{flex: 1}}>
            <Swiper showsButtons={true} showsPagination={false} buttonWrapperStyle={{ alignItems: 'flex-start' }}>
                {months.map((monthItem, i) => (
                    <View key={i} style={styles.slider}>
                        <Text style={styles.text}> {monthItem.name}</Text>
                        <View>
                            <View style={styles.mainCardView}>
                                <TouchableOpacity
                                    // 触发弹窗时传入当前月份
                                    onPress={() => toggleModal(monthItem.name)}
                                    style={{ flex: 1, alignItems: 'flex-end', marginTop: 20 }}
                                >
                                    <FontAwesome name="pencil-square-o" color="black" size={30} />
                                </TouchableOpacity>
                            </View>
                        </View>
                    </View>
                ))}
            </Swiper>
            {/* Modal移出循环,全局复用一个 */}
            <Modal isVisible={isModalVisible} style={{ margin: 0 }}>
                <Text style= {{marginLeft: 50, color: '#fff'}}>Current month: {selectedMonth}</Text>
                <TextInput
                    style={{
                        height: 40,
                        borderColor: 'white',
                        borderWidth: 1,
                        color: 'white',
                        shadowColor: 'white',
                        margin: 50,
                        padding: 5,
                        marginVertical: 10,
                    }}
                    // 替换为React Native TextInput专属的输入监听方法
                    onChangeText={(text) => setValues({ ...values, budget: text })}
                    value={values.budget}
                    placeholder="Budget"
                    keyboardType="decimal-pad"
                    placeholderTextColor="#fff"
                />
                <TouchableHighlight
                    style={{
                        height: 40,
                        borderRadius: 10,
                        backgroundColor: 'gray',
                        marginLeft: 50,
                        marginRight: 50,
                        marginTop: 20,
                    }}
                >
                    <Button
                        onPress={onSave}
                        title="Confirm"
                    />
                </TouchableHighlight>
                <TouchableHighlight
                    style={{
                        height: 40,
                        borderRadius: 10,
                        backgroundColor: 'gray',
                        marginLeft: 50,
                        marginRight: 50,
                        marginTop: 20,
                    }}
                >
                    <Button
                        onPress={toggleModal}
                        title="Back"
                    />
                </TouchableHighlight>
            </Modal>
        </View>
    );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 18:06:05