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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 14:36:26