Summary:
This ticket covers the refactoring of Neo.core.Effect to change its internal isRunning flag from a plain boolean to a reactive Neo.core.Config instance. This change was essential to break an infinite loop encountered in functional components, where an effect's execution was inadvertently creating a dependency on its own update cycle.
Rationale:
Functional components use a central vdomEffect to re-render when state changes. The initial implementation caused an infinite loop because the effect's execution triggered an update process (updateVdom), which in turn read a reactive property (vnode) that was set at the end of the update. This created a feedback loop: effect -> update -> read vnode -> trigger effect.
To break this loop, the component needed to apply the VDOM update after the effect had finished running, outside of its tracking scope. Making Effect a full Observable was deemed too heavyweight. The most minimalistic and elegant solution was to make only the isRunning property observable.
Implementation Details:
- The
isRunning property in Neo.core.Effect was changed from a boolean to an instance of Neo.core.Config, initialized with false.
- The
run() method was updated to use isRunning.get() for checks and isRunning.set() to update the state.
- This allows consumer classes, such as
Neo.functional.component.Base, to subscribe() to the isRunning config and safely trigger actions (like applying VDOM updates) when the state changes from true to false, effectively decoupling the action from the effect's dependency tracking.
Definition of Done:
Effect.isRunning is an instance of Neo.core.Config.
- The
run() method correctly uses get() and set() on isRunning.
- The change successfully enables consumers to observe the effect's execution state, resolving the infinite loop problem in functional components.
Summary: This ticket covers the refactoring of
Neo.core.Effectto change its internalisRunningflag from a plain boolean to a reactiveNeo.core.Configinstance. This change was essential to break an infinite loop encountered in functional components, where an effect's execution was inadvertently creating a dependency on its own update cycle.Rationale: Functional components use a central
vdomEffectto re-render when state changes. The initial implementation caused an infinite loop because the effect's execution triggered an update process (updateVdom), which in turn read a reactive property (vnode) that was set at the end of the update. This created a feedback loop:effect -> update -> read vnode -> trigger effect.To break this loop, the component needed to apply the VDOM update after the effect had finished running, outside of its tracking scope. Making
Effecta fullObservablewas deemed too heavyweight. The most minimalistic and elegant solution was to make only theisRunningproperty observable.Implementation Details:
isRunningproperty inNeo.core.Effectwas changed from a boolean to an instance ofNeo.core.Config, initialized withfalse.run()method was updated to useisRunning.get()for checks andisRunning.set()to update the state.Neo.functional.component.Base, tosubscribe()to theisRunningconfig and safely trigger actions (like applying VDOM updates) when the state changes fromtruetofalse, effectively decoupling the action from the effect's dependency tracking.Definition of Done:
Effect.isRunningis an instance ofNeo.core.Config.run()method correctly usesget()andset()onisRunning.