如何用useSubscription替代useEffect监听Observable数据表更新?
现有Hook与组件代码
自定义Hook tableUpdated
import { useObservable, useObservableState } from 'observable-hooks' const tableUpdated = (table) => { const database = useDatabase(); const data = useObservableState( useObservable( () => database.get(table).query().observe(), [], ), ) return data; }; export default tableUpdated;
组件中使用该Hook
const Foo = () => { const posts = tableUpdated('posts') return <p>{posts.text}</p> }
待转换的useEffect逻辑
你原本想用useEffect监听posts更新来修改本地状态,现在需要换成useSubscription实现:
const Foo = () => { const [foo, setFoo] = useState(null) const posts = tableUpdated('posts') useEffect(() => { if(posts) { const result = ... // 执行自定义逻辑 setFoo(result) } }, [posts]) return <p>{foo}</p> }
修改方案
要用上useSubscription,核心是让tableUpdated返回Observable对象而非直接返回状态值,这样就能直接订阅数据流的变化:
第一步:调整tableUpdated Hook
import { useObservable } from 'observable-hooks' const tableUpdated$ = (table) => { const database = useDatabase(); // 直接返回Observable,不再用useObservableState转成状态 return useObservable( () => database.get(table).query().observe(), [], ); }; export default tableUpdated$;
第二步:在组件中用useSubscription处理数据流
import { useSubscription } from 'observable-hooks' import { useState } from 'react' import tableUpdated$ from './tableUpdated' const Foo = () => { const [foo, setFoo] = useState(null) // 获取数据表对应的Observable const posts$ = tableUpdated$('posts') // 订阅Observable的更新,每次数据流变化时执行逻辑 useSubscription(posts$, (posts) => { if(posts) { const result = ... // 执行你的自定义逻辑 setFoo(result) } }) return <p>{foo}</p> }
为什么这样改?
- 原来的
useObservableState会把Observable转成React状态,再用useEffect监听状态变化,多了一层中间状态的渲染开销 - 直接用
useSubscription订阅Observable,能在数据流更新时直接触发逻辑,更贴合observable-hooks的响应式设计,避免不必要的组件重渲染
内容的提问来源于stack exchange,提问作者four-eyes
相关产品推荐
相关产品推荐

