2021-12-14 MobX分享
observable(value) @observable example = value;
let list = observable([1, 2, 3, 4, 5]); // 还有其他两种写法 @observable list = ([1, 2, 3, 4, 5]); let list = observable.array([1, 2, 3, 4, 5]);
//在任何变化作用于数组时拦截 intercept(target, propertyName?, interceptor) //删除所有项 clear() //查找 find(), findIndex // 通过值从数组中移除一个单个的项。如果项被找到并移除的话,返回 true remove(value)
observable.array
在 observable 数组传递给外部库或者内置方法前创建一份浅拷贝
// 三种定义方式 可自选 let map = observable(new Map()); @observable map = new Map(); let map = observable.map(new Map()); // observable.map(value) 中的value可以是对象、数组或者字符串键的ES6 map
class ObjectTest { @observable obj = { name: 'll' } person = observable.object({ name: 'xiaoming', age: 10 }); cat = observable({ voice: '喵喵' }); }
const objectT = new ObjectTest(); extendObservable(objectT, { firstName: 'li', lastName: 'xiaoming', get fullName() { return this.firstName + " " + this.lastName }, });
// 返回当前值。 get() // 替换当前存储的值并通知所有观察者。 set(value) // 注册一个观察者函数,每次存储值被替换时触发。返回一个函数以取消观察者。 // change 参数是一个对象,其中包含 observable 的 newValue 和 oldValue .observe(callback: (change) => void)
// @observable.shallow value = { @observable.deep value = { name: 'liming', age: 12, details: { tel: 111, addr: '路' } } @action changeTel = () => { this.value.details.tel = 222; } <div> <p>{this.props.data.value.details.tel}</p> <button onClick={this.props.data.changeTel}></button> </div>
// observable.ref @observable.ref test = { name: 'liming', age: 12 } @action changeName() => { this.test.name = 'xiaoming'; }
@observable num = 0; @action addNum = => { this.num++ }
@observable test = "test"; @observable boundStr = "bound"; @action changeTest = () => { this.test = "action"; } @action.bound changeBound() { this.boundStr = "action-bound"; }
@action changeTest = () => { setTimeout(() => { this.changeT(); }, 100); } @action changeT = () => { this.test = "异步"; }
@action changeTest = () => { setTimeout(() => { action('changeT', () => { this.test = "异步"; })(); // 注意需要调用 }, 100); }
@action changeTest = () => { setTimeout(() => { runInAction(() => { this.test = "异步"; }); }, 100); }
@action.bound async asyncChange() { const data = await this.timeout(); runInAction(() => { this.test = data; }); }
@action.bound asyncChange = flow(function * () { const data = yield this.timeout(); this.test = data; });
values(thing)
将集合中的所有值作为数组返回keys(thing)
将集合中的所有键作为数组返回entries(thing)
返回集合中的所有项的键值对数组set(thing, key, value)
或set(thing, { key: value })
使用提供的键值对来更新给定的集合remove(thing, key)
从集合中移除指定的项。用于数组拼接has(thing, key)
如果集合中存在指定的 observable 属性就返回 trueget(thing, key)
返回指定键下的子项
<div> <h4>object改变</h4> <p>{values(actions.obj).join(", ")}</p> <button onClick={this.addProps}>添加obj属性</button> </div> addProps = () => { const { actions } = this.props; set(actions.obj, { age: 18 }); }
@observable firstName = 'li'; @observable lastName = 'ming'; @computed get fullName() { return this.firstName + this.lasName; } <div> <p>fullName: {computeds.fullName}</p> <p>fullName: {computeds.fullName}</p> <button onClick={computeds.changeFirstName}>修改firstName</button> </div>
autorun(() => void, options?)
when(predicate: () => boolean, effect?: () => void, options?)
reaction(() => data, (data, reaction) => { sideEffect }, options?)
autorun(() => { console.log('autorun', productList.length); }); reaction(() => productList.length, data => { console.log('reaction'); if(data > 5) { console.log('reaction', '数量超过5'); } }); when(() => productList.length > 5, () => { console.log('when', '数量超过5'); });
- “读取”
- “追踪函数”
- “过程(during)”
let message = observable({ title: "Foo", author: { name: "Michel" }, likes: [ "John", "Sara" ] })
var obj = mobx.observable({ x: 1 }); var clone = mobx.toJS(obj); console.log(mobx.isObservableObject(obj)); // true console.log(mobx.isObservableObject(clone)); // false
observe
target
propertyName
interceptor
const disposer = intercept(person, 'firstName', change => { if(!change.newValue) { return null; } if(change.newValue.length < 5) { change.newValue += '1'; return change; } if(change.newValue.length === 5) { return change; } if(change.newValue.length > 5) { disposer(); return; } throw new Error(change.newValue + '错误'); })
target
propertyName
listener
invokeImmediately
const disposerOb = observe(cat, change => { console.log('observe', change); if(change.newValue === '白色') { changeFirstName({ target: {value: '李'}}); } if(change.newValue === '黑白') { disposerOb(); } });
intercept
object
type
ReactDOM.render( <Provider {...stores}> <Example /> </Provider>, document.getElementById('root') );
inject("store1", "store2")(observer(MyComponent))
@inject("store1", "store2") @observer MyComponent
@inject((stores, props, context) => props) @observer MyComponent
@observer(["store1", "store2"]) MyComponent