子类化
¥Subclassing
limitations 支持子类化。最值得注意的是,你只能覆盖原型上的操作/流程/计算 - 你不能覆盖 字段声明。对子类中重写的方法/getter 使用 override
注释 - 请参见下面的示例。尽量让事情变得简单,并且更喜欢组合而不是继承。
¥Subclassing is supported with limitations. Most notably you can only override actions/flows/computeds on prototype - you cannot override field declarations. Use the override
annotation for methods/getters overridden in a subclass - see example below. Try to keep things simple and prefer composition over inheritance.
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,
})
}
}
局限性
¥Limitations
只有原型上定义的
action
、computed
、flow
、action.bound
可以被子类覆盖。¥Only
action
,computed
,flow
,action.bound
defined on prototype can be overridden by subclass.字段不能在子类中重新注释,
override
除外。¥Field can't be re-annotated in subclass, except with
override
.makeAutoObservable
不支持子类化。¥
makeAutoObservable
does not support subclassing.不支持扩展内置函数(
ObservableMap
、ObservableArray
等)。¥Extending builtins (
ObservableMap
,ObservableArray
, etc) is not supported.你不能在子类中为
makeObservable
提供不同的选项。¥You can't provide different options to
makeObservable
in subclass.你不能在单个继承链中混合注释/装饰器。
¥You can't mix annotations/decorators in single inheritance chain.
TypeError: Cannot redefine property
如果你看到此内容,你可能正在尝试重写子类 x = () => {}
中的箭头函数。这是不可能的,因为类的所有带注释的字段都是不可配置的(查看限制)。你有两个选择:
¥If you see this, you're probably trying to override arrow function in subclass x = () => {}
. That's not possible because all annotated fields of classes are non-configurable (see limitations). You have two options:
1. Move function to prototype and use action.bound
annotation instead
class Parent {
// action = () => {};
// =>
action() {}
constructor() {
makeObservable(this, {
action: action.bound
})
}
}
class Child {
action() {}
constructor() {
super()
makeObservable(this, {
action: override
})
}
}
2. Remove action
annotation and wrap the function in action manually: x = action(() => {})
class Parent {
// action = () => {};
// =>
action = action(() => {})
constructor() {
makeObservable(this, {}) // <-- annotation removed
}
}
class Child {
action = action(() => {})
constructor() {
super()
makeObservable(this, {}) // <-- annotation removed
}
}