如何修改/替换mobx-state-tree中的store节点并触发组件正常重渲染
问题根源
你遇到的崩溃核心原因是applySnapshot作用于self.user子节点时,若新快照与现有节点结构存在差异,MST会直接销毁旧user节点生成全新节点,组件之前持有的旧user节点引用已完全脱离状态树,对其进行读写操作就会触发「内容不属于当前状态树」的报错。
正确更新方案
方案1:全量替换user属性(适合SDK返回完整User结构的场景)
直接对根store的user属性赋值即可,MST会自动完成类型校验和新节点创建:
const store = types.model({ user: types.maybe(User), settings: types.maybe(Settings) }).actions((self) => ({ updateUsername(username: string) { // 调用原生SDK更新用户 const userUpdated = SDK.updateUsername(username); // 直接替换根store的user属性 self.user = userUpdated }, })).create();
方案2:增量更新user节点(适合仅修改部分属性、不想销毁旧节点的场景)
调用MST内置的assign方法,仅更新传入的属性,不会销毁原有user节点,原有引用可以正常使用:
const store = types.model({ user: types.maybe(User), settings: types.maybe(Settings) }).actions((self) => ({ updateUsername(username: string) { const userUpdated = SDK.updateUsername(username); // 仅当user存在时增量更新属性 if (self.user) { self.user.assign(userUpdated) } }, })).create();
组件渲染注意事项
要保证store变化时自动触发组件重渲染,同时避免持有旧节点引用:
- 所有消费store的组件必须用
observer包裹 - 不要在组件state、闭包中长期缓存store子节点的引用,每次渲染直接从根store读取最新值即可
import { observer } from 'mobx-react-lite' // 正确写法 const UserProfile = observer(() => { return <Text>{store.user?.username}</Text> }) // 错误写法,会缓存旧节点引用 // const BadUserProfile = () => { // const user = store.user // return <Text>{user?.username}</Text> // }
内容的提问来源于stack exchange,提问作者age
相关产品推荐
相关产品推荐

