diff options
Diffstat (limited to 'examples/03-controlled-inputs/README.md')
-rw-r--r-- | examples/03-controlled-inputs/README.md | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/examples/03-controlled-inputs/README.md b/examples/03-controlled-inputs/README.md index 297a3c7..dff4a76 100644 --- a/examples/03-controlled-inputs/README.md +++ b/examples/03-controlled-inputs/README.md @@ -1,3 +1,49 @@  # 03 Controlled Inputs + +The most common way to handle inputs and other state-holding elements is in a +_controlled_ way. This means your app's model is the source of truth for that +element's state, and you update that state based on user input or other events. + +This example shows what that means in practice. For any controlled input we need +two things: + +- A field in our model (or a function to derive a value from the model) to use + as the input's `value` attribute. + +- A message variant to handle input events and update the model. + +```gleam +ui.input([ + // Input's value is fixed to the model's `value` field + attribute.value(model.value), + // Whenever the input changes, we send a `GotInput` message with the new value + event.on_input(GotInput) +]) +``` + +## Why is this beneficial? + +Central to Lustre's architecture is the idea that your model is the single source +of truth for your application's UI. This opens up the door to things like serialising +progam state to load in the future, time-travel debugging, and rehydrating your +app's state from a server. + +It also gives you tighter control of when and how to update your UI in response +to user input. In this example, we only update the model when the new input +value is less than 10 characters long. + +```gleam +case msg { + GotInput(value) -> { + let length = string.length(value) + + case length <= model.max { + True -> Model(..model, value: value, length: length) + False -> model + } + } + + ... +``` |