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
相关产品推荐
相关产品推荐

