React Native中修改状态触发mobx-state-tree异常问题求助
问题分析与解决方案
你遇到的这个错误是**mobx-state-tree(MST)**的核心规则导致的:MST会保护它管理的对象,不允许直接修改属性,所有状态变更必须通过MST定义的action来完成。
为什么你的代码会出错?
你的tags是从this.props.userStore.details.tags获取的,这个对象属于MST的状态树节点,是受保护的。你在changeCheckboxValue里直接修改tag.userSelect,绕过了MST的action机制,所以触发了保护错误。另外,就算没有MST的限制,你的代码也不会触发React组件更新——因为你只是修改了数组内对象的属性,没有改变this.state.tags的引用,React无法检测到状态变化。
正确的解决步骤
1. 在MST模型中定义修改标签状态的Action
首先,你需要在管理tags的MST模型里,给单个标签对象定义一个切换选中状态的action。假设你的模型结构是这样的:
import { types } from 'mobx-state-tree'; // 定义单个标签的模型 const TagModel = types.model('Tag', { name: types.string, userSelect: types.boolean }).actions(self => ({ // 定义action来切换选中状态 toggleUserSelect() { self.userSelect = !self.userSelect; } })); // 定义包含tags的details模型 const DetailsModel = types.model('Details', { tags: types.array(TagModel), // 其他属性... }); // 最终的userStore模型 const UserStoreModel = types.model('UserStore', { details: DetailsModel, // 其他属性... });
2. 修改组件中的触发逻辑
不需要再把tags存在组件自己的state里(MST的状态是响应式的,直接用props里的即可),直接调用MST对象的action来修改状态:
// 渲染方法直接使用props中的tags renderTagCheckbox() { return this.props.userStore.details.tags.map((item, key) => { return( <TouchableOpacity key={key} style={{flexDirection: "row", marginTop: 5, justifyContent: "center"}}> <CheckBox isChecked={item.userSelect} onClick={() => item.toggleUserSelect()} /> <Text>{item.name}</Text> </TouchableOpacity> ) }) }
如果一定要保留changeCheckboxValue方法,也可以改成这样:
changeCheckboxValue(item) { item.toggleUserSelect(); }
3. 为什么这样可行?
- MST的action会确保状态变更被追踪,同时遵循MST的保护机制,不会触发错误。
- MST是响应式的,当action修改了状态后,依赖这个状态的组件会自动重新渲染,不需要手动调用
setState。
内容的提问来源于stack exchange,提问作者Frendom
相关产品推荐
相关产品推荐

