Despite the fact that it all starts with the fact that someone changed something, the final decision whether to recalculate this or that invariant can take both a dependence and a dependent state.
🥌 Push
🚂 Pull
🥌 Push
When the dependency changes, reactions are certainly triggered, which calculate and write new values to the dependent states. This is how, for example, RxJS, Effector and other procedural/functional libraries/frameworks work.
And this works great for a static invariant graph. However, in any not entirely trivial application we have dynamics. Well, it’s trivial: if we switch between pages, then we need to release the resources of the previous page (and in particular unsubscribe from data changes) and seize resources for the new page (and in particular subscribe to data changes).
That is, our graph of invariants must be able to change in the process of recalculating these invariants. This means that when acting on the push principle, we will often find ourselves in situations like this: we spent a long, long time calculating some value, but in the end no one needed it, because the consumer was destroyed.
🚂 Pull
When accessing a dependent state, an invariant is calculated, which pulls values from the dependencies and returns the current value. This is how $mol_wire, CellX, MobX and Vue work.
Here, purely logically, we always know that if a calculation has occurred, then someone needs its result. And if it is not needed, then the calculation will not occur. Therefore, the delaying approach seems to me more practical.
Top comments (3)
What happens with dependency loops? Can we really protect us from infinite loops somehow? I suppose, Pull is better than push, but is it sufficient?
There will be an article on this topic soon.
dev.to/ninjin/cyclic-reactive-depe...