UNPKG

atomico

Version:

Atomico is a small library for the creation of interfaces based on web-components, only using functions and hooks.

345 lines (248 loc) 8.92 kB
# Hooks La 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. 1. core 1. [useState](#usestate) 2. [useEffect](#useeffect) 3. [useMemo](#usememo) 4. [useRef](#useref) 5. [useProp](#useprop) 2. atomico/lazy 1. [useLazy](#uselazy) 3. atomico/router 1. [useRouter](#userouter) 2. [useRoute](#useroute) 3. [useRedirect](#useredirect) 4. atomico/use-state-generator 1. [useStateGenerator](#usestategenerator) ## useState crea un estado local en el web-component ```jsx let [state, setState] = useState(initialState); ``` Donde : * `state` es el estado actual del hook. * `setState` es una función que modifica el estado actual. > **De ser función** será ejecutada recibiendo como argumento el estado actual para retornar el siguiente estado * `initialState` es el estado inicial > **De ser función** será ejecutada para retornar el estado inicial #### Ejemplo ```jsx let [count, setCount] = useState(0); function increment() { setCount(count + 1); } <host> count : {count} <button onclick={increment}>increment</button> </host>; ``` Donde : * `count` es el estado actual, inicializando en `0` * `increment` es el actualizador de estado mediante el uso de `setCount` ## useEffect crea un efecto secundario asociado al ciclo de render, útil para controlar efectos que interactúen con el DOM o asincronía ```jsx function afterRender() { console.log("after render"); return beforeNewRender; } function beforeNewRender() { console.log("new render"); } useEffect(afterRender, optionalArgument); ``` Donde: * `afterRender` es una función que se ejecuta después del render asociado al hook * `beforeNewRender` es el retorno de la funcion `afterRender` y esta sera ejecutada solo si se genera un nuevo render o se desmonta el hook Considere 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: #### Ejemplo ```jsx let [route, setRoute] = useState(location.pathname); useEffect(() => { function handler() { setRoute(location.pathname); } window.addEventListener("popstate", handler); return () => window.removeEventListener("popstate", handler); }, []); ``` En 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. ## useMemo memoriza el retorno de un callback limitando su ejecución mediante un array de argumentos, este se ejecuta en el momento del render ```jsx let data = useMemo( () => { for (let i = 0; i < length; i++) { data.push({ key: i, ...placeholder }); } }, [length] ); ``` ## useRef permite crear una referencia que se mantiene mutable entre renders. ```js let ref = useRef(optionalCurrent); ``` Donde: * `ref` es un objeto que no muta entre renders * `opcionalCurrent` es el estado inicial de la propiedad `ref.current` #### Ejemplo ```jsx let ref = useRef(); useEffect( () => { ref.current.addEventListener("click", ({ target }) => { console.log({ target }); }); }, [ref] ); <host> <button ref={ref}> click </button> </host>; ``` El 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. ## useProp accede a una propiedad(props) previamente declarada sobre el contenedor(web-component), **permitiendo manipular desde el ciclo de render el estado de estas propiedades**. ```jsx let [value, setValue] = useProp(propName); ``` Donde : * `value` es el estado actual de la propiedad asociada al web-component * `setValue` es una función encargada de actualizar el estado * `propsName` es el nombre de la propiedad a modificar por `useProp` #### Ejemplo ```jsx let [count, setCount] = useProp("count"); <host> count : {count} <button onclick={() => setCount(count + 1)}>increment</button> </host>; ``` Ante 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` # atomico/lazy ```jsx import { useLazy } from "atomico/lazy"; ``` ## useLazy crea un nodo asíncrono ideal para el uso de import o request. #### Ejemplo dinamic import ```jsx let UiHeader = useLazy(() => import("./src/web-components/ui-header/ui-header") ); return ( <host> <UiHeader loading="...loading" /> </host> ); ``` #### Ejemplo request ```jsx let UiItems = useLazy(async () => { let request = await fetch(`https://jsonplaceholder.typicode.com/posts`); let data = await request.json(); return data.map(({ body }) => <div>{body}</div>); }); return ( <host> <UiItems loading="...loading" /> </host> ); ``` > El nodo que retorna useLazy posee 2 propiedades `loading` y `error`, las que pueden una función o un nodo virtual #### Ejemplo 2 argumento El segundo argumento en para `useLazy`, permite regenerar el efecto de lazy, de forma similar a lo que ocurre con `useEffect`. ```jsx let [id, setId] = useState(1); let User = useLazy( async () => { let request = await fetch( `https://jsonplaceholder.typicode.com/users/${id}` ); let data = await request.json(); return ( <ul> <li>username : {data.username}</li> <li>email : {data.email}</li> </ul> ); }, [id] ); return ( <host> <button onclick={() => setState(0)}>user 1</button> <button onclick={() => setState(1)}>user 1</button> <button onclick={() => setState(2)}>user 2</button> <User loading={`...loading user ${id}`} /> </host> ); ``` [Ejemplo](https://codepen.io/uppercod/pen/BaaMORB?editors=1010) # atomico/router ```js import { useRouter, useRoute, useRedirect } from "atomico/router"; ``` ## useRouter define desde un objeto la vista actual a utilizar a base de la ruta actual ```jsx let paths = { "/": () => <WebComponentHome />, "/user/:id": ({ id }) => <WebComponentUser id={id} />, default: <h1>404</h1> }; let View = useRouter(paths); ``` Donde : * `paths` objeto que define las expreciones para que `useRouter` realize la comprovacion que define a `View` * `View` es el retorno de la expresión asociada a `paths`. ## useRoute define si una ruta esta activa y optiene los parametros de esta ```jsx let [inRoute, paramsRoute] = useRoute("/:id?"); ``` Donde : * `inRoute` **Booleano** que defin cvv xc cv e si la expresión concuerda con la expresión dada a `useRoute`. * `paramsRoute` **Objeto** que define los parámetros capturados por la expresión dada a `useRoute`. #### Comodines de useRoute y useRouter | Comodin | descripcion | | ---------- | ------------------------- | | `/static` | Ruta requerida | | `/:id` | parámetros obligatorio | | `/:id?` | parámetro opcional | | `/:any...` | parámetro opcional spread | ## useRedirect ```jsx let goHome = useRedirect("/"); ``` # atomico/use-state-generator ```js import { useStateGenerator, delay } from "atomico/use-state-generator"; ``` ## useStateGenerator Este 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. ```jsx let [state, promise] = useStateGenerator(callbackGenerator, initialState, vars); ``` Donde : * `state` es el estado actual del hook. * `promise` es una promesa que define si el proceso asincrono de `useStateGenerator` ha finalizado. * `callbackGenerator` es una funcion sea asincrona, generador o generador asincrono a consumir por `useStateGenerator`. * `initialState`, estado inicial del hook. * `vars` es un array de variables a observar entre renders, de ser distinto uno de estos elementos regenera el hook ejecutando nuevamente `callbackGenerator`. #### Ejemplo ```jsx import { useStateGenerator, delay} /** inside web-component */ let length = 10; let [state] = useStateGenerator((state)=>{ while(--state){ yield delay(1000); yield state; } return state; },0, [length]) ``` El ejemplo anterior genera una cuenta regresiva de 10..1, cada paso es de 1000ms.