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

监听BLE特征时丢失Context最新状态的问题求助

解决BLE监听回调无法获取Context最新状态的问题

问题根源

你的问题本质是闭包陷阱:onUpdate回调在组件初始渲染时被创建,捕获了当时的currentMatch和currentPerson值。后续MatchProvider中的状态更新时,这个回调并没有重新生成,仍然使用旧闭包中的状态值,导致无法获取最新状态。

解决方案

方案1:用useRef保存状态的最新引用

通过useRef维护状态的实时引用,让回调总能拿到最新值:

import { useContext, useRef, useEffect } from 'react';

// BluetoothProvider组件内部逻辑
const { currentMatch, currentPerson } = useContext(MatchDataContext);
const matchRef = useRef(currentMatch);
const personRef = useRef(currentPerson);

// 监听状态变化,实时更新ref的引用
useEffect(() => {
  matchRef.current = currentMatch;
  personRef.current = currentPerson;
}, [currentMatch, currentPerson]);

// 检查状态的函数,改用ref.current获取最新值
const updating = () => {
  if (matchRef.current != null && personRef.current != null) {
      console.log('found person')
  } else {
      console.log('no person')
  }
}

const onUpdate = (error: BleError | null, characteristic: Characteristic | null) => {
  updating();
}

// 用useEffect管理BLE监听的生命周期,避免内存泄漏
useEffect(() => {
  const subscription = device.monitorCharacteristicForService(
    service.uuid,
    characteristic.uuid,
    onUpdate
  );

  // 组件卸载或依赖变化时取消监听
  return () => {
    subscription.remove();
  };
}, [device, service.uuid, characteristic.uuid]);

方案2:用useCallback和useEffect重新注册回调

让onUpdate回调在状态变化时重新生成,并同步更新BLE监听的注册:

import { useContext, useCallback, useEffect } from 'react';

// BluetoothProvider组件内部逻辑
const { currentMatch, currentPerson } = useContext(MatchDataContext);

// 用useCallback包裹回调,依赖包含状态值,状态变化时重新生成回调
const onUpdate = useCallback((error: BleError | null, characteristic: Characteristic | null) => {
  if (currentMatch != null && currentPerson != null) {
      console.log('found person')
  } else {
      console.log('no person')
  }
}, [currentMatch, currentPerson]);

// 用useEffect管理监听,依赖包含onUpdate,回调变化时重新注册
useEffect(() => {
  const subscription = device.monitorCharacteristicForService(
    service.uuid,
    characteristic.uuid,
    onUpdate
  );

  return () => {
    subscription.remove();
  };
}, [device, service.uuid, characteristic.uuid, onUpdate]);

关键注意事项

  • 必须通过useEffect管理BLE监听的生命周期,确保组件卸载或依赖变化时取消旧监听,避免内存泄漏和无效回调残留。
  • 方案1适合状态频繁变化的场景,无需频繁重新注册监听;方案2通过重新注册回调保证上下文同步,逻辑更直接。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 21:15:12