Skip to content

Commit 9fea37a

Browse files
committed
refactor(website): Improve documentation clarity and update state management examples
1 parent 7ee9fba commit 9fea37a

File tree

9 files changed

+362
-24
lines changed

9 files changed

+362
-24
lines changed

website/public/opengraph.png

8.11 KB
Loading

website/src/content/docs/es/core_concepts/state_management.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ la cual encapsula los datos y el comportamiento de un estado particular, y propo
4949

5050
### Metodos del estado
5151

52-
<HT>[`RtState`](/reactter/api/classes/rt_state)</HT> clase proporciona algunos métodos para la gestión de estados. Conozcámoslos:
52+
La clase <HT>[`RtState`](/reactter/api/classes/rt_state)</HT> proporciona algunos métodos para la gestión de estados. Conozcámoslos:
5353

5454
<StateMethods />
5555

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
---
2+
title: Vinculación del estado a la dependencia
3+
description: Aprende a vincular un estado a una dependencia en Reactter para una gestión de estado más eficiente y reactiva.
4+
---
5+
6+
import { Code } from "@astrojs/starlight/components";
7+
import { HE, HK, HM, HN, HS, HT } from '@/components/Highlight';
8+
9+
:::tip
10+
Este guía asume que ya has leído sobre [Inyección de dependencias](/reactter/es/core_concepts/dependency_injection) y [Gestión del estado](/reactter/es/core_concepts/state_management).
11+
Se recomienda leer eso primero si eres nuevo en Reactter.
12+
:::
13+
14+
Un estado de Reactter(<HT>[`RtState`](/reactter/es/core_concepts/state_management/#state)</HT>) como <HT>[`Signal`](/reactter/es/api/classes/signal)</HT> o cualquier <HT>[`Hooks`](/reactter/es/core_concepts/hooks)</HT> puede ser vinculado a la dependencia, permitiendo que el estado sea manipulado directamente desde la dependencia y notificar a sus oyentes sobre cualquier cambio.
15+
Además, asegura que el estado se elimine automáticamente cuando la dependencia ya no sea necesaria.
16+
17+
Al integrar el estado directamente dentro de las dependencias, se beneficia de un **código más limpio** y **mantenible**.
18+
El manejo automático por parte de Reactter significa **menos código repetitivo** y **menos errores* relacionados con la gestión manual del estado, lo que conduce a un proceso de desarrollo más eficiente.
19+
Este enfoque **simplifica** la sincronización entre el estado y su dependencia asociada, **mejorando la capacidad de respuesta** y la **fiabilidad** general de su aplicación.
20+
21+
### Vinculación automática
22+
23+
Para que esto suceda automáticamente, el estado debe declararse como propiedad o dentro del constructor de la dependencia.
24+
Cuando se hace esto, Reactter se encarga automáticamente de vincular el estado a la dependencia, asegurando una gestión y reactividad del estado sin problemas, por ejemplo:
25+
26+
```dart title="count_controller.dart" "UseState" "UseEffect"
27+
import "package:reactter/reactter.dart";
28+
29+
class CountController {
30+
// Estado declarado como propiedad
31+
final uCount = UseState(0);
32+
33+
CountController() {
34+
// Estado declarado dentro del constructor
35+
UseEffect(() {
36+
print("Count: ${uCount.value}");
37+
}, [uCount]);
38+
}
39+
}
40+
```
41+
42+
En el ejemplo anterior, el estado `uCount` se declara como propiedad de la clase <HT>`CountController`</HT> y el hook <HT>`UseEffect`</HT> se utiliza dentro del constructor para reaccionar a los cambios en el estado `uCount`, imprimiendo su valor cada vez que cambia.
43+
Esto vincula automáticamente el estado `uCount` y el hook <HT>`UseEffect`</HT> a la instancia de <HT>`CountController`</HT>, demostrando cómo Reactter maneja la vinculación y reactividad de forma transparente.
44+
45+
:::caution
46+
Si el estado se declara de forma perezosa (por ejemplo, utilizando la palabra clave <HK>`late`</HK>), no se vinculará automáticamente a la dependencia.
47+
En tales casos, debes usar el método <HT>`Rt.lazyState`</HT> para vincular el estado a la dependencia(Ver [vinculación perezoso](#vinculación-perezosa)).
48+
:::
49+
50+
### Vinculación perezosa
51+
52+
Cuando un estado se declara de forma perezosa, no se vincula automáticamente a la dependencia.
53+
En tales casos, puedes usar el método <HT>[`Rt.lazyState`](/reactter/es/api/methods/state_management_methods/#rtlazy_state)</HT> para vincular el estado a la dependencia, por ejemplo:
54+
55+
```dart title="count_controller.dart" "UseState" "Rt.lazyState"
56+
import "package:reactter/reactter.dart";
57+
58+
class CountController {
59+
final int initialCount;
60+
61+
late final uCount = Rt.lazyState(
62+
() => UseState(this.initialCount),
63+
this,
64+
);
65+
66+
CountController([this.initialCount = 0]) {
67+
UseEffect(() {
68+
print("Count: ${uCount.value}");
69+
}, [uCount]);
70+
}
71+
}
72+
```
73+
74+
En el ejemplo anterior, el estado `uCount` se declara de forma perezosa utilizando la palabra clave <HK>`late`</HK>.
75+
Para vincular el estado a la instancia de <HT>`CountController`</HT>, se utiliza el método <HT>[`Rt.lazyState`](/reactter/es/api/methods/state_management_methods/#rtlazy_state)</HT>, pasando la función de creación del estado y la instancia de la dependencia como argumentos.
76+
Esto asegura que cuando se accede a `uCount`, se vinculará automáticamente a la instancia de <HT>`CountController`</HT>.
77+
78+
### Vinculación manual
79+
80+
Si bien la vinculación automática simplifica la gestión del estado, puede haber escenarios en los que necesites vincular manualmente el estado a una dependencia.
81+
La vinculación manual proporciona un mayor control sobre cómo y cuándo se asocia el estado con la dependencia.
82+
83+
Para vincular manualmente un estado a una dependencia, debes vincular explícitamente el estado dentro de la dependencia utilizando el método <HM>`bind`</HM> del estado, por ejemplo:
84+
85+
```dart title="count_controller.dart" "UseState" "bind"
86+
class CountController {
87+
late final uCount = UseState(this.initialCount);
88+
89+
final int initialCount;
90+
91+
CountController([this.initialCount = 0]) {
92+
count.bind(this);
93+
}
94+
}
95+
```
96+
97+
En el ejemplo anterior, el estado `uCount` se declara de forma perezosa utilizando la palabra clave <HK>`late`</HK>.
98+
Para vincular el estado a la instancia de <HT>`CountController`</HT>, se utiliza el método <HM>`bind`</HM> del estado, pasando la instancia de la dependencia como argumento.
99+
Esto asegura que el estado `uCount` esté asociado a la instancia de <HT>`CountController`</HT>, lo que permite que la dependencia actualice reactivamente en función de los cambios en el estado.
100+
101+
:::note
102+
La [vinculación manual](#vinculación-manual) y [vinculación perezosa](#vinculación-perezosa) tienen propositos diferentes.
103+
La vinculación manual es útil cuando se necesita un control preciso sobre el proceso de vinculación de estados, mientras que la **vinculación perezosa** es adecuada cuando se desea que el estado se inicialice sólo cuando se accede a él por primera vez.
104+
Elige el método adecuado en función de tus necesidades específicas.
105+
:::
106+
107+
### Desvinculación automática
108+
109+
Cuando se elimina una dependencia, el estado asociado se elimina automáticamente.
110+
Este mecanismo de desvinculación automática simplifica la gestión de estados y reduce el riesgo de fugas de memoria o desperdicio de recursos.
111+
112+
En el ejemplo siguiente, el estado `uCount` se elimina automáticamente cuando se borra la instancia <HT>`CountController`</HT>, lo que garantiza que los recursos se liberan de forma eficiente:
113+
114+
```dart title="main.dart" "Rt.create" "Rt.delete"
115+
import "./count_controller.dart";
116+
117+
void main() {
118+
final controller = Rt.create(() => CountController(10));
119+
controller.uCount.value += 2; // Count: 12
120+
Rt.delete<CountController>();
121+
controller.uCount.value += 3; // Error: "Can't update when it's been disposed"
122+
}
123+
```
124+
125+
### Desvinculación manual
126+
127+
En algunos casos, puede que necesites desvincular manualmente un estado de una dependencia.
128+
La desvinculación manual proporciona un mayor control sobre cuándo se libera el estado y puede ser útil en escenarios en los que se desea desvincular el estado de forma temporal o permanente.
129+
130+
Para desvincular manualmente un estado de una dependencia, puedes utilizar el método <HM>`unbind`</HM> del estado, por ejemplo:
131+
132+
```dart title="count_controller.dart" "UseState" "unbind"
133+
class CountController {
134+
late final uCount = UseState(this.initialCount);
135+
136+
final int initialCount;
137+
138+
CountController([this.initialCount = 0]) {
139+
count.bind(this);
140+
}
141+
142+
void dispose() {
143+
count.unbind(this);
144+
}
145+
}
146+
```
147+
148+
:::caution
149+
Aunque la desvinculación manual proporciona un mayor control, un uso inadecuado puede provocar problemas de gestión de memoria y aumentar el riesgo de errores.
150+
Se recomienda utilizar la [desvinculación automática](#desvinculación-automática) siempre que sea posible, ya que simplifica el proceso y reduce la probabilidad de introducir fugas de memoria o de no liberar los recursos correctamente.
151+
152+
La desvinculación manual debe utilizarse con precaución y sólo cuando sea absolutamente necesario.
153+
Además, los desarrolladores deben asegurarse de realizar un seguimiento del proceso de desvinculación para evitar dejar estados no utilizados en memoria, lo que podría afectar negativamente al rendimiento y la utilización de recursos.
154+
:::
155+
156+
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
---
2+
title: Actualizar objectos en estado
3+
description: Aprende a actualizar objectos en estado de Reactter.
4+
---
5+
import { HM, HN, HS, HT } from '@/components/Highlight';
6+
7+
Un estado de Reactter(<HT>`RtState`</HT>) como <HT>`Signal`</HT>, <HT>`UseState`</HT>, <HT>`UseAsyncState`</HT>, <HT>`UseReducer`</HT> y <HT>`UseCompute`</HT> pueden contener cualquier tipo de valor de Dart, incluidos objetos.
8+
Sin embargo, no debes modificar los objetos contenidos en el estado de Reactter directamente.
9+
10+
En esta guía, aprenderás cómo actualizar objetos de forma segura y efectiva en un estado Reactter.
11+
12+
## ¿Qué es una mutación?
13+
14+
Puedes almacenar cualquier tipo de valor de Dart en el estado.
15+
16+
```dart showLineNumbers=false
17+
final count = Signal(0);
18+
```
19+
20+
Hasta ahora has estado trabajando con números, cadenas y booleanos.
21+
Estos tipos de valores de Dart son _**inmutables**_, lo que significa que no se pueden cambiar o son _**de solo lectura**_.
22+
Puedes desencadenar una nueva representación para reemplazar un valor:
23+
24+
```dart showLineNumbers=false
25+
count.value = 2;
26+
```
27+
28+
El estado `count` cambió de <HN>`0`</HN> a <HN>`2`</HN>, pero el número <HN>`0`</HN> en sí mismo no cambió.
29+
No es posible realizar cambios en los valores primitivos incorporados como números, cadenas y booleanos en Dart.
30+
31+
Ahora considera un objeto en un estado:
32+
33+
```dart showLineNumbers=false collapse={1-7}
34+
class User {
35+
String name;
36+
int age;
37+
38+
User({required this.name, required this.age});
39+
}
40+
41+
final user = Signal(User(name: "Jane Doe", age: 25));
42+
```
43+
44+
Tecnicamente, es posible cambiar el contenido del objeto en sí. Esto se llama una **mutación**:
45+
46+
```dart showLineNumbers=false
47+
user.value.name = "John Doe";
48+
```
49+
50+
Sin embargo, aunque los objetos en el estado de Reactter son técnicamente mutables, debes tratarlos como si fueran inmutables, como números, booleanos y cadenas.
51+
En lugar de mutarlos, siempre debes reemplazarlos.
52+
53+
## Tratar el estado como de solo lectura
54+
55+
En otras palabras, debes tratar cualquier objeto de Dart que pongas en el estado como de solo lectura.
56+
57+
El siguiente ejemplo mantiene un objeto en el estado para representar al usuario.
58+
El nombre del usuario se cambia de <HS>`"Jane Doe"`</HS> a <HS>`"John Doe"`</HS> cuando haces clic en el botón,
59+
pero el nombre del usuario sigue siendo el mismo.
60+
61+
```dart title="main.dart" "Signal" "User" "RtSignalWatcher" "user.value.name" "user.value.age" "user" mark={31}
62+
import 'package:flutter/material.dart';
63+
import 'package:reactter/reactter.dart';
64+
65+
void main() {
66+
runApp(MyApp());
67+
}
68+
69+
class User {
70+
String name;
71+
int age;
72+
73+
User({required this.name, required this.age});
74+
}
75+
76+
final user = Signal(User(name: "Jane Doe", age: 25));
77+
78+
class MyApp extends StatelessWidget {
79+
@override
80+
Widget build(BuildContext context) {
81+
return MaterialApp(
82+
home: Scaffold(
83+
appBar: AppBar(title: Text("Inmutable state example")),
84+
body: Center(
85+
child: RtSignalWatcher((){
86+
return Column(
87+
children: [
88+
Text('Name: ${user.value.name}'),
89+
Text('Age: ${user.value.age}'),
90+
ElevatedButton(
91+
onPressed: () {
92+
user.value.name = "John Doe";
93+
},
94+
child: Text("Change Name"),
95+
),
96+
],
97+
);
98+
}),
99+
),
100+
),
101+
);
102+
}
103+
}
104+
```
105+
106+
El problema está en este fragmento de código.
107+
108+
```dart startLineNumber=24
109+
user.value.name = "John Doe";
110+
```
111+
112+
Este código modifica el objeto asignado a un nuevo `name` cuando se hace clic en el botón
113+
pero no desencadena un nuevo renderizado porque el objeto en sí no ha cambiado.
114+
La propiedad `name` del objeto ha cambiado, pero el objeto en sí no lo ha hecho.
115+
Y Reactter no sabe que el objeto ha cambiado porque sigue siendo el mismo objeto.
116+
Aunque la mutación del estado puede funcionar en algunos casos, no lo recomendamos.
117+
Debes tratar el valor de estado al que tienes acceso como de solo lectura.
118+
119+
Para desencadenar un nuevo renderizado en este caso, crea un nuevo objeto y pásalo a la función de configuración del estado:
120+
121+
```dart startLineNumber=24
122+
user.value = User(name: "John Doe", age: user.value.age);
123+
```
124+
125+
Cunado `value` se establece en un nuevo objeto, Reactter sabe que el estado ha cambiado y desencadena un nuevo renderizado.
126+
127+
## Copiar objetos
128+
129+
En el ejemplo anterior, creaste un nuevo objeto con el mismo `age` y un `name` diferente.
130+
Pero ¿qué pasa si quieres cambiar el `age` y mantener el `name` igual?. También puedes hacerlo:
131+
132+
```dart showLineNumbers=false
133+
user.value = User(name: user.value.name, age: 30);
134+
```
135+
136+
Esto es un patrón común cuando trabajas con objetos en el estado.
137+
Sin embargo, crear un nuevo objeto cada vez que quieras cambiar una propiedad puede ser tedioso.
138+
Para simplificar este proceso, puedes agregar el siguiente método(<HM>`copyWith`</HM>) a la clase <HT>`User`</HT>:
139+
140+
```dart collapse={2-6} ins="final" ins={7-13} mark={2-3} mark="copyWith"
141+
class User {
142+
final String name;
143+
final int age;
144+
145+
const User({required this.name, required this.age});
146+
147+
User copyWith({String? name, int? age}) {
148+
return User(
149+
name: name ?? this.name,
150+
age: age ?? this.age,
151+
);
152+
}
153+
}
154+
```
155+
156+
Este método crea un nuevo objeto con las mismas propiedades que el objeto original, excepto por las propiedades que especifiques.
157+
Puedes usar este método para crear un nuevo objeto con el mismo `name` y un `age` diferente:
158+
159+
```dart showLineNumbers=false ".copyWith"
160+
user.value = user.value.copyWith(age: 30);
161+
```
162+
163+
## Resumen
164+
165+
- Trata los objetos en el estado como de solo lectura.
166+
- Cuando necesites actualizar un objeto, crea uno nuevo o haz una copia del objeto existente, y luego establece el estado para usar este nuevo o copiado objeto.
167+
- Evita mutar objetos en el estado directamente.
168+
- Crea un nuevo objeto y pásalo a la función de configuración del estado para desencadenar un nuevo renderizado.
169+
- Usa el método <HM>`copyWith`</HM> para crear un nuevo objeto con las mismas propiedades que el objeto original, excepto por las propiedades que especifiques.

website/src/content/docs/es/overview.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Esto ha dado lugar a una amplia variedad de paquetes de gestión de estado, cada
1111

1212
**Reactter** nació del deseo de crear algo diferente, una solución de gestión de estados que no se limita a resolver problemas, sino que eleva toda la experiencia de desarrollo.
1313
Inspirado en la simplicidad y reactividad de ReactJS, Reactter aporta un enfoque fresco y moderno al desarrollo con Dart y Flutter.
14-
No es sólo otro paquete de gestión de estado, es un framework completo, diseñado para hacer su aplicación más rápida, su código más limpio y su vida como desarrollador más fácil.
14+
No es sólo otro paquete de gestión de estado, es una herramienta potente, diseñado para hacer su aplicación más rápida, su código más limpio y su vida como desarrollador más fácil.
1515

1616
¿Qué diferencia a Reactter? Mientras que otros paquetes se centran únicamente en la gestión de estados, Reactter va más allá integrando a la perfección **inyección de dependencias**, **manejo de eventos** y **control de renderizado** en un único framework cohesionado.
1717
Es ligero pero potente, sencillo pero flexible, y está diseñado para funcionar a la perfección con cualquier arquitectura o patrón.

website/src/content/docs/es/shareds/state_methods.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Cuando se invoca, emite dos eventos [lifecycle](/reactter/es/core_concepts/lifec
1111
A diferencia de <HM>`update`</HM>, sólo emite el evento <HE>`Lifecycle.didUpdate`</HE>, ya que no implica ningún paso previo a la notificación.
1212
- <HM>**`bind`**</HM>: Establece una conexión entre el estado y una instancia específica.
1313
Esta conexión permite a la instancia actualizarse de forma reactiva en función de los cambios en el estado.
14-
Al vincular el estado, la instancia se da cuenta de los cambios en el estado y puede reflejar adecuadamente esos cambios en su comportamiento.
14+
Al vincular el estado, la instancia es notificado de los cambios en el estado y puede reflejar adecuadamente esos cambios en su comportamiento.
1515
- <HM>**`unbind`**</HM>: Libera la conexión entre el estado y la instancia.
1616
Al desvincularse, la instancia dejará de recibir actualizaciones del estado.
1717
Esto puede ser útil cuando una instancia ya no está utilizando activamente el estado o cuando necesita desvincularse del estado temporal o permanentemente.
@@ -20,5 +20,5 @@ Disponer del estado garantiza que se libere correctamente y que ya no consuma me
2020

2121
:::note
2222
Mientras que los métodos <HM>`bind`</HM>, <HM>`unbind`</HM> y <HM>`dispose`</HM> se utilizan normalmente para gestionar el [ciclo de vida](/reactter/es/core_concepts/lifecycle) de un estado,
23-
Reactter maneja esto automáticamente, cuando el estado es declarado dentro de una instancia que existe dentro del contexto de Reactter vía [dependecy injection](/reactter/es/core_concepts/dependency_injection/), por lo que no necesitas preocuparte por ello(Learn more about [Binding State to Dependency](/reactter/es/extra_topics/binding_state_to_dependency/)).
23+
Reactter maneja esto automáticamente, cuando el estado es declarado dentro de una instancia que existe dentro del contexto de Reactter vía [dependecy injection](/reactter/es/core_concepts/dependency_injection/), por lo que no necesitas preocuparte por ello(Apendas más acerca de la [vinculación del estado a la dependencia](/reactter/es/extra_topics/binding_state_to_dependency/)).
2424
:::

0 commit comments

Comments
 (0)