当前位置:网站首页>Analyzing mobx responsive refresh mechanism from source code
Analyzing mobx responsive refresh mechanism from source code
2022-06-12 18:19:00 【InfoQ】
Preface
Observer class

StatelessObserverWidget
abstract class StatelessObserverWidget extends StatelessWidget
with ObserverWidgetMixin {
/// Initializes [key], [context] and [name] for subclasses.
const StatelessObserverWidget(
{Key? key, ReactiveContext? context, String? name})
: _name = name,
_context = context,
super(key: key);
final String? _name;
final ReactiveContext? _context;
@override
String getName() => _name ?? '$this';
@override
ReactiveContext getContext() => _context ?? super.getContext();
@override
StatelessObserverElement createElement() => StatelessObserverElement(this);
}
createElementStatelessWidgetStatelessObserverElementElementObserverWidgetMixin
WidgetmixincreateReactionreactioncreateReactionObserverElementMixinmixin ObserverWidgetMixin on Widget {
String getName();
ReactiveContext getContext() => mainContext;
@visibleForTesting
Reaction createReaction(
Function() onInvalidate, {
Function(Object, Reaction)? onError,
}) =>
ReactionImpl(
getContext(),
onInvalidate,
name: getName(),
onError: onError,
);
void log(String msg) {
debugPrint(msg);
}
}
StatelessObserverElement
StatelessObserverElementStatelessElementObserverElementMixinObserverElementMixinObserverElementMixinmixin ObserverElementMixin on ComponentElement {
ReactionImpl get reaction => _reaction;
late ReactionImpl _reaction;
// Not using the original `widget` getter as it would otherwise make the mixin
// impossible to use
ObserverWidgetMixin get _widget => widget as ObserverWidgetMixin;
@override
void mount(Element? parent, dynamic newSlot) {
_reaction = _widget.createReaction(invalidate, onError: (e, _) {
FlutterError.reportError(FlutterErrorDetails(
library: 'flutter_mobx',
exception: e,
stack: e is Error ? e.stackTrace : null,
));
}) as ReactionImpl;
super.mount(parent, newSlot);
}
void invalidate() => markNeedsBuild();
@override
Widget build() {
late Widget built;
reaction.track(() {
built = super.build();
});
if (!reaction.hasObservables) {
_widget.log(
'No observables detected in the build method of ${reaction.name}',
);
}
return built;
}
@override
void unmount() {
reaction.dispose();
super.unmount();
}
}
mixinElemenntmountmountreactioninvalidateinvalidatemarkNeedsBuildreactionmarkNeedsBuildElementWidgetbuildmixinbuildreactiontrackobserverObserverbuilderwidgetvoid _bindDependencies(Derivation derivation) {
final staleObservables =
derivation._observables.difference(derivation._newObservables!);
final newObservables =
derivation._newObservables!.difference(derivation._observables);
var lowestNewDerivationState = DerivationState.upToDate;
// Add newly found observables
for (final observable in newObservables) {
observable._addObserver(derivation);
// Computed = Observable + Derivation
if (observable is Computed) {
if (observable._dependenciesState.index >
lowestNewDerivationState.index) {
lowestNewDerivationState = observable._dependenciesState;
}
}
}
// Remove previous observables
for (final ob in staleObservables) {
ob._removeObserver(derivation);
}
if (lowestNewDerivationState != DerivationState.upToDate) {
derivation
.._dependenciesState = lowestNewDerivationState
.._onBecomeStale();
}
derivation
.._observables = derivation._newObservables!
.._newObservables = {}; // No need for newObservables beyond this point
}
State object tracking
@observablefinal _$praiseCountAtom = Atom(name: 'ShareStoreBase.praiseCount');
@override
int get praiseCount {
_$praiseCountAtom.reportRead();
return super.praiseCount;
}
@override
set praiseCount(int value) {
_$praiseCountAtom.reportWrite(value, super.praiseCount, () {
super.praiseCount = value;
});
}
getAtomreportRead_reportObservedObservervoid _reportObserved(Atom atom) {
final derivation = _state.trackingDerivation;
if (derivation != null) {
derivation._newObservables!.add(atom);
if (!atom._isBeingObserved) {
atom
.._isBeingObserved = true
.._notifyOnBecomeObserved();
}
}
}
setsetAtomreportWritereaction void schedule() {
if (_isScheduled) {
return;
}
_isScheduled = true;
_context
..addPendingReaction(this)
..runReactions();
}
reaction_run_onInvalidateObserverElementMixincreateReactionWidgetbuildvoid _run() {
if (_isDisposed) {
return;
}
_context.startBatch();
_isScheduled = false;
if (_context._shouldCompute(this)) {
try {
_onInvalidate();
} on Object catch (e, s) {
// Note: "on Object" accounts for both Error and Exception
_errorValue = MobXCaughtException(e, stackTrace: s);
_reportException(_errorValue!);
}
}
_context.endBatch();
}
summary
- Controls the of rendering
ElementyesStatelessObserverElement, In the classmountStage throughcreateReactionregisteredreaction.
StatelessObserverElementstaybuildIn the methodreactionandobservableBinding .
- stay
ObserverWhen reading the properties of the state object in , Will call itsgetMethod , This method will match the state object property with the correspondingObserverComponents Binding .
- When the properties of the state object are
setWhen changing , Will be dispatched to the bound of this propertyreaction, perform_onInvalidateMethod to refresh , Thus, a responsive non perceptual refresh is realized .

边栏推荐
- 联想回应笔记本太多太杂乱:现在是产品调整期 未来将分为数字/Air/ Pro三大系列
- 从源码解析 MobX 响应式刷新机制
- TypeScript常用类型(一)
- Reconstruction -- sort out and decompose the inheritance system
- 企业架构的第一性原理
- Gospel of audio and video developers, rapid integration of AI dubbing capability
- This shift, I still have to go
- 在同花顺开户证券安全吗
- Lightweight and convenient small program to app technology solution to realize interconnection with wechat / traffic app
- 有源差分晶振原理圖以及LV-PECL、LVDS、HCSL區別
猜你喜欢

HTTP缓存<强缓存与协商缓存>

网盘和对象云存储管理之磁盘映射工具比较

Installation and configuration of window version pytorch entry depth learning environment

PHP implementation of infinite classification tree (recursion and Optimization)

轻量、便捷的小程序转App技术方案,实现与微信/流量App互联互通

js两数之和

A story on the cloud of the Centennial Olympic Games belonging to Alibaba cloud video cloud

An easy-to-use IDE for small programs

Machine learning series (3): logistic regression

ESP-IDF 添加自己的组件
随机推荐
MySQL learning notes
Esp32-c3 esp-idf configuring smartconfig and SNTP to obtain network time
js求斐波那契数列
JS中的栈(含leetcode例题)<持续更新~>
Introduction to service grid and istio - continued
Machine learning series (5): Naive Bayes
Relationship between resolution and line field synchronization signal
Typescript type declaration file (III)
Explanation of core interrupt of Godson processor
联想回应笔记本太多太杂乱:现在是产品调整期 未来将分为数字/Air/ Pro三大系列
torch.where的新用法(很老但是大家忽略的用法)
Research results of low code platform
es7不使用父子和嵌套关系来实现一对多功能
VirtualLab基础实验教程-5.泊松亮斑
VirtualLab基础实验教程-6.闪耀光栅
同花顺能开户吗,同花顺在APP上可以直接开通券商安全吗
Vant3+ts H5 pages are nested into apps to communicate with native apps
有源差分晶振原理图以及LV-PECL、LVDS、HCSL区别
MYSQL:Expression #4 of SELECT list is not in GROUP BY clause and contains nonaggregated column
Small program +app, a low-cost and active technology combination idea