React Native FlatList点击按钮仅显示对应答案问题排查
问题原因
你当前的核心问题是全局状态showValue被所有列表项共用——点击任意一个"Show Answer"按钮都会切换这个全局状态,导致所有问答项的答案同时显示或隐藏。
解决方案
方案一:记录当前显示答案的Item ID(单开模式)
适合需要"同时仅显示一个答案"的场景,点击新问题的按钮时自动隐藏之前的答案。
修改后的完整代码:
import React, { useState, useEffect } from 'react'; import { FlatList, View, Text, Pressable, Button } from 'react-native'; import {firebase} from '../config'; const Testing = ({ navigation }) =>{ const [users, setUsers] = useState([]); const todoRef = firebase.firestore().collection('dd11'); // 改为存储当前要显示答案的item ID,初始为null const [showAnswerId, setShowAnswerId] = useState(null); useEffect(() => { todoRef.onSnapshot(querySnapshot => { const users = [] querySnapshot.forEach((doc) => { const { QuestionOne, ans, optionOne, optionTwo, optionThree, optionFour } = doc.data() users.push({ id: doc.id, QuestionOne, ans, optionOne, optionTwo, optionThree, optionFour }) }) setUsers(users) }) }, []) return ( <View style={{ flex:1,}}> <FlatList data={users} numColumns={1} renderItem={({item}) => ( <Pressable> <View style={{paddingLeft: 10, paddingRight: 10, marginVertical: 10}}> {item.QuestionOne && <Text style={{fontSize: 16, fontWeight: '500'}}>{item.QuestionOne}</Text>} {item.optionOne && <Text style={{marginTop: 8}}>{item.optionOne}</Text>} {item.optionTwo && <Text style={{marginTop: 4}}>{item.optionTwo}</Text>} {item.optionThree && <Text style={{marginTop: 4}}>{item.optionThree}</Text>} {item.optionFour && <Text style={{marginTop: 4}}>{item.optionFour}</Text>} {/* 仅当当前item的ID匹配状态值时显示答案 */} {showAnswerId === item.id && item.ans && <Text style={{color: 'green', marginTop: 8, fontSize: 16}}>{item.ans}</Text>} <Button title={showAnswerId === item.id ? "Hide Answer" : "Show Answer"} onPress={() => { // 切换状态:已显示则隐藏,未显示则记录当前item ID setShowAnswerId(prev => prev === item.id ? null : item.id) }} style={{marginTop: 12}} /> </View> </Pressable> )} /> </View> ); } export default Testing;
方案二:拆分独立组件(多开模式)
适合允许同时显示多个答案的场景,每个问答项维护自己的独立状态。
修改后的完整代码:
import React, { useState, useEffect } from 'react'; import { FlatList, View, Text, Pressable, Button } from 'react-native'; import {firebase} from '../config'; // 独立的问答项组件,内部维护自己的显示状态 const QuestionItem = ({ item }) => { const [showAnswer, setShowAnswer] = useState(false); return ( <Pressable> <View style={{paddingLeft: 10, paddingRight: 10, marginVertical: 10}}> {item.QuestionOne && <Text style={{fontSize: 16, fontWeight: '500'}}>{item.QuestionOne}</Text>} {item.optionOne && <Text style={{marginTop: 8}}>{item.optionOne}</Text>} {item.optionTwo && <Text style={{marginTop: 4}}>{item.optionTwo}</Text>} {item.optionThree && <Text style={{marginTop: 4}}>{item.optionThree}</Text>} {item.optionFour && <Text style={{marginTop: 4}}>{item.optionFour}</Text>} {showAnswer && item.ans && <Text style={{color: 'green', marginTop: 8, fontSize: 16}}>{item.ans}</Text>} <Button title={showAnswer ? "Hide Answer" : "Show Answer"} onPress={() => setShowAnswer(!showAnswer)} style={{marginTop: 12}} /> </View> </Pressable> ) } const Testing = ({ navigation }) =>{ const [users, setUsers] = useState([]); const todoRef = firebase.firestore().collection('dd11'); useEffect(() => { todoRef.onSnapshot(querySnapshot => { const users = [] querySnapshot.forEach((doc) => { const { QuestionOne, ans, optionOne, optionTwo, optionThree, optionFour } = doc.data() users.push({ id: doc.id, QuestionOne, ans, optionOne, optionTwo, optionThree, optionFour }) }) setUsers(users) }) }, []) return ( <View style={{ flex:1,}}> <FlatList data={users} numColumns={1} renderItem={({item}) => <QuestionItem item={item} />} /> </View> ); } export default Testing;
内容的提问来源于stack exchange,提问作者Rahul Aadam
相关产品推荐
相关产品推荐

