React Native中合并useState已有trips与新增行程的最简单方法
问题根因
你遇到的是React Hook的闭包陷阱问题:
- 现有代码直接引用当前作用域的
trips状态生成新数组,fetchCreatedTrips执行时会捕获当时的trips值(首次执行时trips为空数组),后续状态更新后闭包内的trips不会同步更新,导致每次添加新行程都是基于空数组拼接,自然只会保留最新一条。 - 没有做订阅清理逻辑,页面多次进出时会重复创建订阅,也会导致数据更新异常。
修复方案
修改setTrips为函数式更新形式,函数式更新可以直接拿到最新的状态值,不受闭包影响;同时补充订阅清理逻辑,避免内存泄漏和重复订阅,修改后参考代码如下:
const [trips, setTrips] = useState([]); useEffect(() => { // 存储订阅实例,用于后续清理 let tripSubscription = null; function fetchCreatedTrips() { try { tripSubscription = API.graphql(graphqlOperation(onCreateTrip)).subscribe({ next: (result) => { console.log(result); // 使用函数式更新,参数prevTrips为当前最新的trips状态 setTrips(prevTrips => [...prevTrips, result.value.data.onCreateTrip]) } }) } catch (err) { console.log(err) } } fetchCreatedTrips(); // 页面卸载/依赖更新时取消订阅,避免重复订阅和内存泄漏 return () => { if (tripSubscription) { tripSubscription.unsubscribe(); } } // 空依赖数组保证只在页面首次加载时执行一次订阅 }, [])
补充说明
- 如果你的页面需要每次进入都同步最新的历史行程列表,需要额外在useEffect中补充调用拉取全量行程列表的接口,和订阅新增的行程数据做拼接即可。
- 不要在组件顶层或者渲染逻辑中直接调用
fetchCreatedTrips,必须放到useEffect内执行。
内容的提问来源于stack exchange,提问作者Tony
相关产品推荐
相关产品推荐

