72 lines
2.2 KiB
Markdown
72 lines
2.2 KiB
Markdown
# computed
|
|
|
|
A `computed` is a [subscribable](./subscribable.md), computed value expression. It takes any number
|
|
of dependent inputs and provides one output. Subscribers are only notified if the computed value
|
|
changes. `computed` forms the core of a logic graph.
|
|
|
|
## Behavior
|
|
|
|
A `computed` takes any kind of dependency but if a dependency is a [subscribable](./subscribable.md)
|
|
then the `computed` will subscribe to it such that the `computed` will be marked as _dirty_ when any
|
|
that subscribable value changes. Whenever the `computed` is read from, if will recompute its result
|
|
if the _dirty_ flag has been set, otherwise it just return the stored result from the last time it
|
|
computed.
|
|
|
|
Unlike [KnockoutJS](http://knockoutjs.com/) and [Vuejs](https://vuejs.org), Reactimal's `computed`
|
|
requires explicit dependency expression to help avoid dependency loops and allow code retain
|
|
readability as it grows.
|
|
|
|
## Usage
|
|
|
|
### Creation
|
|
|
|
Creates a computed instance. Internally the passed computation function is called once to establish
|
|
the initial value.
|
|
|
|
```js
|
|
const showDialog = computed(
|
|
(inVP, shouldShow) => inVP && shouldShow, // computation function
|
|
[inViewport, shouldShow] // array of subscribable dependencies
|
|
);
|
|
```
|
|
|
|
### Read
|
|
|
|
Call the computed to receive the computed value. The value will be computed if any upstream
|
|
dependencies have changed.
|
|
|
|
```js
|
|
if (showDialog()) {
|
|
/* showDialog() is truthy */
|
|
}
|
|
```
|
|
|
|
### Provide a hash function for complex result types
|
|
|
|
When the computed result is a type that is not determined to be equal with simple equality (===),
|
|
provide a hash function to the `hashableComputed` type to create a computed that will reduce the
|
|
result value to a value that can be compared with the identity operator before comparison. The
|
|
computed result value will still be stored unmodified.
|
|
|
|
```js
|
|
function hashSet(_a) {
|
|
if (_a instanceof Set) {
|
|
return Array.from(_a.keys())
|
|
.sort()
|
|
.map(k => `${(typeof k).substr(0, 1)}:${encodeURIComponent(k)}/`)
|
|
.join('?');
|
|
}
|
|
return _a;
|
|
}
|
|
|
|
const computedSet = hashableComputed(hashSet);
|
|
|
|
function _intersection(a, b) {
|
|
return new Set([...a].filter(x => b.has(x)));
|
|
}
|
|
|
|
const a = prop(new Set([1, 2]), hashSet);
|
|
const b = prop(new Set([2, 3]), hashSet);
|
|
const intersection = computedSet(_intersection, [a, b]);
|
|
```
|