Closed Aqours closed 4 years ago
Yeah to do this more efficient you could split it up in smaller autoruns / computeds (it is possible to create computeds or autoruns inside autoruns (but don't forget you need to cleanup for the latter)), or you could compare the items you have with what you have in the DOM, or deepUtils indeed. It's all possible I'd expect, and I recommend to just play and study how different solutions like https://github.com/ryansolid/mobx-jsx and https://github.com/adobe/lit-mobx. Beyond that this question is basically asking how to build a framework, which is a bit out of scope of an issue tracker :)
Yep, it's out of scope. Close it.
it is possible to create computeds ...
A little confused. I can get ADD and UPDATE actions via computed value, but REMOVE action will lost. So what are you means?
interface IStageItem {
message: string;
contextMessage?: string;
status?: string;
needUpdate?: boolean; // Change it manually
}
class Segement {
@observable stages = <IObservableArray<IStageItem>>[];
@computed
get needUpdateStages() {
return this.stages.filter(item => (item.needUpdate == null || item.needUpdate));
}
setView() {
autorun(() => {
/**
* Get ADD/UPDATE stages via @computed value, and then re-rendering them.
*/
for (const item of this.needUpdateStages) {
// Rendering Code
}
});
return this;
}
}
I try mobx.observe
and it works fine except the code looks redundant when update values.
interface IStageItem {
message: string;
contextMessage?: string;
status?: string;
}
class Segement {
@observable stages = <IObservableArray<IStageItem>>[];
@action.bound
protected observeListener<T>(change: IArrayChange<T> | IArraySplice<T>): void {
if (isObservableArray(change.object)) {
switch (change.type) {
case MobXEventType.Update:
// UPDATE
// this.onListUpdate(change.newValue, change.oldValue, change.object, change.index);
break;
case MobXEventType.Splice:
if (change.removedCount) {
// REMOVE
// this.onListRemove(change.removed, change.removedCount, change.object, change.index);
}
if (change.addedCount) {
// ADD
// this.onListAdd(change.added, change.addedCount, change.object, change.index);
}
break;
}
}
}
setView() {
observe(this.stages, this.observeListener, true);
return this;
}
}
const s = new Segement().setView();
s.stages.push({ message: 'First', status: 'fail' });
/**
* Update .stages[0].status value
*
* It works fine but looks redundant when update values. (Working with `Intercept` maybe a good idea)
*/
s.stages[0] = Object.assign({}, s.stages[0], { status: 'done' });
Background
I create an observable array
Segment.stages
which contains some objects.mobx.autorun
will renderingSegment.stages
and append dom node to Document without any frameworks.Question
The first element which I don't change anymore, will always re-rendering when
Segment.stages
has been changed. I think it will affect dom rendering performace whenSegment.stages
include many items or this code had been used in many places.In this case, how to optimizing rendering native dom?
Possible Solutions
mobx.observe
ormobxUtils.deepObserve
to distinguish array ADD, UPDATE, REMOVE actions Shortcomingmobx.observe
can not observe deep changesmobxUtils.deepObserve
can not fire immediately Expected