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

Expo React Native特定iOS设备TouchableOpacity无响应问题排查

问题描述

基于Expo React Native开发的订单处理应用出现异常:用户点击购买流程末尾的「ORDER NOW」按钮时,按钮正常高亮但无后续反馈,服务器无请求日志,仅按钮出现闪烁效果。

但当信息缺失(如未填地址、未选日期)时,能正常弹出提示框,说明onPress事件正常触发。

已尝试更新应用、重启设备、重装应用、登出登录、更换账号等操作,问题依旧。两台登录同一iCloud账号的iPhone(13和11)均出现该问题,怀疑是否与iCloud设置限制有关。

相关代码

「ORDER NOW」按钮代码

<TouchableOpacity onPress={formikprops.handleSubmit}
    style={[{ marginTop: 45 }, shadow.standard]}>
    <View style={{
        backgroundColor: foodhiRed,
        justifyContent: "center",
        height: 50,
        alignSelf: "center",
        alignItems: "center",
        width: Dimensions.get('window').width * 0.8,
        borderRadius: 6,
    }}>
        <Text style={[cartStyle.cartFloatingBarText, { fontSize: 16 }]}>
            {loading ? <Loading /> : "Jetzt bestellen"}
        </Text>
    </View>
</TouchableOpacity>

Formik的handleSubmit代码

<Formik
    initialValues={{
        address: shipping_address && `${shipping_address.street_1}, ${shipping_address.city}, ${shipping_address.postcode}`,
        deliveryDate: selectedDate,
        deliveryTime: selectedTime,
        immediateDelivery,
        moreDetails: deliveryMessage
    }}
    onSubmit={(values) => {
        if (selectedDate) {
            if (shipping_address) {
                handleCallback(values)
            } else Alert.alert("Alert", "Please provide an address")
        } else Alert.alert("Alert", "Please specify a date")
    }}

handleCallback及后续提交逻辑代码

const confirmSubmit = (values) => {
    // IF CONDITION IS MET, AND ORDER IS WITHIN TIME CUTOFF
    dispatch(loadingStart());
    // CHECK IF THERE'S AN ADDRESS REGISTERED
    if (!userProfile.fk_shipping_address) {
        Alert.alert("Addresse", "You must specify an address");
        dispatch(loadingStop());
    } else {
        const orderData = {
            delivery_date: values.deliveryDate,
            total: (values.immediateDelivery ? subTotal : subTotal + farmer.delivery_fee).toFixed(3),
            delivery_fee: values.immediateDelivery ? 0 : farmer.delivery_fee,
            delivery_note: values.moreDetails,
            immediate_order: values.immediateDelivery,
            restaurant: {
                id: userProfile.id,
            },
            farmer: {
                id: route.params.farmer.id,
            },
            fk_order_items: cartProducts.map((product) => {
                const subtotal = (product.item.price - (product.item.price * (product.discount / 100)));
                const item_total = (product.item.price - (product.item.price * (product.discount / 100))) * product.quantity;

                return (
                    {
                        product_id: product.item.id,
                        stock_quantity: product.item.stock_quantity,
                        name: product.item.name,
                        unit_amount: product.item.amount,
                        measurement: product.item.fk_unit_measurement?.name,
                        images: product.item.images,
                        quantity: product.quantity,
                        price: product.item.price,
                        discount: (product.item.price * (product.discount / 100)),
                        subtotal,
                        item_total,
                        product_amount: product.item.amount * product.quantity,
                        updated_product_amount: product.item.amount * product.quantity,
                        updated_subtotal: subtotal,
                        tax_rate: product.item.tax
                            ? product.item.tax.tax_rate
                            : farmer.fk_global_tax
                                ? farmer.fk_global_tax.tax_rate
                                : 0,
                        is_refunded: false
                    }
                )
            }),
            fk_order_status: {
                id: 1
            },
            fk_shipping_address: {
                id: userProfile.fk_shipping_address.id
            },
            fk_billing_address: {
                id: userProfile.fk_shipping_address.id
            }
        }

        getAxiosInstance(store).post(`/items/orders?fields=*.*.*`, orderData)
            .then((response) => {
                const orderDataResponse = response.data.data;
                const {
                    fk_order_items,
                    farmer,
                    restaurant,
                    id,
                    delivery_date
                } = orderDataResponse;

                sendPushNotification( {
                    to: userProfile.push_notification_key,
                    title: `Bestellung #${id} wurde erstellt`,
                    body: `Der Liefertermin ist: ${dayjs(delivery_date).format("DD.MM.YYYY")}`,
                    data: null,
                })

                // SEND TRANSACTIONAL EMAIL TO RESTAURANT
                sendEmail({
                    templateId: "DIRECTUS_RESTAURANT_Order_Confirmation",
                    data: {
                        total: values.immediateDelivery ? subTotal : (subTotal + farmer.delivery_fee),
                        farmerFirstName: farmer.contact_first_name,
                        restaurantFirstName: restaurant.contact_first_name,
                        items: fk_order_items,
                        vendor: farmer.store_name,
                        orderNum: id,
                        delivery_fee: farmer.delivery_fee,
                        deliveryDate: dayjs(delivery_date).format("DD.MM.YYYY"),
                    },
                    recipient: restaurant.contact_email,
                });

                // SEND TRANSACTIONAL EMAIL TO FARMER
                sendEmail({
                    templateId: "DIRECTUS_FARMER_New_Order_Received",
                    data: {
                        total: values.immediateDelivery ? subTotal : (subTotal + farmer.delivery_fee),
                        restaurant,
                        items: fk_order_items,
                        farmer,
                        orderNum: id,
                        delivery_fee: farmer.delivery_fee,
                        deliveryDate: dayjs(delivery_date).format("DD.MM.YYYY"),
                    },
                    recipient: farmer.contact_email,
                });

                // LOWER STOCK AND EMPTY CART
                dispatch(createOrder(orderDataResponse, navigation))

                trackAmplitudeEvent("Purchase", {
                    total: values.immediateDelivery ? subTotal : (subTotal + farmer.delivery_fee),
                    immediateDelivery: values.immediateDelivery
                })

                dispatch(loadingStop())
            })
            .catch(error => {
                console.log(error, "ERROR CREATING ORDER");
                dispatch(loadingStop())
            })
    }
}

const handleCallback = (values) => {
    const formattedDeliveryDate = values.deliveryDate;
    formattedDeliveryDate.setHours(0, 0, 0, 0)

    const today = new Date()
    const daysBefore = new Date(today)
    daysBefore.setDate(daysBefore.getDate() + cutoffOrderingDay)
    daysBefore.setHours(0, 0, 0, 0)
    //CHECK IF DELIVERY IS BEFORE CUTOFF TIME SPECIFIED BY VENDOR


    if (values.immediateDelivery) {
        Alert.alert(
            "Bist du sicher?",
            "Möchtest du direkt vor Ort (in deinem Restaurant oder auf dem Hof) bestellen?",
            [
                {
                    text: "Ja", onPress: () => {
                        confirmSubmit(values)
                    },
                    style: "default"
                },
                {
                    text: "Abbrechen",
                    style: "cancel"
                }
            ]
        )
    } else {
        confirmSubmit(values)
    }

};

排查方向及可能原因

  • 日期对象引用修改导致状态异常:handleCallback中直接修改values.deliveryDate(formattedDeliveryDate = values.deliveryDate是引用赋值),会直接篡改Formik的表单状态,引发重渲染或流程阻塞。应改为创建新日期对象:const formattedDeliveryDate = new Date(values.deliveryDate);

  • 未捕获的静默异常:构建orderData时可能存在属性未定义的情况(如farmer.delivery_fee、userProfile.fk_shipping_address.id),导致代码卡在数据构建阶段,未走到axios请求。建议给confirmSubmit添加全局try-catch,并在关键步骤打印日志,排查具体异常点。

  • iCloud相关限制或冲突:同一iCloud账号设备出现相同问题,可能是iCloud隐私设置(如限制应用网络、跨设备跟踪)或iCloud Drive同步干扰了应用状态。可尝试让用户关闭该应用的iCloud Drive同步权限,或关闭设备的「跨设备跟踪」功能测试。

  • Loading状态逻辑异常:若loading状态的redux处理存在问题,可能导致按钮闪烁。检查loadingStart和loadingStop的dispatch逻辑,确保所有分支都能正确停止loading。

  • 表单状态判断的隐性矛盾:onSubmit仅判断shipping_address存在,但confirmSubmit额外判断userProfile.fk_shipping_address,若前者存在后者不存在,会弹出提示,但用户无反馈说明该情况未触发,需确认这两个值的一致性,或在onSubmit中提前做完整校验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 19:40:54