Closed FlyingLxy closed 1 year ago
我看看
effect中fromQuery返回的subject.isStopped 是 true。不知道是我写的哪儿有问题导致的还是什么其他原因
我构造了一个测试用例,试图复现,但没有遇到你提的这个问题。
可以再排查一下,是不是意料之外地卸载了组件导致取消 effect 订阅了。
或者构造一个最小可复现 demo.
找到原因了,第一张图,我做了一个用户信息加载状态的判断,这个注释掉就没问题。 但是我在最外侧使用了RemeshScope,domain在组件销毁时不应该被销毁吧?
是的,RemeshScope 可以保活 domain 实例,理论上不会因为组件销毁所致的引用归零而自动回收掉。
不过,尽管 domain 不会被回收,但 domain-query
等领域资源还是会回收的。因此不再有引用的 domain-query
会被回收,因而 fromQuery(..)
的 observable
会 completed
掉。
对于 domain-query
层面的保活,目前可以通过下面的步骤来完成,后续可能考虑新增相关 API。
const HolderQuery = domain.query({
name: 'HolderQuery',
impl: ({ get }) => {
get(AQuery())
get(BQuery())
// 其他需要保活的 query
if (get(CQuery())) {
// 还可以根据动态条件选择保活
get(DQuery())
}
}
})
这个特殊的 Query,返回 undefined,这样它不会引起组件的更新(每次都一样的值),但会记住它依赖的其它 domain-query
const HolderComponent = ({ children }: { children: ReactNode }) => {
const domain = useRemeshDomain(MyDomain())
useRemeshQuery(domain.query.HolderQuery())
// 手动保活 domain
useRemeshDomain(ChatDomain())
useRemeshDomain(UserDomain())
return <>{children}</>
}
// 这样用
<HolderComponent>
<XXRouterProvider />
</HolderComponent>
通过上述方式,我们同时按需保活的 domain 和 domain-query,实现了 RemeshScope 的功能并做得更多。
对于
domain-query
层面的保活,目前可以通过下面的步骤来完成,后续可能考虑新增相关 API。第一步,创建一个特殊的 domain-query
const HolderQuery = domain.query({ name: 'HolderQuery', impl: ({ get }) => { get(AQuery()) get(BQuery()) // 其他需要保活的 query if (get(CQuery())) { // 还可以根据动态条件选择保活 get(DQuery()) } } })
这个特殊的 Query,返回 undefined,这样它不会引起组件的更新(每次都一样的值),但会记住它依赖的其它 domain-query
第二步,在合适的组件层级里,订阅 HolderQuery
const HolderComponent = ({ children }: { children: ReactNode }) => { const domain = useRemeshDomain(MyDomain()) useRemeshQuery(domain.query.HolderQuery()) // 手动保活 domain useRemeshDomain(ChatDomain()) useRemeshDomain(UserDomain()) return <>{children}</> } // 这样用 <HolderComponent> <XXRouterProvider /> </HolderComponent>
通过上述方式,我们同时按需保活的 domain 和 domain-query,实现了 RemeshScope 的功能并做得更多。
好的,谢谢。建议在文档里提示一下这个问题,ScopeDomain介绍有些模糊了,会让人误解。
好的,这块确实得好好处理一下。
如果我把组件内的useRemeshQuery注释掉,effect的observable会执行。否则只会执行组件内的变更渲染。
急。。。