-
Notifications
You must be signed in to change notification settings - Fork 353
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
I18n: Spanish #96
I18n: Spanish #96
Changes from all commits
8f285a3
7fe8519
8e624c5
893b392
788d32e
696170d
4e1be87
7ff4b05
ae40d46
d1acda9
3abcbae
fb617fa
5ac2acd
2fbee14
8bdea32
5b517e4
ac2e56a
3bd3c43
9d3e05d
cbfd5b5
08187bb
8eef89b
dc5c371
86a190d
afda561
fc12bec
4f7f6fb
cfe020b
ce9158f
794afc4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"performance": "Rendimiento" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
# Rendimiento | ||
|
||
SWR proporciona una funcionalidad crítica en todo tipo de aplicaciónes web, por lo que el **rendimiento** | ||
es una prioridad absoluta. | ||
|
||
SWR’s tiene **caché** incorporado y la **[deduplicación](/advanced/performance#deduplication)** evitan las solicitudes de red innecesarias, | ||
pero el rendimiento del propio hook `useSWR` sigue siendo importante. En una aplicación compleja, puede haber cientos de llamadas `useSWR` | ||
en una solo página. | ||
|
||
SWR asegura que su aplicación tiene: | ||
|
||
- _no hay peticiones de red innecesarias_ | ||
- _no hay renderizado innecesarios_ | ||
- _no se importa código innecesario_ | ||
|
||
sin ningún cambio de código por su parte. | ||
|
||
## Deduplicación | ||
|
||
Es muy común reutilizar los hooks SWR en tu aplicación. Por ejemplo, una aplicación que muestra el avatar del usuario | ||
actual 5 veces: | ||
|
||
```jsx | ||
|
||
function useUser() { | ||
return useSWR('/api/user', fetcher) | ||
} | ||
|
||
function Avatar () { | ||
const { data, error } = useUser() | ||
if (error) return <Error /> | ||
if (!data) return <Spinner /> | ||
|
||
return <img src={data.avatar_url} /> | ||
} | ||
|
||
function App() { | ||
return <> | ||
<Avatar /> | ||
<Avatar /> | ||
<Avatar /> | ||
<Avatar /> | ||
<Avatar /> | ||
</> | ||
} | ||
|
||
``` | ||
|
||
Cada componente `<Avatar/>` tiene un hook `useSWR` en su interior. Dado que tienen el mismo key SWR y | ||
que se renderizan casi al mismo tiempo, **sólo se hará 1 solicitud de red**. | ||
|
||
Puedes reutilizar tus hooks de datos (como `useUser` en el ejemplo anterior) en todas partes, sin preocuparte por el rendimiento | ||
o las peticiones duplicadas. | ||
|
||
También existe la [opción `dedupingInterval`](/docs/options) para anular el intervalo de deduplicación por defecto. | ||
|
||
## Comparación profunda | ||
|
||
SWR por defecto tiene **deep compares** al cambio de datos. Si el valor de `data` no ha cambiado, no se | ||
activará una nueva renderización. | ||
|
||
También puede personalizar la función de comparación mediante la [opción `compare`](/docs/options) si quieres cambiar el comportamiento. | ||
Por ejemplo, algunas respuestas de la API devuelven una marca de tiempo del servidor que tal vez quiera excluir de la difusión de datos. | ||
|
||
## Coleción de dependencias | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. typo: colección |
||
|
||
`useSWR` devuelve 3 valores de **estado**: `data`, `error` y `isValidating` cada uno de ellos puede actualizarse de forma independientemente. | ||
Por ejemplo, si imprimimos esos valores dentro de un ciclo de vida completo de obtención de datos, será algo como esto: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good use of the plural to make it impersonal 👍 |
||
|
||
```jsx | ||
|
||
function App () { | ||
const { data, error, isValidating } = useSWR('/api', fetcher) | ||
console.log(data, error, isValidating) | ||
return null | ||
} | ||
|
||
``` | ||
|
||
En el peor de los casos (la primera solicitud falló, entonces el reitento fue exitoso), verá 4 líneas de registros: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. typo: reintento There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use 'entonces' as in 'then' not 'therefore'. "Si la primera solicitud falló, entonces el reintento fue exitoso" There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. verá is formal you. Let's use impersonal: "Se verán 4 líneas de registros" |
||
|
||
```js | ||
// console.log(data, error, isValidating) | ||
|
||
undefined undefined true // => start fetching | ||
undefined Error false // => end fetching, got an error | ||
undefined Error true // => start retrying | ||
Data undefined false // => end retrying, get the data | ||
``` | ||
|
||
Los cambios de estado tienen sentido. Pero eso también significa que nuestro componente se **renderizo 4 veces.** | ||
|
||
Si cambiamos nuestro componente para usar solo `data`: | ||
|
||
```jsx | ||
|
||
function App () { | ||
const { data } = useSWR('/api', fetcher) | ||
console.log(data) | ||
return null | ||
} | ||
``` | ||
|
||
La magia ocurre - ahora solo hay **2 rederizaciones**: | ||
|
||
```js | ||
// console.log(data) | ||
undefined // => hydration / initial render | ||
Data // => end retrying, get the data | ||
``` | ||
|
||
El mismo proceso ha ocurrido internamente, hubo un error de la primera solicitud, entonces tenemos los datos del reintento. | ||
Sin embargo, **SWR sólo actualiza los estados que utiliza el componente**, que ahora sólo es `data`. | ||
|
||
Si no utiliza siempre estos 3 estados, ya se está beneficiando de esta función. En [Vercel](https://vercel.com), esta optimización se | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "Si no se utilizan..." |
||
traduce en un 60% menos de repeticiones. | ||
|
||
## Tree Shaking | ||
|
||
El paquete SWR es [tree-shakeable](https://webpack.js.org/guides/tree-shaking) y no tiene efectos secundarios. | ||
Esto significa que si sólo importa `useSWR` core API, las APIs no utilizadas, como `useSWRInfinite`, no se incluirán en tu aplicación. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ... que si sólo se importa... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ... no se incluirán en la aplicación. |
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import Markdown from 'markdown-to-jsx' | ||
import { useSSG } from 'nextra/ssg' | ||
|
||
export const getStaticProps = ({ params }) => { | ||
return fetch('https://api.github.com/repos/vercel/swr/releases') | ||
.then(res => res.json()) | ||
// we keep the most recent 5 releases here | ||
.then(releases => ({ props: { ssg: releases.slice(0, 5) }, revalidate: 10 })) | ||
} | ||
|
||
export const ReleasesRenderer = () => { | ||
const releases = useSSG() | ||
return <Markdown>{ | ||
releases.map(release => { | ||
const body = release.body | ||
.replace(/'/g, "'") | ||
.replace(/@([a-zA-Z0-9_-]+)(?=(,| ))/g, '<a href="https://github.com/$1" target="_blank" rel="noopener">@$1</a>') | ||
return `## <a href="${release.html_url}" target="_blank" rel="noopener">${release.tag_name}</a> | ||
Publicado en ${new Date(release.published_at) .toDateString()}.\n\n${body}`}).join('\n\n') | ||
}</Markdown> | ||
} | ||
|
||
# Registro de cambios | ||
|
||
Visite [SWR release page](https://github.com/vercel/swr/releases) para ver todo el historial de lanzamientos. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Se puede visitar... |
||
|
||
<ReleasesRenderer/> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
# Argumentos | ||
|
||
Por defecto, `key` se pasará a `fetcher` como argumento. Así que las siguientes 3 expresiones son equivalentes: | ||
|
||
```js | ||
useSWR('/api/user', () => fetcher('/api/user')) | ||
useSWR('/api/user', url => fetcher(url)) | ||
useSWR('/api/user', fetcher) | ||
``` | ||
|
||
## Argumentos múltiples | ||
|
||
En algunos escenarios, es útil pasar múltiples argumentos (puede pasar cualquier valor u objeto) a | ||
la función `fetcher`. Por ejemplo una solicitud de obtención autorizada: | ||
|
||
```js | ||
useSWR('/api/user', url => fetchWithToken(url, token)) | ||
``` | ||
|
||
Esto es **incorrecto**. Dado que el identificador (también la key del caché) de los datos es `'/api/user'`, incluso si el token cambia, SWR seguirá utilizando la misma key y devolverá los datos incorrectos. | ||
|
||
En su lugar, puedes utilizar un **array** como parámetro `key`, que contiene múltiples argumentos de `fetcher`: | ||
|
||
```js | ||
const { data: user } = useSWR(['/api/user', token], fetchWithToken) | ||
``` | ||
|
||
La función `fetchWithToken` sigue aceptando los mismo 2 argumentos, pero ahora la key del caché también estará asociada al `token`. | ||
|
||
## Pasar objectos | ||
|
||
Digamos que tienes otra función que obtiene datos con un scope | ||
del usuario: `fetchWithUser(api, user)`. Puedes hacer lo siguiente: | ||
|
||
```js | ||
const { data: user } = useSWR(['/api/user', token], fetchWithToken) | ||
// ...y pasarlo como un argumento a otra query | ||
const { data: orders } = useSWR(user ? ['/api/orders', user] : null, fetchWithUser) | ||
``` | ||
La `key` de la solicitud es ahora la combinación de ambos valores. SWR **shallowly** compara los argumentos en cada renderización, | ||
y activa la revalidación si alguno de ellos ha cambiado. | ||
|
||
Ten en cuenta que no debes recrear los objetos al renderizar, ya que serán tratados como objetos diferentes en cada render: | ||
|
||
```js | ||
// No lo hagas. Los deps se cambiarán en cada render. | ||
useSWR(['/api/user', { id }], query) | ||
|
||
// En su lugar, sólo debe pasar valores "estables". | ||
useSWR(['/api/user', id], (url, id) => query(url, { id })) | ||
``` | ||
|
||
Dan Abramov explica muy bien las dependencias en [está entrada del blog](https://overreacted.io/a-complete-guide-to-useeffect/#but-i-cant-put-this-function-inside-an-effect). | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# Búsqueda Condicional | ||
|
||
## Condicional | ||
|
||
Utilice `null` o pase una función como `key` para obtener datos de forma condicional. | ||
Si la función lanza o devuelve un falsy value, SWR no iniciará la petición. | ||
|
||
|
||
```js | ||
// conditionally fetch | ||
const { data } = useSWR(shouldFetch ? '/api/data' : null, fetcher) | ||
|
||
// ...o devuelve un falsy value | ||
const { data } = useSWR(() => shouldFetch ? '/api/data' : null, fetcher) | ||
|
||
// ...o lanza un error cuando user.id no está definifo | ||
const { data } = useSWR(() => '/api/data?uid=' + user.id, fetcher) | ||
``` | ||
|
||
## Dependiente | ||
|
||
SWR también permite obtener datos que dependen de otros datos. Garantiza el máximo paralelismo posible (evitando las cascadas), así como la obtención en serie cuando se necesita un dato dinámico para que se produzca la siguiente obtención de datos. | ||
|
||
```js | ||
function MyProjects () { | ||
const { data: user } = useSWR('/api/user') | ||
const { data: projects } = useSWR(() => '/api/projects?uid=' + user.id) | ||
// Al pasar una función, SWR utilizará el valor devuelto | ||
// como `key`. Si la función lanza o devuelve | ||
// falsy, SWR sabrá que algunas dependencias no estan | ||
// ready. En este caso `user.id` lanza cuando `user` | ||
// no este cargado. | ||
|
||
if (!projects) return 'loading...' | ||
return 'You have ' + projects.length + ' projects' | ||
} | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import Callout from 'nextra-theme-docs/callout' | ||
import Link from 'next/link' | ||
|
||
# Obtención De Datos | ||
|
||
```js | ||
const { data, error } = useSWR(key, fetcher) | ||
``` | ||
|
||
Esta es la API fundamental de SWR. El `fetcher` aquí es una función asíncrona que **acepta el `key`** de SWR, | ||
y devuelve los datos. | ||
|
||
El valor devuelto será pasado como `data`, y si lanza, será capturado como `error`. | ||
|
||
<Callout emoji="💡"> | ||
Tenga en cuenta que el <code>fetcher</code> puede ser omitido de los parámetros si se | ||
<Link href="/docs/global-configuration"><a href="/docs/global-configuration">proporciona globalmente</a></Link>. | ||
</Callout> | ||
|
||
## Fetch | ||
|
||
Puedes utilizar cualquier librería para manejar data fetching, por ejemplo un `fetch` polyfill [developit/unfetch](https://github.com/developit/unfetch): | ||
|
||
```js | ||
import fetch from 'unfetch' | ||
|
||
const fetcher = url => fetch(url).then(r => r.json()) | ||
|
||
function App () { | ||
const { data, error } = useSWR('/api/data', fetcher) | ||
// ... | ||
} | ||
``` | ||
|
||
<Callout emoji="💡"> | ||
Si estás usando <strong>Next.js</strong>, no necesita importar este polyfill: | ||
<br /> | ||
<a target="_blank" rel="noopener" href="https://nextjs.org/blog/next-9-1-7#new-built-in-polyfills-fetch-url-and-objectassign">Nuevos Polyfills Incorporados: fetch(), URL, y Object.assign</a> | ||
</Callout> | ||
|
||
## Axios | ||
|
||
```js | ||
import axios from 'axios' | ||
|
||
const fetcher = url => axios.get(url).then(res => res.data) | ||
|
||
function App () { | ||
const { data, error } = useSWR('/api/data', fetcher) | ||
// ... | ||
} | ||
``` | ||
|
||
## GraphQL | ||
|
||
O utilizando GraphQL con librerías como [graphql-request](https://github.com/prisma-labs/graphql-request): | ||
|
||
```js | ||
import { request } from 'graphql-request' | ||
|
||
const fetcher = query => request('/api/graphql', query) | ||
|
||
function App () { | ||
const { data, error } = useSWR( | ||
`{ | ||
Movie(title: "Inception") { | ||
releaseDate | ||
actors { | ||
name | ||
} | ||
} | ||
}`, | ||
fetcher | ||
) | ||
// ... | ||
} | ||
``` | ||
|
||
_Si quiere pasar variables a una query GraphQL, consulte [Argumentos múltiples](/docs/arguments)._ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here the informal 'you' is used whereas later in the document the formal 'you' is used. To avoid mixing it up it's better to use the impersonal form (an alternative is to use the plural as it's correctly used later in the document too):
"Se pueden reutilizar los hooks de datos ... sin preocuparse por el rendimiento"