Skip to content

Commit

Permalink
fix: staticImage should only set blur placeholder for jpeg,png,webp,a…
Browse files Browse the repository at this point in the history
…vif (#1058)

* should only use blur placeholder when file type is jpeg,png,webp,avif

* should only use blur placeholder when file type is jpeg,png,webp,avif

* update changesets

* update test snapshots

* chore: add comments about VALID_BLUR_EXT for staticImage

* chore: add jpg

* prettify

* update changeset description

Co-authored-by: Dimitri POSTOLOV <dmytropostolov@gmail.com>
  • Loading branch information
promer94 and dimaMachina committed Dec 11, 2022
1 parent 99ec64e commit f488e2e
Show file tree
Hide file tree
Showing 18 changed files with 1,128 additions and 2 deletions.
9 changes: 9 additions & 0 deletions .changeset/forty-snakes-clean.md
@@ -0,0 +1,9 @@
---
'nextra': patch
'nextra-theme-blog': patch
'nextra-theme-docs': patch
---

remove @react/skip-nev #1051

fix: staticImage should only set blur placeholder for jpeg,png,webp,avif
125 changes: 125 additions & 0 deletions examples/swr-site/pages/docs/understanding.en-US.mdx
@@ -0,0 +1,125 @@
import { Callout } from 'nextra-theme-docs'
import Video from 'components/video'

# Understanding SWR

## State Machine

`useSWR` returns `data`, `error`, `isLoading`, and `isValidating` depending on the state of the `fetcher` function. This diagrams describe how SWR returns values in some scenarios.

### Fetch and Revalidate

This pattern is to fetch data and revalidate it later.

![A pattern for fetch and revalidate](/img/understanding/fetch-and-revalidate.svg)

### Key Change

This pattern is to fetch data and change the key and revalidate it later.

![A pattern for key change](/img/understanding/key-change.svg)

### Key Change + Previous Data

This pattern is to fetch data and change the key and revalidate it later with the `keepPreviousData` option.

![A pattern for key change + previous data](/img/understanding/key-change-previous-data.svg)

### Fallback

This pattern is to fetch data and revalidate it later with fallback data.

![A pattern for fallback](/img/understanding/fallback.svg)

### Key Change + Fallback

This pattern is to fetch data and change the key and revalidate it later with fallback data.

![A pattern for key change + fallback](/img/understanding/key-change-fallback.svg)

### Key Change + Previous Data + Fallback

This pattern is to fetch data and change the key and revalidate it later with the `keepPreviousData` option and fallback data.

![A pattern for key change + previous data + fallback](/img/understanding/key-change-previous-data-fallback.svg)

## Combining with isLoading and isValidating for better UX

Comparing to the existing `isValidating` value, `isLoading` is a new property that can help you for the more general loading cases for UX.

- `isValidating` becomes `true` whenever there is an ongoing request **whatever the the data is loaded or not**
- `isLoading` becomes `true` when there is an ongoing request and **data is not loaded yet**.

Simply saying you can use `isValidating` for indicating everytime there is an ongoing revalidation, and `isLoading` for indicating that SWR is revalidating but there is no data yet to display.

<Callout emoji="📝">
Fallback data and previous data are not considered "loaded data," so when you use fallback data or enable the keepPreviousData option, you might have data to display.
</Callout>

```jsx
function Stock() {
const { data, isLoading, isValidating } = useSWR(STOCK_API, fetcher, {
refreshInterval: 3000
});

// If it's still loading the initial data, there is nothing to display.
// We return a skeleton here.
if (isLoading) return <div className="skeleton" />;

// Otherwise, display the data and a spinner that indicates a background
// revalidation.
return (
<>
<div>${data}</div>
{isValidating ? <div className="spinner" /> : null}
</>
);
}
```

![An example of using the isLoading state](/img/understanding/isloading.gif)

You can find the code example [here](https://codesandbox.io/s/swr-isloading-jtopow)

## Return previous data for better UX

When doing data fetching based on continuous user actions, e.g. real-time search when typing, keeping the previous fetched data can improve the UX a lot. `keepPreviousData` is an option to enable that behavior. Here's a simple search UI:

```jsx
function Search() {
const [search, setSearch] = React.useState('');

const { data, isLoading } = useSWR(`/search?q=${search}`, fetcher, {
keepPreviousData: true
});

return (
<div>
<input
type="text"
value={search}
onChange={(e) => setSearch(e.target.value)}
placeholder="Search..."
/>

<div className={isLoading ? "loading" : ""}>
{data?.products.map(item => <Product key={item.id} name={item.name} />)
</div>
</div>
);
}
```
With `keepPreviousData` enabled, you will still get the previous data even if you change the SWR key and the data for the new key starts loading again.
<Video
src="https://user-images.githubusercontent.com/3676859/163695903-a3eb1259-180e-41e0-821e-21c320201194.mp4"
caption="Keep previous search results when keepPreviousData has been enabled"
ratio={640/730}
/>
You can find the full code for this example here: https://codesandbox.io/s/swr-keeppreviousdata-fsjz3m.
## Dependency Collection for performance
SWR only triggers re-rendering when the states used in the component have been updated. If you only use `data` in the component, SWR ignores the updates of other properties like `isValidating`, and `isLoading`. This reduces rendering counts a lot. More information can be found [here](/docs/advanced/performance#dependency-collection).
125 changes: 125 additions & 0 deletions examples/swr-site/pages/docs/understanding.es-ES.mdx
@@ -0,0 +1,125 @@
import { Callout } from 'nextra-theme-docs'
import Video from 'components/video'

# Understanding SWR

## State Machine

`useSWR` returns `data`, `error`, `isLoading`, and `isValidating` depending on the state of the `fetcher` function. This diagrams describe how SWR returns values in some scenarios.

### Fetch and Revalidate

This pattern is to fetch data and revalidate it later.

![A pattern for fetch and revalidate](/img/understanding/fetch-and-revalidate.svg)

### Key Change

This pattern is to fetch data and change the key and revalidate it later.

![A pattern for key change](/img/understanding/key-change.svg)

### Key Change + Previous Data

This pattern is to fetch data and change the key and revalidate it later with the `keepPreviousData` option.

![A pattern for key change + previous data](/img/understanding/key-change-previous-data.svg)

### Fallback

This pattern is to fetch data and revalidate it later with fallback data.

![A pattern for fallback](/img/understanding/fallback.svg)

### Key Change + Fallback

This pattern is to fetch data and change the key and revalidate it later with fallback data.

![A pattern for key change + fallback](/img/understanding/key-change-fallback.svg)

### Key Change + Previous Data + Fallback

This pattern is to fetch data and change the key and revalidate it later with the `keepPreviousData` option and fallback data.

![A pattern for key change + previous data + fallback](/img/understanding/key-change-previous-data-fallback.svg)

## Combining with isLoading and isValidating for better UX

Comparing to the existing `isValidating` value, `isLoading` is a new property that can help you for the more general loading cases for UX.

- `isValidating` becomes `true` whenever there is an ongoing request **whatever the the data is loaded or not**
- `isLoading` becomes `true` when there is an ongoing request and **data is not loaded yet**.

Simply saying you can use `isValidating` for indicating everytime there is an ongoing revalidation, and `isLoading` for indicating that SWR is revalidating but there is no data yet to display.

<Callout emoji="📝">
Fallback data and previous data are not considered "loaded data," so when you use fallback data or enable the keepPreviousData option, you might have data to display.
</Callout>

```jsx
function Stock() {
const { data, isLoading, isValidating } = useSWR(STOCK_API, fetcher, {
refreshInterval: 3000
});

// If it's still loading the initial data, there is nothing to display.
// We return a skeleton here.
if (isLoading) return <div className="skeleton" />;

// Otherwise, display the data and a spinner that indicates a background
// revalidation.
return (
<>
<div>${data}</div>
{isValidating ? <div className="spinner" /> : null}
</>
);
}
```

![An example of using the isLoading state](/img/understanding/isloading.gif)

You can find the code example [here](https://codesandbox.io/s/swr-isloading-jtopow)

## Return previous data for better UX

When doing data fetching based on continuous user actions, e.g. real-time search when typing, keeping the previous fetched data can improve the UX a lot. `keepPreviousData` is an option to enable that behavior. Here's a simple search UI:

```jsx
function Search() {
const [search, setSearch] = React.useState('');

const { data, isLoading } = useSWR(`/search?q=${search}`, fetcher, {
keepPreviousData: true
});

return (
<div>
<input
type="text"
value={search}
onChange={(e) => setSearch(e.target.value)}
placeholder="Search..."
/>

<div className={isLoading ? "loading" : ""}>
{data?.products.map(item => <Product key={item.id} name={item.name} />)
</div>
</div>
);
}
```
With `keepPreviousData` enabled, you will still get the previous data even if you change the SWR key and the data for the new key starts loading again.
<Video
src="https://user-images.githubusercontent.com/3676859/163695903-a3eb1259-180e-41e0-821e-21c320201194.mp4"
caption="Keep previous search results when keepPreviousData has been enabled"
ratio={640/730}
/>
You can find the full code for this example here: https://codesandbox.io/s/swr-keeppreviousdata-fsjz3m.
## Dependency Collection for performance
SWR only triggers re-rendering when the states used in the component have been updated. If you only use `data` in the component, SWR ignores the updates of other properties like `isValidating`, and `isLoading`. This reduces rendering counts a lot. More information can be found [here](/docs/advanced/performance#dependency-collection).
125 changes: 125 additions & 0 deletions examples/swr-site/pages/docs/understanding.ja.mdx
@@ -0,0 +1,125 @@
import { Callout } from 'nextra-theme-docs'
import Video from 'components/video'

# SWR を理解する

## 状態機械

`useSWR``data``error``isLoading``isValidating``fetcher` 関数の状態に応じて返します。これらの図は SWR がそれぞれでどのように値を返すのかを示しています。

### フェッチして再検証する

これはフェッチして再検証するパターンです。

![フェッチと再検証のパターン](/img/understanding/fetch-and-revalidate.svg)

### キーの変更

これはフェッチした後にキーを変更し、さらにその後再検証するパターンです。

![キーが変更されたパターン](/img/understanding/key-change.svg)

### キーの変更と以前のデータ

これはフェッチした後にキーを変更し再検証するのを `keepPreviousData` オプション付きで行うパターンです。

![キーの変更を keepPreviousData オプションありで行うパターン](/img/understanding/key-change-previous-data.svg)

### フォールバック

これはフェッチした後に再検証するのをフォールバックデータと一緒に行うパターンです。

![フォールバックのパターン](/img/understanding/fallback.svg)

### キーの変更とフォールバック

これはフェッチした後にキーを変更し再検証するのをフォールバックデータと一緒に行うパターンです。

![キーの変更をフォールバックありで行うパターン](/img/understanding/key-change-fallback.svg)

### キーの変更と以前のデータとフォールバック

これはフェッチした後にキーを変更し再検証するのを `keepPreviousData` オプションとフォールバックデータと一緒に行うパターンです。

![キーの変更を keepPreviousData オプションとフォールバックありで行うパターン](/img/understanding/key-change-previous-data-fallback.svg)

## よりよい UX のために isLoading と isValidating を組み合わせる

既存の `isValidating` の値と比較して、`isLoading` はより一般的なローディングのための UX に役に立つ新しいプロパティです。

- `isValidating` は実行中のリクエストがある場合に **データがロード済みかどうかに関わらず** `true` になります
- `isLoading` は実行中のリクエストがあり ***ロード済みのデータがまだない場合**`true` になります

わかりやすく言うと、`isValidating` は実行中の再検証が存在する場合全てで、`isLoading` は SWR が再検証中だけど表示するためのデータがない場合に使えます。

<Callout emoji="📝">
フォールバックデータと以前のデータ (previous data) は "ロードされたデータ" とは扱われません。そのため、フォールバックデータや `keepPreviousData` オプションを使う場合には、表示するためのデータがあるかもしれません。
</Callout>

```jsx
function Stock() {
const { data, isLoading, isValidating } = useSWR(STOCK_API, fetcher, {
refreshInterval: 3000
});

// 初期データのローディング中の場合には、表示するためのデータはありません
// そのため、スケルトンの表示を返します
if (isLoading) return <div className="skeleton" />;

// そうでなければ、データとバックグラウンドで再検証中であることを示す
// UI を表示します
return (
<>
<div>${data}</div>
{isValidating ? <div className="spinner" /> : null}
</>
);
}
```

![isLoading を使った例](/img/understanding/isloading.gif)

[こちら](https://codesandbox.io/s/swr-isloading-jtopow) から実際のコードを確認できます。

## よりよいユーザー体験のために以前のデータを返す

キー入力に応じたリアルタイム検索など継続的なユーザーアクションをベースにしたデータ取得を行う時、以前のデータを維持することによりユーザー体験を改善できます。`keepPreviousData` はこれを可能にするオプションです。これはシンプルな検索の例です。

```jsx
function Search() {
const [search, setSearch] = React.useState('');

const { data, isLoading } = useSWR(`/search?q=${search}`, fetcher, {
keepPreviousData: true
});

return (
<div>
<input
type="text"
value={search}
onChange={(e) => setSearch(e.target.value)}
placeholder="Search..."
/>

<div className={isLoading ? "loading" : ""}>
{data?.products.map(item => <Product key={item.id} name={item.name} />)
</div>
</div>
);
}
```
`keepPreviousData` が有効にされている場合、SWR のキーが変わり新しいデータの取得が開始された場合にも以前のキーに対応するデータが返されます。
<Video
src="https://user-images.githubusercontent.com/3676859/163695903-a3eb1259-180e-41e0-821e-21c320201194.mp4"
caption="keepPreviousData が有効な場合には以前の検索結果が維持されます"
ratio={640/730}
/>
この例のコードはこちらです: https://codesandbox.io/s/swr-keeppreviousdata-fsjz3m.
## パフォーマンのための依存収集
SWR はコンポーネントで使われているデータが更新された場合のみ再レンダリングします。コンポーネントの中で `data` しか使っていない場合、SWR は `isValidating``isLoading` のプロパティの更新を無視します。これはレンダリングの回数を減らします。詳細については [こちら](/docs/advanced/performance#dependency-collection)。

1 comment on commit f488e2e

@vercel
Copy link

@vercel vercel bot commented on f488e2e Dec 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.