mirror of
https://github.com/centau/vide.git
synced 2026-08-20 14:41:37 +00:00
95 lines
2.1 KiB
Markdown
95 lines
2.1 KiB
Markdown
# Derived Sources
|
|
|
|
We have seen the basic way to derive a source:
|
|
|
|
```lua
|
|
local count = source(0)
|
|
|
|
local text = function()
|
|
return "count: " .. tostring(count())
|
|
end
|
|
|
|
print(text()) -- "count: 0"
|
|
count(1)
|
|
print(text()) -- "count: 1"
|
|
```
|
|
|
|
However, in some cases where this source could be used by multiple effects at
|
|
the same time, the function wrapping the source will needlessly rerun to convert
|
|
the count into a string for each effect using it.
|
|
|
|
```lua
|
|
local source = vide.source
|
|
local effect = vide.effect
|
|
|
|
local count = source(0)
|
|
|
|
local text = function()
|
|
print "ran"
|
|
return "count: " .. tostring(count())
|
|
end
|
|
|
|
effect(function()
|
|
text() -- prints "ran"
|
|
end)
|
|
|
|
effect(function()
|
|
text() -- prints "ran" again
|
|
end)
|
|
```
|
|
|
|
To avoid this, you can use `derive()` to derive a new source instead. This will
|
|
run a callback in a new reactive scope only when a dependent source has updated.
|
|
Reading this derived source multiple times will just return a cached result from
|
|
when it last updated.
|
|
|
|
```lua
|
|
local source = vide.source
|
|
local derive = vide.derive
|
|
local effect = vide.effect
|
|
|
|
local count = source(0)
|
|
|
|
local text = derive(function()
|
|
print "ran"
|
|
return "count: " .. tostring(count())
|
|
end)
|
|
|
|
effect(function()
|
|
text() -- prints "ran"
|
|
end)
|
|
|
|
effect(function()
|
|
text() -- does not print
|
|
end)
|
|
```
|
|
|
|
Deriving a source in this manner is similar to creating an effect to update
|
|
another source. You should never manually do this using an effect however,
|
|
improper usage could accidently create infinite loops in the reactive graph.
|
|
Always favour deriving when you need one source to update based on another.
|
|
|
|
`derive()` must also be used within a root reactive scope, just like `effect()`.
|
|
|
|
The reactive graph for the above example:
|
|
|
|
```mermaid
|
|
%%{init: {
|
|
"theme": "base",
|
|
"themeVariables": {
|
|
"primaryColor": "#1B1B1F",
|
|
"primaryTextColor": "#fff",
|
|
"primaryBorderColor": "#1B1B1F",
|
|
"lineColor": "#79B8FF",
|
|
"tertiaryColor": "#161618",
|
|
"tertiaryBorderColor": "#161618"
|
|
}
|
|
}}%%
|
|
|
|
flowchart
|
|
|
|
subgraph root
|
|
direction LR
|
|
count --> text --> effect1 & effect2
|
|
end
|
|
```
|