docs: typo fixes and other small changes to the docs (#662)

This commit is contained in:
Elliot Waite 2023-03-12 11:51:47 -07:00 committed by GitHub
parent e7d56b76b8
commit 2e671887d9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 260 additions and 258 deletions

View file

@ -2,7 +2,7 @@
Believe it or not, weve made it this far without having mentioned half of the reactive system: effects.
Leptos is built on a fine-grained reactive system, which means that individual reactive values (“signals,” sometimes known as observables) trigger the code that reacts to them (“effects,” sometimes known as observers) to re-run. These two halves of the reactive system are inter-dependent. Without effects, signals can change within the reactive system but never be observed in a way that interacts with the outside world. Without signals, effects run once but never again, as theres no observable value to subscribe to.
Leptos is built on a fine-grained reactive system, which means that individual reactive values (“signals,” sometimes known as observables) trigger rerunning the code that reacts to them (“effects,” sometimes known as observers). These two halves of the reactive system are inter-dependent. Without effects, signals can change within the reactive system but never be observed in a way that interacts with the outside world. Without signals, effects run once but never again, as theres no observable value to subscribe to.
[`create_effect`](https://docs.rs/leptos_reactive/latest/leptos_reactive/fn.create_effect.html) takes a function as its argument. It immediately runs the function. If you access any reactive signal inside that function, it registers the fact that the effect depends on that signal with the reactive runtime. Whenever one of the signals that the effect depends on changes, the effect runs again.
@ -22,7 +22,7 @@ By default, effects **do not run on the server**. This means you can call browse
## Autotracking and Dynamic Dependencies
If youre familiar with a framework like React, you might notice one key difference. React and similar frameworks typically require you to pass a “dependency array,” an explicit set of variables that determine when the effect should re-run.
If youre familiar with a framework like React, you might notice one key difference. React and similar frameworks typically require you to pass a “dependency array,” an explicit set of variables that determine when the effect should rerun.
Because Leptos comes from the tradition of synchronous reactive programming, we dont need this explicit dependency list. Instead, we automatically track dependencies depending on which signals are accessed within the effect.
@ -82,7 +82,7 @@ view! { cx,
}
```
This works because the framework essentially creates an effect wrapping this update. You can imagine Leptos translating this view something like this:
This works because the framework essentially creates an effect wrapping this update. You can imagine Leptos translating this view into something like this:
```rust
let (count, set_count) = create_signal(cx, 0);

View file

@ -48,6 +48,6 @@ view! { cx,
}
```
Resources also provide a `refetch()` method that allow you to manually reload the data (for example, in response to a button click) and a `loading()` method that returns a `ReadSignal<bool>` indicating whether the resource is currently loading or not.
Resources also provide a `refetch()` method that allows you to manually reload the data (for example, in response to a button click) and a `loading()` method that returns a `ReadSignal<bool>` indicating whether the resource is currently loading or not.
<iframe src="https://codesandbox.io/p/sandbox/10-async-resources-4z0qt3?file=%2Fsrc%2Fmain.rs&selection=%5B%7B%22endColumn%22%3A1%2C%22endLineNumber%22%3A3%2C%22startColumn%22%3A1%2C%22startLineNumber%22%3A3%7D%5D" width="100%" height="1000px"></iframe>

View file

@ -18,7 +18,7 @@ let text = move || if count_is_odd() {
};
// an effect automatically tracks the signals it depends on
// and re-runs when they change
// and reruns when they change
create_effect(cx, move |_| {
log!("text = {}", text());
});
@ -45,7 +45,7 @@ The key phrase here is “runs some kind of code.” The natural way to “run s
1. virtual DOM (VDOM) frameworks like React, Yew, or Dioxus rerun a component or render function over and over, to generate a virtual DOM tree that can be reconciled with the previous result to patch the DOM
2. compiled frameworks like Angular and Svelte divide your component templates into “create” and “update” functions, rerunning the update function when they detect a change to the components state
3. in fine-grained reactive frameworks like SolidJS, Sycamore, or Leptos, _you_ define the functions that re-run
3. in fine-grained reactive frameworks like SolidJS, Sycamore, or Leptos, _you_ define the functions that rerun
Thats what all our components are doing.
@ -68,7 +68,7 @@ pub fn SimpleCounter(cx: Scope) -> impl IntoView {
The `SimpleCounter` function itself runs once. The `value` signal is created once. The framework hands off the `increment` function to the browser as an event listener. When you click the button, the browser calls `increment`, which updates `value` via `set_value`. And that updates the single text node represented in our view by `{value}`.
Closures are key to reactivity. They provide the framework with the ability to re-run the smallest possible unit of your application in responsive to a change.
Closures are key to reactivity. They provide the framework with the ability to rerun the smallest possible unit of your application in responsive to a change.
So remember two things:

View file

@ -17,8 +17,8 @@ For example, instead of embedding logic in a component directly like this:
pub fn TodoApp(cx: Scope) -> impl IntoView {
let (todos, set_todos) = create_signal(cx, vec![Todo { /* ... */ }]);
// ⚠️ this is hard to test because it's embedded in the component
let maximum = move || todos.with(|todos| {
todos.iter().filter(|todo| todo.completed).sum()
let num_remaining = move || todos.with(|todos| {
todos.iter().filter(|todo| !todo.completed).sum()
});
}
```
@ -29,8 +29,8 @@ You could pull that logic out into a separate data structure and test it:
pub struct Todos(Vec<Todo>);
impl Todos {
pub fn remaining(&self) -> usize {
todos.iter().filter(|todo| todo.completed).sum()
pub fn num_remaining(&self) -> usize {
todos.iter().filter(|todo| !todo.completed).sum()
}
}
@ -46,7 +46,7 @@ mod tests {
pub fn TodoApp(cx: Scope) -> impl IntoView {
let (todos, set_todos) = create_signal(cx, Todos(vec![Todo { /* ... */ }]));
// ✅ this has a test associated with it
let maximum = move || todos.with(Todos::remaining);
let num_remaining = move || todos.with(Todos::num_remaining);
}
```

View file

@ -31,7 +31,7 @@ fn App(cx: Scope) -> impl IntoView {
set_count.update(|n| *n += 1);
}
>
"Click me"
"Click me: "
{move || count.get()}
</button>
}
@ -61,7 +61,7 @@ Every component is a function with the following characteristics
## The Component Body
The body of the component function is a set-up function that runs once, not a
render function that re-runs multiple times. Youll typically use it to create a
render function that reruns multiple times. Youll typically use it to create a
few reactive variables, define any side effects that run in response to those values
changing, and describe the user interface.
@ -110,7 +110,7 @@ than theyve ever used in their lives. And fair enough. Basically, passing a f
into the view tells the framework: “Hey, this is something that might change.”
When we click the button and call `set_count`, the `count` signal is updated. This
`move || count.get()` closure, whose value depends on the value of `count`, re-runs,
`move || count.get()` closure, whose value depends on the value of `count`, reruns,
and the framework makes a targeted update to that one specific text node, touching
nothing else in your application. This is what allows for extremely efficient updates
to the DOM.

View file

@ -26,7 +26,7 @@ things:
all of which can be rendered. Spending time in the `Option` and `Result` docs in particular
is one of the best ways to level up your Rust game.
4. And always remember: to be reactive, values must be functions. Youll see me constantly
wrap things in a `move ||` closure, below. This is to ensure that they actually re-run
wrap things in a `move ||` closure, below. This is to ensure that they actually rerun
when the signal they depend on changes, keeping the UI reactive.
## So What?

View file

@ -154,6 +154,7 @@ pub fn Layout(cx: Scope) -> impl IntoView {
view! { cx,
<header>
<h1>"My Page"</h1>
</header>
<main>
<Content/>
</main>
@ -194,6 +195,7 @@ pub fn Layout(cx: Scope, set_toggled: WriteSignal<bool>) -> impl IntoView {
view! { cx,
<header>
<h1>"My Page"</h1>
</header>
<main>
<Content set_toggled/>
</main>