使用react-native-netinfo检测连接变化时获取旧状态问题
问题原因
这是典型的闭包陷阱:你的useEffect依赖数组为空,组件仅在初始渲染时创建handleConnectionChange函数,该函数会捕获当时的tickets状态值。后续tickets更新时,这个旧的函数实例不会重新创建,所以始终访问的是初始的tickets值,直到APP重启重新初始化组件。
解决方案
以下是三种可行的解决方式,按推荐度排序:
方案一:直接从AsyncStorage读取最新数据
既然已经确认新增项已存入AsyncStorage,网络切换时无需依赖组件状态,直接读取存储中的最新数据:
const handleConnectionChange = async (state) => { // 读取并解析AsyncStorage中的最新数据 const storedTicketsStr = await AsyncStorage.getItem('tickets'); const latestTickets = storedTicketsStr ? JSON.parse(storedTicketsStr) : []; console.log("Array: ", latestTickets); if (state.isConnected && latestTickets.length > 0) { console.log("TRY TO SYNC"); callAPI(latestTickets); // 将最新数据传入API调用 } setConnectionStatus(state.isConnected); };
方案二:用useRef保存最新状态引用
通过useRef保存tickets的最新值,确保监听函数能访问到实时状态:
// 初始化ref,绑定当前tickets值 const ticketsRef = useRef(tickets); // 每次tickets更新时同步ref的当前值 useEffect(() => { ticketsRef.current = tickets; }, [tickets]); const handleConnectionChange = (state) => { // 从ref中获取最新的tickets值 const latestTickets = ticketsRef.current; console.log("Array: ", latestTickets); if (state.isConnected && latestTickets.length > 0) { console.log("TRY TO SYNC"); callAPI(latestTickets); } setConnectionStatus(state.isConnected); };
方案三:让监听函数随tickets更新重新创建
将handleConnectionChange移入useEffect内部,并把tickets加入依赖数组,这样每次tickets变化时都会重新创建监听函数并订阅NetInfo:
useEffect(() => { const handleConnectionChange = (state) => { console.log("Array: ", tickets); if (state.isConnected && tickets.length > 0) { console.log("TRY TO SYNC"); callAPI(); } setConnectionStatus(state.isConnected); }; const unsubscribe = NetInfo.addEventListener((state) => { handleConnectionChange(state); console.log("Connection type", state.type); console.log("Is connected?", state.isConnected); }); return () => { unsubscribe(); }; }, [tickets]); // 添加tickets作为依赖
注意:此方案会因
tickets频繁更新导致NetInfo重复订阅/取消订阅,可能存在性能损耗,仅在必要时使用。
内容的提问来源于stack exchange,提问作者Hernán Casillas
相关产品推荐
相关产品推荐

