子类化
子类化受 限制 的支持。最值得注意的是,你只能在 **原型上重写操作/流程/计算值** - 你不能重写 字段声明。对于在子类中重写的方法/getter,使用 override
注解 - 请参见下面的示例。尽量保持简单,并优先使用组合而不是继承。
import { makeObservable, observable, computed, action, override } from "mobx"
class Parent {
// Annotated instance fields are NOT overridable
observable = 0
arrowAction = () => {}
// Non-annotated instance fields are overridable
overridableArrowAction = action(() => {})
// Annotated prototype methods/getters are overridable
action() {}
actionBound() {}
get computed() {}
constructor(value) {
makeObservable(this, {
observable: observable,
arrowAction: action
action: action,
actionBound: action.bound,
computed: computed,
})
}
}
class Child extends Parent {
/* --- INHERITED --- */
// THROWS - TypeError: Cannot redefine property
// observable = 5
// arrowAction = () = {}
// OK - not annotated
overridableArrowAction = action(() => {})
// OK - prototype
action() {}
actionBound() {}
get computed() {}
/* --- NEW --- */
childObservable = 0;
childArrowAction = () => {}
childAction() {}
childActionBound() {}
get childComputed() {}
constructor(value) {
super()
makeObservable(this, {
// inherited
action: override,
actionBound: override,
computed: override,
// new
childObservable: observable,
childArrowAction: action
childAction: action,
childActionBound: action.bound,
childComputed: computed,
})
}
}
限制
- 只有在 **原型上** 定义的
action
、computed
、flow
、action.bound
可以被子类 **重写**。 - 除了使用
override
,字段不能在子类中重新注解。 makeAutoObservable
不支持子类化。- 不支持扩展内置类型 (
ObservableMap
、ObservableArray
等)。 - 你不能在子类中为
makeObservable
提供不同的选项。 - 你不能在一个单一的继承链中混合注解/装饰器。
- 所有其他限制也适用。
TypeError: Cannot redefine property
如果你看到这个错误,你可能正在尝试在子类 x = () => {}
中 **重写箭头函数**。这是不可能的,因为类的 **所有注解** 字段都是 **不可配置的** (参见限制)。你有两个选择
1. 将函数移到原型上,并使用 action.bound
注解代替
class Parent {
// action = () => {};
// =>
action() {}
constructor() {
makeObservable(this, {
action: action.bound
})
}
}
class Child {
action() {}
constructor() {
super()
makeObservable(this, {
action: override
})
}
}
2. 删除 action
注解,并在操作中手动包装函数:x = action(() => {})
class Parent {
// action = () => {};
// =>
action = action(() => {})
constructor() {
makeObservable(this, {}) // <-- annotation removed
}
}
class Child {
action = action(() => {})
constructor() {
super()
makeObservable(this, {}) // <-- annotation removed
}
}