Skip to content
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

Added docs on topological dependency tracking #253

Merged
merged 2 commits into from
Sep 19, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions docs/versioned_docs/v0.6/basics/reactivity.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,32 @@ let root = {

If we call `state.set(...)` somewhere else in our code, the text content will automatically be
updated!

## Common pitfalls

Dependency tracking is *topological*, which means that reactive dependencies (like a `Signal`) must be accessed (and thus recorded as reactive dependencies) *before* the tracking scope (like a `create_effect`) returns.

For example, this code won't work as intended:

```rust
create_effect(move || {
wasm_bindgen_futures::spawn_local(async move {
// This scope is not tracked because spawn_local runs on the next microtask tick (in other words, some time later).
};
// Everything that is accessed until here is tracked. Once this closure returns, nothing is tracked.
});
```

We'll find that any `Signal`s we track in the `create_effect` won't be tracked properly in the `wasm_bindgen_futures::spawn_local`, which is often not what's intended. This problem can be gotten around by accessing reactive dependencies as needed before going into a future, or with this simple fix:

```rust
create_effect(move || {
let _ = signal.get(); // Where `signal` is a reactive dependency
wasm_bindgen_futures::spawn_local(async move {
// This scope is not tracked because spawn_local runs on the next microtask tick (in other words, some time later).
};
// Everything that is accessed until here is tracked. Once this closure returns, nothing is tracked.
});
```

All we're doing there is accessing the dependency before we move into the future, which means dependency tracking should work as intended.