如何处理 class 构造函数中定义的反应?
How do you dispose a reaction defined in a class constructor?
在我的一些模型中,我需要像这样在构造函数中定义一个反应:
constructor() {
//...some code
const dispose = reaction(
() => this.items.length,
count => {
this.setItemCount(count);
}
);
}
我使用的是反应而不是计算 (@computed get itemCount()
),因为将 items
加载到状态是一项昂贵的操作(通过网络传输大量数据),因此我需要保留最近的值,以便它可以在整个应用程序中使用。如果在项目加载到状态时计数发生变化,则反应是更新值。
所以,考虑到上述情况,我想知道 when/how 我会处理反应吗?我想避免内存泄漏。尽管我更喜欢反应式方法而不是命令式方法,但我愿意接受其他方法来完成我需要的事情。
我正在使用一系列一次性物品 + 特定方法来处理它们。
它看起来像:
class MyClass {
...
disposables = [];
...
constructor () {
// constructor stuff
this.disposables.push(reaction(
() => this.items.length,
count => {
this.setItemCount(count);
}
))
}
...
disposeAll = () => {
this.disposables.forEach(dispose => dispose());
}
}
如果你想处理特定的反应,这种方法是没有用的。但在这种情况下,您可以映射而不是数组。
三种方法。
- 反应完成后处理它。
constructor() {
const dispose = reaction(
() => this.items.length,
(count, reaction) => {
this.setItemCount(count);
if(count === 100) reaction.dispose()
}
);
}
- 其他一些操作会为您处理它。就像一个按钮点击。或者另一种反应。实际上,无论您需要什么。
class myStore {
disposer
constructor() {
this.disposer = reaction(
() => this.items.length,
(count) => this.setItemCount(count)
);
}
myButtonClick = () => {
this.disposer()
}
}
- 在您的 class 中创建一个 "deconstructor" 方法,当您不再 "need" 此 class/store 时将调用该方法。在安全地将东西传递给垃圾收集器之前,您可以使用此方法倾倒任何需要清理的东西。
class myStore {
disposers = []
constructor () {
this.disposers.push(reaction(
() => this.items.length,
(count, reaction) => {
this.setItemCount(count);
if(count === 100) reaction.dispose()
}
))
}
deconstructor() {
this.disposers.forEach((disposer) => disposer())
}
}
你也有责任调用这个解构函数。通常您会在组件卸载时调用它。下面的挂钩示例:
function Example() {
const [store] = useState(() => new myStore())
useEffect(() => {
return () => store.deconstructor()
}, [])
return <App/>
}
如果store是global/context,你可以在frame组件(应用程序生命周期中一直挂载的组件)中调用析构函数,所以当用户退出应用程序时它是运行。然而,我不太确定,这个步骤对于 Mobx 一次性用品的需求有多大,也许有人可以对此发表评论。不过这样做并没有什么坏处。
注意。实际上,无论如何您都应该始终执行第 3 项,因为可能由于某些原因,条件 1.(或 2.)可能无法触发并且您在后台留下不必要的反应滴答作响。
在我的一些模型中,我需要像这样在构造函数中定义一个反应:
constructor() {
//...some code
const dispose = reaction(
() => this.items.length,
count => {
this.setItemCount(count);
}
);
}
我使用的是反应而不是计算 (@computed get itemCount()
),因为将 items
加载到状态是一项昂贵的操作(通过网络传输大量数据),因此我需要保留最近的值,以便它可以在整个应用程序中使用。如果在项目加载到状态时计数发生变化,则反应是更新值。
所以,考虑到上述情况,我想知道 when/how 我会处理反应吗?我想避免内存泄漏。尽管我更喜欢反应式方法而不是命令式方法,但我愿意接受其他方法来完成我需要的事情。
我正在使用一系列一次性物品 + 特定方法来处理它们。 它看起来像:
class MyClass {
...
disposables = [];
...
constructor () {
// constructor stuff
this.disposables.push(reaction(
() => this.items.length,
count => {
this.setItemCount(count);
}
))
}
...
disposeAll = () => {
this.disposables.forEach(dispose => dispose());
}
}
如果你想处理特定的反应,这种方法是没有用的。但在这种情况下,您可以映射而不是数组。
三种方法。
- 反应完成后处理它。
constructor() {
const dispose = reaction(
() => this.items.length,
(count, reaction) => {
this.setItemCount(count);
if(count === 100) reaction.dispose()
}
);
}
- 其他一些操作会为您处理它。就像一个按钮点击。或者另一种反应。实际上,无论您需要什么。
class myStore {
disposer
constructor() {
this.disposer = reaction(
() => this.items.length,
(count) => this.setItemCount(count)
);
}
myButtonClick = () => {
this.disposer()
}
}
- 在您的 class 中创建一个 "deconstructor" 方法,当您不再 "need" 此 class/store 时将调用该方法。在安全地将东西传递给垃圾收集器之前,您可以使用此方法倾倒任何需要清理的东西。
class myStore {
disposers = []
constructor () {
this.disposers.push(reaction(
() => this.items.length,
(count, reaction) => {
this.setItemCount(count);
if(count === 100) reaction.dispose()
}
))
}
deconstructor() {
this.disposers.forEach((disposer) => disposer())
}
}
你也有责任调用这个解构函数。通常您会在组件卸载时调用它。下面的挂钩示例:
function Example() {
const [store] = useState(() => new myStore())
useEffect(() => {
return () => store.deconstructor()
}, [])
return <App/>
}
如果store是global/context,你可以在frame组件(应用程序生命周期中一直挂载的组件)中调用析构函数,所以当用户退出应用程序时它是运行。然而,我不太确定,这个步骤对于 Mobx 一次性用品的需求有多大,也许有人可以对此发表评论。不过这样做并没有什么坏处。
注意。实际上,无论如何您都应该始终执行第 3 项,因为可能由于某些原因,条件 1.(或 2.)可能无法触发并且您在后台留下不必要的反应滴答作响。