我有一个 MobX Store,其中包含用户角色信息和验证角色的方法:
class Store {
constructor() {
makeAutoObservable(this)
}
role: string = ""
setRole(name: string) {
this.role = name
}
checkRole(name: string) {
return this.role === name
}
}
我想在我的组件中使用 useMemo 内的 checkRole 方法,以便在角色没有以任何方式更改的情况下不重新计算该值。 (我意识到这个例子是一个简单的计算,不需要useMemo,但这只是一个例子)
我的组件如下所示:
const App = observer(() => {
const [, forceRender] = useReducer((prev) => prev + 1, 0)
const store = useContext(StoreContext)
const isHaveAccess = useMemo(() => {
return store.checkRole('ADMIN')
}, [store, store.role])
return (
<div>
{isHaveAccess ? 'Access allowed' : 'Access denied'}
<button
onClick={() => store.setRole('ADMIN')}
>Set Role</button>
<button onClick={forceRender}>Force Render</button>
</div>
);
})
它有效,但我收到 ESLint 的警告:
React Hook useMemo has an unnecessary dependency: 'store.role'
,它表示 useMemo 中未使用 store.role。
此外,如果我将逻辑从 checkRole 方法移至 useMemo,警告就会消失。
这是正常做法还是有更好的方法?
我尝试使用 使用参数计算,但这并没有解决问题,并且在每次渲染时都会调用 checkRole 方法。
在这种情况下,您可以抑制此 eslint 警告并保持代码不变。缺点是你的代码不是很透明,基本上
useMemo
以某种方式知道checkRole
的内部实现,它需要store.role
重新计算。它有点脏,但如果你不介意脏的话,这或多或少是正常的做法。
我建议你尝试mobx-utils
中的
compulatedFn,它基本上正是你所需要的。但要小心,它需要几乎是纯粹的,并且只依赖于可观察值和函数参数。
//...
checkRole = computedFn((name) => this.role === name)
// ...
另一种选择是使
checkRole
纯粹并始终传递当前角色和目标角色,但它有点冗长。 eslint
还是会很开心。