React Native Android端用expo-checkbox触发「文本需在<Text>组件渲染」报错
React Native待办App Android端CheckBox崩溃问题排查与修复
问题详情
开发的简易待办列表App在Web端运行正常,但Android端使用expo-checkbox组件时,只要保留value和onValueChange属性就会触发崩溃,注释这两个属性后恢复正常。已排查空格、条件渲染等常见问题,均未解决。
data属性日志输出:1690929274428 0 'f' false
相关代码
Task组件
import { StyleSheet, View, TextInput } from 'react-native'; import { useState } from 'react'; import CheckBox from 'expo-checkbox'; const Task = props => { let data = props.data; const [valueDisplayed, onChangeText] = useState(data.text); return ( <View style={styles.task}> <CheckBox value={data.done} onValueChange={(value)=>{props.finish(data.created)}} /> <TextInput value={valueDisplayed} onChangeText={input => { onChangeText(input); props.update(data.created, input); }} style={styles.textBox} onKeyPress={keyPress => { console.log(keyPress.nativeEvent.key); if (keyPress.nativeEvent.key == "Enter") { props.add(data.created); } else if (data.text.length == 0 && keyPress.nativeEvent.key == "Backspace") { props.delete(data.created); } }} onSubmitEditing={() => { props.add(data.created); }} autoFocus={data.focus} /> </View> ); } const styles = StyleSheet.create({ task: { flexDirection: "row", }, textBox: { flex: 1, fontSize: 32, } }); export default Task;
父组件代码片段
const finishItem = async (list, created, setTasks) => { let array = await loadList(list); for (let i = 0; i < array.length; i++) if (array[i].created == created) if (array[i].done == 0) array[i].done = Date.now(); else array[i].done = 0; sortTasks(array); setTasks(array); await saveList(list, array); } const TaskList = (props) => { const [tasks, setTasks] = useState([]); useEffect(()=>{ getInitialList(props.list, setTasks); }, []); return ( <FlatList data={tasks} extraData={tasks} renderItem={({item}) => ( <Task data={item} add={(createdFrom) => { addItem(props.list, createdFrom, setTasks); }} update={(created, text) => { updateItem(props.list, created, text, setTasks); }} delete={(created) => { deleteItem(props.list, created, setTasks); }} finish={(created) => { finishItem(props.list, created, setTasks); }} /> )} keyExtractor={(item) => { return item.created }} showsHorizontalScrollIndicator={false} /> ); }
问题根源
expo-checkbox的value属性要求传入布尔类型值,但当前代码中data.done是数字类型(0或时间戳)。Web端会自动进行类型转换,而Android端对类型校验更严格,导致组件渲染时崩溃。
修复方案
方案1:临时类型转换
修改CheckBox的value属性,将数字类型的data.done转换为布尔值:
<CheckBox value={!!data.done} // 双感叹号将0转为false,非0数字转为true onValueChange={(value)=>{props.finish(data.created)}} />
方案2:统一数据类型(推荐)
修改finishItem函数,将done字段改为布尔值存储,从根源避免类型不匹配问题:
const finishItem = async (list, created, setTasks) => { let array = await loadList(list); for (let i = 0; i < array.length; i++) if (array[i].created == created) array[i].done = !array[i].done; // 直接取反布尔值 sortTasks(array); setTasks(array); await saveList(list, array); }
同时需要同步修改初始化和其他涉及done字段的逻辑,确保数据一致性。
内容的提问来源于stack exchange,提问作者Multiple Sources
相关产品推荐
相关产品推荐

