UNPKG

8.92 kBMarkdownView Raw
1# Hooks
2
3La sintaxis de Atomico se basa en la experiencia funcional heredada de React, Atomico aplica este comportamiento funcional para crear web-components con un código legible, sostenible y simple ... Gracias React.
4
51. core
6 1. [useState](#usestate)
7 2. [useEffect](#useeffect)
8 3. [useMemo](#usememo)
9 4. [useRef](#useref)
10 5. [useProp](#useprop)
112. atomico/lazy
12 1. [useLazy](#uselazy)
133. atomico/router
14 1. [useRouter](#userouter)
15 2. [useRoute](#useroute)
16 3. [useRedirect](#useredirect)
174. atomico/use-state-generator
18 1. [useStateGenerator](#usestategenerator)
19
20## useState
21
22crea un estado local en el web-component
23
24```jsx
25let [state, setState] = useState(initialState);
26```
27
28Donde :
29
30* `state` es el estado actual del hook.
31
32* `setState` es una función que modifica el estado actual.
33
34 > **De ser función** será ejecutada recibiendo como argumento el estado actual para retornar el siguiente estado
35
36* `initialState` es el estado inicial
37
38 > **De ser función** será ejecutada para retornar el estado inicial
39
40#### Ejemplo
41
42```jsx
43let [count, setCount] = useState(0);
44
45function increment() {
46 setCount(count + 1);
47}
48
49<host>
50 count : {count}
51 <button onclick={increment}>increment</button>
52</host>;
53```
54
55Donde :
56
57* `count` es el estado actual, inicializando en `0`
58* `increment` es el actualizador de estado mediante el uso de `setCount`
59
60## useEffect
61
62crea un efecto secundario asociado al ciclo de render, útil para controlar efectos que interactúen con el DOM o asincronía
63
64```jsx
65function afterRender() {
66 console.log("after render");
67 return beforeNewRender;
68}
69
70function beforeNewRender() {
71 console.log("new render");
72}
73
74useEffect(afterRender, optionalArgument);
75```
76
77Donde:
78
79* `afterRender` es una función que se ejecuta después del render asociado al hook
80* `beforeNewRender` es el retorno de la funcion `afterRender` y esta sera ejecutada solo si se genera un nuevo render o se desmonta el hook
81
82Considere que en el ejemplo las funciones se separan para definir su uso, se recomienda que el callback de retorno siempre exista dentro de la función que requiere useEffect, ya que el objetivo es la limpieza de eventos que se generan en el scope ejecución del hook, como se enseña en el siguiente ejemplo:
83
84#### Ejemplo
85
86```jsx
87let [route, setRoute] = useState(location.pathname);
88
89useEffect(() => {
90 function handler() {
91 setRoute(location.pathname);
92 }
93 window.addEventListener("popstate", handler);
94 return () => window.removeEventListener("popstate", handler);
95}, []);
96```
97
98En el ejemplo useEffect se ejecutara solo una vez indiferente a la cantida de actualizaciones asociada, siendo esto de utilidad para la suscripción de eventos externos al hook.
99
100## useMemo
101
102memoriza el retorno de un callback limitando su ejecución mediante un array de argumentos, este se ejecuta en el momento del render
103
104```jsx
105let data = useMemo(
106 () => {
107 for (let i = 0; i < length; i++) {
108 data.push({ key: i, ...placeholder });
109 }
110 },
111 [length]
112);
113```
114
115## useRef
116
117permite crear una referencia que se mantiene mutable entre renders.
118
119```js
120let ref = useRef(optionalCurrent);
121```
122
123Donde:
124
125* `ref` es un objeto que no muta entre renders
126* `opcionalCurrent` es el estado inicial de la propiedad `ref.current`
127
128#### Ejemplo
129
130```jsx
131let ref = useRef();
132
133useEffect(
134 () => {
135 ref.current.addEventListener("click", ({ target }) => {
136 console.log({ target });
137 });
138 },
139 [ref]
140);
141
142<host>
143 <button ref={ref}> click </button>
144</host>;
145```
146
147El en ejemplo la variable `ref` se entrega al virtual-dom, este definirá en el momento de la renderizacion el nodo como `ref.current`, permitiendo acceder a este después del render.
148
149## useProp
150
151accede a una propiedad(props) previamente declarada sobre el contenedor(web-component), **permitiendo manipular desde el ciclo de render el estado de estas propiedades**.
152
153```jsx
154let [value, setValue] = useProp(propName);
155```
156
157Donde :
158
159* `value` es el estado actual de la propiedad asociada al web-component
160* `setValue` es una función encargada de actualizar el estado
161* `propsName` es el nombre de la propiedad a modificar por `useProp`
162
163#### Ejemplo
164
165```jsx
166let [count, setCount] = useProp("count");
167
168<host>
169 count : {count}
170 <button onclick={() => setCount(count + 1)}>increment</button>
171</host>;
172```
173
174Ante cada cambio de count ud podrá leer estos cambios mediante la propiedad count asociada al nodo del DOM asociada al web-component, ej `nodeWebComponent.count`
175
176# atomico/lazy
177
178```jsx
179import { useLazy } from "atomico/lazy";
180```
181
182## useLazy
183
184crea un nodo asíncrono ideal para el uso de import o request.
185
186#### Ejemplo dinamic import
187
188```jsx
189let UiHeader = useLazy(() =>
190 import("./src/web-components/ui-header/ui-header")
191);
192
193return (
194 <host>
195 <UiHeader loading="...loading" />
196 </host>
197);
198```
199
200#### Ejemplo request
201
202```jsx
203let UiItems = useLazy(async () => {
204 let request = await fetch(`https://jsonplaceholder.typicode.com/posts`);
205 let data = await request.json();
206 return data.map(({ body }) => <div>{body}</div>);
207});
208
209return (
210 <host>
211 <UiItems loading="...loading" />
212 </host>
213);
214```
215
216> El nodo que retorna useLazy posee 2 propiedades `loading` y `error`, las que pueden una función o un nodo virtual
217
218#### Ejemplo 2 argumento
219
220El segundo argumento en para `useLazy`, permite regenerar el efecto de lazy, de forma similar a lo que ocurre con `useEffect`.
221
222```jsx
223let [id, setId] = useState(1);
224
225let User = useLazy(
226 async () => {
227 let request = await fetch(
228 `https://jsonplaceholder.typicode.com/users/${id}`
229 );
230 let data = await request.json();
231
232 return (
233 <ul>
234 <li>username : {data.username}</li>
235 <li>email : {data.email}</li>
236 </ul>
237 );
238 },
239 [id]
240);
241
242return (
243 <host>
244 <button onclick={() => setState(0)}>user 1</button>
245 <button onclick={() => setState(1)}>user 1</button>
246 <button onclick={() => setState(2)}>user 2</button>
247 <User loading={`...loading user ${id}`} />
248 </host>
249);
250```
251
252[Ejemplo](https://codepen.io/uppercod/pen/BaaMORB?editors=1010)
253
254# atomico/router
255
256```js
257import { useRouter, useRoute, useRedirect } from "atomico/router";
258```
259
260## useRouter
261
262define desde un objeto la vista actual a utilizar a base de la ruta actual
263
264```jsx
265let paths = {
266 "/": () => <WebComponentHome />,
267 "/user/:id": ({ id }) => <WebComponentUser id={id} />,
268 default: <h1>404</h1>
269};
270let View = useRouter(paths);
271```
272
273Donde :
274
275* `paths` objeto que define las expreciones para que `useRouter` realize la comprovacion que define a `View`
276* `View` es el retorno de la expresión asociada a `paths`.
277
278## useRoute
279
280define si una ruta esta activa y optiene los parametros de esta
281
282```jsx
283let [inRoute, paramsRoute] = useRoute("/:id?");
284```
285
286Donde :
287
288* `inRoute` **Booleano** que defin cvv xc cv e si la expresión concuerda con la expresión dada a `useRoute`.
289
290* `paramsRoute` **Objeto** que define los parámetros capturados por la expresión dada a `useRoute`.
291
292#### Comodines de useRoute y useRouter
293
294| Comodin | descripcion |
295| ---------- | ------------------------- |
296| `/static` | Ruta requerida |
297| `/:id` | parámetros obligatorio |
298| `/:id?` | parámetro opcional |
299| `/:any...` | parámetro opcional spread |
300
301## useRedirect
302
303```jsx
304let goHome = useRedirect("/");
305```
306
307# atomico/use-state-generator
308
309```js
310import { useStateGenerator, delay } from "atomico/use-state-generator";
311```
312
313## useStateGenerator
314
315Este hook permite consumir generadores o funciones asíncronas para definir un estado, este consumo es recursivo por lo que ud puede usarlo para streaming complejos de data y concurrencia.
316
317```jsx
318let [state, promise] = useStateGenerator(callbackGenerator, initialState, vars);
319```
320
321Donde :
322
323* `state` es el estado actual del hook.
324* `promise` es una promesa que define si el proceso asincrono de `useStateGenerator` ha finalizado.
325* `callbackGenerator` es una funcion sea asincrona, generador o generador asincrono a consumir por `useStateGenerator`.
326* `initialState`, estado inicial del hook.
327* `vars` es un array de variables a observar entre renders, de ser distinto uno de estos elementos regenera el hook ejecutando nuevamente `callbackGenerator`.
328
329#### Ejemplo
330
331```jsx
332import { useStateGenerator, delay}
333/** inside web-component */
334let length = 10;
335let [state] = useStateGenerator((state)=>{
336 while(--state){
337 yield delay(1000);
338 yield state;
339 }
340 return state;
341},0, [length])
342```
343
344El ejemplo anterior genera una cuenta regresiva de 10..1, cada paso es de 1000ms.