You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: packages/overmind-website/guides/beginner/03_definingstate.md
+16-16Lines changed: 16 additions & 16 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
# Defining state
2
2
3
-
Typically we think of the user interface as the application itself. But the user interface is really just there to allow a user to interact with the application. This interface can be anything. A browser window, native, sensors etc. it does not matter what the interface is, the application is still the same.
3
+
Typically we think of the user interface as the application itself. But the user interface is really just there to allow a user to interact with the application. This interface can be anything. A browser window, native, sensors etc. It does not matter what the interface is, the application is still the same.
4
4
5
5
The mechanism of communicating from the application to the user interface is called **state**. A user interface is created by **transforming** the current state. To communicate from the user interface to the application an API is exposed, called **actions** in Overmind. Any interaction can trigger an action which changes the state, causing the application to notify the user interface about any updated state.
6
6
@@ -10,64 +10,64 @@ The mechanism of communicating from the application to the user interface is cal
10
10
11
11
In JavaScript we can create all sorts of abstractions to describe values, but in Overmind we lean on the core serializable values. These are **objects**, **arrays**, **strings**, **numbers**, **booleans** and **null**. Serializable values means that we can easily convert the state into a string and back again. This is fundamental for creating great developer experiences, passing state between client and server and other features. You can describe any application state with these core values.
12
12
13
-
Let us talk a litte bit about what each value helps us represent in our application.
13
+
Let us talk a little bit about what each value helps us represent in our application.
14
14
15
15
### Naming
16
16
17
-
Each value needs to sit behind a name. Naming can be difficult, but we have some help. Even though we eventually do want to consume our application through a user interface we ideally want to avoid naming things specifically related to the environment where we show the user interface. Things like **page**, **tabs**, **modal** etc. is specific to a browser experience, maybe realted to a certain size. We want to avoid those names as they should not dictate what elements are to be used with the state, that is up to the user interface to decide later. So here are some generic terms to use instead:
17
+
Each value needs to sit behind a name. Naming can be difficult, but we have some help. Even though we eventually do want to consume our application through a user interface we ideally want to avoid naming things specifically related to the environment where we show the user interface. Things like **page**, **tabs**, **modal** etc. are specific to a browser experience, maybe related to a certain size. We want to avoid those names as they should not dictate which elements are to be used with the state, that is up to the user interface to decide later. So here are some generic terms to use instead:
18
18
19
19
- page: **mode**
20
20
- tabs: **sections**
21
21
- modal: **editUser.active**
22
22
23
23
### Objects
24
24
25
-
The root value of your state tree is an object, because objects are great for holding other values. An object has keys that points to values. Most of these keys points to values that is the actual state of the application, but these keys can also represent domains of the application. A typical state structure could be:
25
+
The root value of your state tree is an object, because objects are great for holding other values. An object has keys that point to values. Most of these keys point to values that are the actual state of the application, but these keys can also represent domains of the application. A typical state structure could be:
Arrays are in a way similar to objects in the sense that they hold other values, but instead of keys pointing to values you have indexes. That means it is ideal for iteration. But more often than not objects are actually better at managing lists of values. We can actually do fine without arrays in our state. It is when we produce the actual user interface that we usually want arrays. You can learn more about this in the [managing lists](/guides/intermediate/01_managinglists) guide.
33
+
Arrays are similar to objects in the sense that they hold other values, but instead of keys pointing to values you have indexes. That means it is ideal for iteration. But more often than not objects are actually better at managing lists of values. We can actually do fine without arrays in our state. It is when we produce the actual user interface that we usually want arrays. You can learn more about this in the [managing lists](/guides/intermediate/01_managinglists) guide.
34
34
35
35
### Strings
36
36
37
-
Strings are of course used to represent text values. Names, descriptions and what not. But strings are also used for ids, types, etc. Strings can be used as values to reference other values. This is an important part in structuring state. For example in our **objects** example above we chose to use an array to represent the modes, using an index to point to the current mode, but we could also do:
37
+
Strings are of course used to represent text values. Names, descriptions and whatnot. But strings are also used for ids, types, etc. Strings can be used as values to reference other values. This is an important part in structuring state. For example in our **objects** example above we chose to use an array to represent the modes, using an index to point to the current mode, but we could also do:
Now we are referencing the current mode with a string. In this scenario you would probably stick with the array, but it is important to highlight that objects allows you to reference things by string, while arrays reference by number.
43
+
Now we are referencing the current mode with a string. In this scenario you would probably stick with the array, but it is important to highlight that objects allow you to reference things by string, while arrays reference by number.
44
44
45
45
### Numbers
46
46
47
-
Numbers of course represents things like counts, age, etc. But just like strings, they can also represent a reference to something in a list. Like we saw in our **objects** example, to define what the current mode of our application is, we can use a number. You could say that referencing things by number works very well when the value behind the number does not change. Our modes will most likely not change and that is why an array and referencing the current mode by number, is perfectly fine.
47
+
Numbers of course represent things like counts, age, etc. But just like strings, they can also represent a reference to something in a list. Like we saw in our **objects** example, to define what the current mode of our application is, we can use a number. You could say that referencing things by number works very well when the value behind the number does not change. Our modes will most likely not change and that is why an array and referencing the current mode by number, is perfectly fine.
48
48
49
49
### Booleans
50
50
51
-
Are things loading or not, is the user logged in or not? These are typical usages of boolean values. We use booleans to express that something is activated or not. We should not confuse this with **null**, which means "not existing". We should not use **null** in place of a boolean value. We have to use either `true` or `false`.
51
+
Are things loading or not, is the user logged in or not? These are typical uses of boolean values. We use booleans to express that something is activated or not. We should not confuse this with **null**, which means "not existing". We should not use **null** in place of a boolean value. We have to use either `true` or `false`.
52
52
53
53
### Null
54
54
55
-
All values, with the exception of booleans, can also be **null**. Nonexisting. You can have a nonexisting object, array, string or number. That means if we have not selected a mode both the string version and number version would have the value **null**.
55
+
All values, with the exception of booleans, can also be **null**. Non-existing. You can have a non-existing object, array, string or number. It means that if we haven't selected a mode, both the string version and number version would have the value **null**.
56
56
57
57
## Deriving state
58
58
59
59
60
60
### Getter
61
61
62
-
A concept in Javascript called a [getter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get) allows you to intercept accessing a property in an object. A getter is just like a plain value, it can be added an removed at any point. Getters does**not** cache the result for that very reason, but whatever state they access is tracked.
62
+
A concept in Javascript called a [getter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get) allows you to intercept accessing a property in an object. A getter is just like a plain value, it can be added or removed at any point. Getters do**not** cache the result for that very reason, but whatever state they access is tracked.
When you need to do more heavy calculation or combine state from different parts ot the tree you can use a plain function instead. Overmind treats these functions like a **getter**, but the returned value is cached and they can also access the root state of the application. A simple example of this would be:
70
+
When you need to do more heavy calculation or combine state from different parts of the tree you can use a plain function instead. Overmind treats these functions like a **getter**, but the returned value is cached and they can also access the root state of the application. A simple example of this would be:
@@ -85,7 +85,7 @@ The first argument of the function is the state the derived function is attached
85
85
That means the function only runs when accessed and the depending state has changed since last access.
86
86
87
87
```marksy
88
-
h(Notice, null, "Even though derived state is defined as functions you consume them as plain values. You do not have to call the derived function to get the value. Derived state can not be dynamically added. They have to be defined and live in the tree from start to end of your application lifecycle")
88
+
h(Notice, null, "Even though derived state is defined as functions you consume them as plain values. You do not have to call the derived function to get the value. Derived state can not be dynamically added. They have to be defined and live in the tree from start to end of your application lifecycle.")
When you add objects and arrays to your state tree, they are labeled with an "address" in the tree. That means if you try to add the same object or array in multiple spots in the tree you will get an error, as they can not have multiple addresses. Typically this indicates that you rather want to create a references to an existing object or array.
101
+
When you add objects and arrays to your state tree, they are labeled with an "address" in the tree. That means if you try to add the same object or array in multiple spots in the tree you will get an error, as they can not have multiple addresses. Typically this indicates that you'd rather want to create a reference to an existing object or array.
102
102
103
103
So this is an example of how you would **not** want to do it:
0 commit comments