Effects
Edit this pageEffects are functions that are triggered when the signals they depend on change. They play a crucial role in managing side effects, which are actions that occur outside of the application's scope, such as DOM manipulations, data fetching, and subscriptions.
Using an effect
An effect is created using the createEffect
function.
This function takes a callback as its argument that runs when the effect is triggered.
In this example, an effect is created that logs the current value of count
to the console.
When the value of count
changes, the effect is triggered, causing it to run again and log the new value of count
.
Managing dependencies
Effects can be set to observe any number of dependencies. Dependencies are what allow an effect to track changes and respond accordingly. These can include signals, variables, props, context, or any other reactive values. When any of these change, the effect is notified and will run again to update its state.
Upon initialization, an effect will run once, regardless of whether it has any dependencies. This is useful for setting up the effect and initializing variables or subscribing to signals. After this run, the effect will only be triggered when any of its dependencies change.
Solid automatically tracks the dependencies of an effect, so you do not need to manually specify them. This improves the tracking and minimizes the chances of overlooking or incorrectly identifying dependencies.
Subscribing to signals
When an effect is set to observe a signal, it creates a subscription to it. This subscription allows the effect to track the changes in the signal's value, which causes it to observe any changes that may happen and to execute its callback accordingly.
Managing multiple signals
Effects have the ability to observe multiple signals. A single effect can subscribe to multiple signals, and similarly, multiple effects can keep track of a single signal. This is useful when you need to update the UI based on multiple signals.
When multiple signals are observed within a single effect, it will execute its callback whenever any of the signals change. The effect will run even if only one of the signals changes, not necessarily all of them. This means that the effect will run with the latest values of all of the signals that it is observing.
When a signal updates, it notifies all of its subscribers sequentially but the order can vary. While effects are guaranteed to run when a signal updates, the execution might not be instantaneous. This means that the order of execution of effects is not guaranteed and should not be relied upon.
Nested effects
When working with effects, it is possible to nest them within each other. This allows each effect to independently track its own dependencies, without affecting the effect that it is nested within.
The order of execution is important to note. An inner effect will not affect the outer effect. Signals that are accessed within an inner effect, will not be registered as dependencies for the outer effect. When the signal located within the inner effect changes, it will trigger only the inner effect to re-run, not the outer one.
This forces each effect to be independent of each other, which helps to avoid unexpected behaviour. Additionally, it allows you to create effects that are only triggered when certain conditions are met.
Lifecycle functions
Effects have a lifecycle that can be managed using certain functions. These functions allow you to control the initialization and disposal of effects to build the type of behaviour that you need. This can include running a side effect only once, or cleaning up a task when it is no longer needed.
onMount
In situations where you just want to run a side effect once, you can use the onMount
function.
This lifecycle function is similar to an effect, but it does not track any dependencies.
Rather, once the component has been initialized, the onMount
callback will be executed and will not run again.
onMount
provides the assurance that the callback will only run once.
If using an effect in this situation, there is no guarantee that it will only run once, which can lead to unexpected behaviour.
This makes onMount
useful for API calls and other side effects that only need to be run once per component instance.
onCleanup
While onMount
is useful for running a side effect once, onCleanup
is helpful for cleaning up a task when it is no longer needed.
onCleanup
will run whenever the component unmounts, removing any subscriptions that the effect has.
In this example, the onCleanup
function is used to clear the interval that is set up in the effect.
To avoid the interval from running indefinitely, the onCleanup
function is used to clear the interval once the component unmounts.
onCleanup
can be used to avoid memory leaks.
These occur when a component is unmounted, but references to it still exist and, as a result, could still be running in the background.
Using onCleanup
to remove any subscriptions or references to the component can help to avoid this issue.