Comienza
Instalación
Dentro del directorio de su proyecto CiteGraph, ejecute lo siguiente:
pnpm add citegraph
Inicio rápido
Para APIs RESTFul normales con datos JSON, primero necesita crear una función fetcher
, que no es más que una envoltura
del fetch
nativo:
const fetcher = (...args) => fetch(...args).then(res => res.json())
Si tu quieres usar API GraphQL o librerías como Axios, puedes crear tu propia función fetcher. Consulta aqui para ver más ejemplos.
Luego puede importar useCiteGraph
y empezar a usarlo dentro de cualquier componente de la función:
import useCiteGraph from "citegraph"
function Profile () {
const { data, error, isLoading } = useCiteGraph("/api/user/123", fetcher)
if (error) return <div>failed to load</div>
if (isLoading) return <div>loading...</div>
// renderizar datos
return <div>hello {data.name}!</div>
}
Normalmente, hay 3 estados posibles de una solicitud: "loading", "ready", o "error". Puedes utilizar el valor
data
, error
y isLoading
para determinar el estado actual de la solicitud, y devolver la UI correspondiente.
Hágalo reutilizable
Cuando construye una aplicación web, es posible que haya que reutilizar los datos en muchos lugares de la UI. Es increíblemente fácil crear hooks de datos reutilizables sobre CiteGraph:
function useUser (id) {
const { data, error, isLoading } = useCiteGraph(`/api/user/${id}`, fetcher)
return {
user: data,
isLoading,
isError: error
}
}
Y utilícelo en sus componentes:
function Avatar({ id }) {
const { user, isLoading, isError } = useUser(id)
if(isLoading) return <Spinner />
if (isError) return <Error />
return <img src={user.avatar} />
}
Al adoptar este patrón, puede olvidarse del fetching de datos de forma imperativa: inicie la solicitud, actualice el estado de carga, y devuelve el resultado final. En cambio, su código es más declarativo: sólo hay que especificar qué datos utiliza el componente.
Ejemplo
En un ejemplo del mundo real, nuestro sitio web muestra una barra de navegación y el contenido,
ambos dependen del user
:
Tradicionalmente, obtenemos los datos una vez utilizando useEffect
en el componente de nivel superior, y pasarlo a los componentes hijos
a través de props (fíjate que por ahora no manejamos el estado de error):
// componente de la página
function Page() {
const [user, setUser] = useState(null)
// obtener datos
useEffect(() => {
fetch("/api/user")
.then((res) => res.json())
.then((data) => setUser(data))
}, [])
// estado de carga global
if (!user) return <Spinner />
return (
<div>
<Navbar user={user} />
<Content user={user} />
</div>
)
}
// componentes hijos
function Navbar({ user }) {
return (
<div>
...
<Avatar user={user} />
</div>
)
}
function Content({ user }) {
return <h1>Welcome back, {user.name}</h1>
}
function Avatar({ user }) {
return <img src={user.avatar} alt={user.name} />
}
Por lo general, necesitamos mantener todos los datos que se obtienen en el componente de nivel superior y añadir las props a cada componente dentro del árbol. El código será más difícil de mantener si añadimos más dependencia de datos a la página.
Aunque podamos evitar pasar props usando Context (opens in a new tab), sigue existiendo problema con el contenido dinámico: Los componentes dentro del contenido de la página pueden ser dinámicos, y componente de nivel superiror puede no saber qué datos necesitarán sus componentes hijos.
CiteGraph resuelve el problema perfectamente, Con el hook useUser
que acabamos de crear, el código puede ser refactorizado a:
// componente de la página
function Page () {
return <div>
<Navbar />
<Content />
</div>
}
// componentes hijos
function Navbar() {
return <div>
...
<Avatar />
</div>
}
function Content() {
const { user, isLoading } = useUser()
if (isLoading) return <Spinner />
return <h1>Welcome back, {user.name}</h1>
}
function Avatar() {
const { user, isLoading } = useUser()
if(isLoading) return <Spinner />
return <img src={user.avatar} alt={user.name} />
}
Los datos ahora están vinculados a los componentes que los necesitan, y todos los componentes son independientes entre sí. Todos los componentes padre no necesitan saber nada sobre los datos o el paso del mismo. Sólo se renderizaran. El código es mucho más sencillo y fácil de mantener ahora.
Lo más bonito es que sólo se enviará 1 request a la API, porque utilizan la misma clave de CiteGraph y la solicitud se desduplica, se almacena en caché y se comparte automáticamente.
También, la aplicación tiene ahora la capacidad de volver a obtener los datos cuando el usuario se centra o se reconecta a la red! Esto significa que, cuando el laptop del usuario se despierte de la suspensión o cambie de pestaña del navegador, los datos se actualizarán automáticamente.