Reactivity
Ansiq’s preferred reactive primitives are:
signalcomputedeffect
If you are coming from React, the first shift to make is:
- Ansiq does not center everything around whole-component rerender
- Ansiq is closer to a Vue / Solid style fine-grained model
- reactivity decides what is dirty, while the runtime decides how the terminal updates
Continue the NotesApp
In Your First App, we built a minimal input-and-submit app.
Now we extend the same example instead of switching to a new one. We add:
- one derived value: the current input length
- one side-effect boundary: an
effectthat reacts when the input becomes empty
fn render(&mut self, cx: &mut ViewCtx<'_, Self::Message>) -> Element<Self::Message> {
let draft = cx.signal(|| String::new());
let current = draft.get();
let input_len = cx.computed({
let draft = draft.clone();
move || draft.get().chars().count()
});
cx.effect({
let draft = draft.clone();
move || {
if draft.get().is_empty() {
// side-effect boundary
}
}
});
view! {
<Paragraph text={"Type and press Enter"} />
<Input
value={current.clone()}
on_change={{
let draft = draft.clone();
move |next| draft.set_if_changed(next)
}}
on_submit={|next| Some(Message::Submit(next))}
/>
<Paragraph text={format!("Characters: {}", input_len.get())} />
<Paragraph text={format!("Last submit: {}", self.submitted)} />
}
}At this point the same small app already demonstrates the three reactive layers:
draftas base stateinput_lenas derived stateeffectas a side-effect boundary
signal
signal is the basic mutable reactive state unit.
Use it for:
- input values
- current selections
- local panel state
- small pieces of state read by multiple UI regions
computed
computed represents derived state.
Use it for:
- display values derived from signals
- sorted or filtered results
- values that should not become duplicated stored state
In the running NotesApp, input_len is the clearest example: it depends on draft, but should not be stored separately.
effect
effect is for reactive side effects.
One important note:
effectis not React’suseEffect.
It has no dependency array. Dependencies are tracked automatically from reactive reads during execution.
Use it for:
- behavior triggered by reactive changes
- integration with tasks or other systems
- logic that should not be encoded as direct UI rendering
A useful rule:
- if it is displayed derived state, think
computed - if it triggers behavior, think
effect
The important boundary
This page matters because of one line:
- reactivity decides what became dirty
- runtime decides how the terminal updates
That separation is one of the main reasons Ansiq stays understandable.
If you want one question to keep in mind while reading the next pages, use this one:
- when the current draft changes, does the whole app really need to be rebuilt?
Ansiq’s answer is no. First shrink the dirty scope, then shrink the rendering work.
Next
If you want the deeper mechanism first, continue with Reactive System in Depth.
If you want to keep moving toward UI composition, continue with Components and view!.