-
-
Notifications
You must be signed in to change notification settings - Fork 4.6k
Clearer documentation of store contract #4216
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
51473d6
8c1f689
669a8a5
64a95f4
84573a9
eaa3416
0193422
c3017a6
26dea62
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -147,24 +147,7 @@ If a statement consists entirely of an assignment to an undeclared variable, Sve | |
|
||
--- | ||
|
||
A *store* is any object that allows reactive access to a value via a simple *store contract*. | ||
|
||
The [`svelte/store` module](docs#svelte_store) contains minimal store implementations which fulfil this contract. You can use these as the basis for your own stores, or you can implement your stores from scratch. | ||
|
||
A store must contain a `.subscribe` method, which must accept as its argument a subscription function. This subscription function must be immediately and synchronously called with the store's current value upon calling `.subscribe`. All of a store's active subscription functions must later be synchronously called whenever the store's value changes. The `.subscribe` method must also return an unsubscription function. Calling an unsubscription function must stop its subscription, and its corresponding subscription function must not be called again by the store. | ||
|
||
A store may optionally contain a `.set` method, which must accept as its argument a new value for the store, and which synchronously calls all of the store's active subscription functions. Such a store is called a *writable store*. | ||
|
||
```js | ||
const unsubscribe = store.subscribe(value => { | ||
console.log(value); | ||
}); // logs `value` | ||
|
||
// later... | ||
unsubscribe(); | ||
``` | ||
|
||
--- | ||
A *store* is an object that allows reactive access to a value via a simple *store contract*. The [`svelte/store` module](docs#svelte_store) contains minimal store implementations which fulfil this contract. | ||
|
||
Any time you have a reference to a store, you can access its value inside a component by prefixing it with the `$` character. This causes Svelte to declare the prefixed variable, and set up a store subscription that will be unsubscribed when appropriate. | ||
|
||
|
@@ -189,6 +172,53 @@ Local variables (that do not represent store values) must *not* have a `$` prefi | |
</script> | ||
``` | ||
|
||
--- | ||
|
||
You can create your own stores without relying on [`svelte/store`](docs#svelte_store), by implementing the **store contract**: | ||
|
||
1) A store must contain a `.subscribe` method, which must accept as its argument a subscription function. This subscription function must be immediately and synchronously called with the store's current value upon calling `.subscribe`. All of a store's active subscription functions must later be synchronously called whenever the store's value changes. | ||
2) The `.subscribe` method must return an unsubscribe function. Calling an unsubscribe function must stop its subscription, and its corresponding subscription function must not be called again by the store. | ||
3) A store may *optionally* contain a `.set` method, which must accept as its argument a new value for the store, and which synchronously calls all of the store's active subscription functions. Such a store is called a *writable store*. | ||
|
||
```js | ||
|
||
/* Example: a custom writable store for `location.hash` */ | ||
|
||
const subscriptions = []; | ||
|
||
let lastHash; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What specifically is this trying to address? I think the built-in writable stores will call subscribers again if you There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Setting |
||
|
||
const callSubscriptions = () => { | ||
if (location.hash !== lastHash) { | ||
lastHash = location.hash; | ||
for (const subscription of subscriptions) { | ||
subscription(location.hash); | ||
} | ||
} | ||
}; | ||
|
||
window.addEventListener('hashchange', callSubscriptions); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be more in the Svelte-y spirit to have this store not actually register the hashchange event handler until the first subscriber is added, and to unregister it when the last subscriber is removed. This can be easily done by checking |
||
|
||
const hashStore = { | ||
subscribe(subscription) { | ||
subscription(location.hash); // Call subscription with current value | ||
subscriptions.push(subscription); // Subscribe to future values | ||
return () => { // Return an "unsubscribe" function | ||
const index = subscriptions.indexOf(subscription); | ||
if (index !== -1) { | ||
subscriptions.splice(index, 1); // Remove the subscription | ||
} | ||
}; | ||
}, | ||
set(hash) { | ||
location.hash = hash; // Set the value | ||
callSubscriptions(); // Synchronously notify all subscriptions | ||
} | ||
}; | ||
|
||
|
||
``` | ||
|
||
|
||
### <script context="module"> | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.