This repository has been archived on 2020-09-01. You can view files and clone it, but cannot push or open issues or pull requests.
reactimal/docs/computed.md
2018-11-02 20:44:04 +00:00

76 lines
2.5 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
);
```
Note: Property and container dependencies are "locked" while the computation function is run. If
there are any out-of-band updates to a dependency, the value will be set but will not propagate
until after the computation function is complete and the computed's subscribers are notified.
### 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]);
```