diff --git a/.github/workflows/analyze.yml b/.github/workflows/analyze.yml index 87dcfdc73..2a905a0df 100644 --- a/.github/workflows/analyze.yml +++ b/.github/workflows/analyze.yml @@ -11,10 +11,10 @@ jobs: analyze: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up node - uses: actions/setup-node@v1 + uses: actions/setup-node@v3 with: node-version: '20.x' @@ -22,7 +22,7 @@ jobs: uses: bahmutov/npm-install@v1.7.10 - name: Restore next build - uses: actions/cache@v2 + uses: actions/cache@v3 id: restore-build-cache env: cache-name: cache-next-build @@ -41,7 +41,7 @@ jobs: run: npx -p nextjs-bundle-analysis@0.5.0 report - name: Upload bundle - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: path: .next/analyze/__bundle_analysis.json name: bundle_analysis.json @@ -73,7 +73,7 @@ jobs: run: ls -laR .next/analyze/base && npx -p nextjs-bundle-analysis compare - name: Upload analysis comment - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: analysis_comment.txt path: .next/analyze/__bundle_analysis_comment.txt @@ -82,7 +82,7 @@ jobs: run: echo ${{ github.event.number }} > ./pr_number - name: Upload PR number - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: pr_number path: ./pr_number diff --git a/src/components/Layout/Footer.tsx b/src/components/Layout/Footer.tsx index 5bcf9df98..4e19039ed 100644 --- a/src/components/Layout/Footer.tsx +++ b/src/components/Layout/Footer.tsx @@ -283,7 +283,7 @@ export function Footer() {
- ©{new Date().getFullYear()} + Copyright © Meta Platforms, Inc
- {name} {isPacked && '✔'} + {name} {isPacked && '✅'} ); } @@ -307,7 +307,7 @@ export default function PackingList() { function Item({ name, isPacked }) { return (
  • - {name} {isPacked ? '✔' : '❌'} + {name} {isPacked ? '✅' : '❌'}
  • ); } diff --git a/src/content/community/conferences.md b/src/content/community/conferences.md index 994afa491..a4a25fc44 100644 --- a/src/content/community/conferences.md +++ b/src/content/community/conferences.md @@ -10,26 +10,6 @@ title: React カンファレンス ## Upcoming Conferences {/*upcoming-conferences*/} -### React Nexus 2024 {/*react-nexus-2024*/} -July 04 & 05, 2024. Bangalore, India (In-person event) - -[Website](https://reactnexus.com/) - [Twitter](https://twitter.com/ReactNexus) - [Linkedin](https://www.linkedin.com/company/react-nexus) - [YouTube](https://www.youtube.com/reactify_in) - -### Chain React 2024 {/*chain-react-2024*/} -July 17-19, 2024. In-person in Portland, OR, USA - -[Website](https://chainreactconf.com) - [Twitter](https://twitter.com/ChainReactConf) - -### The Geek Conf 2024 {/*the-geek-conf-2024*/} -July 25, 2024. In-person in Berlin, Germany + remote (hybrid event) - -[Website](https://thegeekconf.com) - [Twitter](https://twitter.com/thegeekconf) - -### React Rally 2024 🐙 {/*react-rally-2024*/} -August 12-13, 2024. Park City, UT, USA - -[Website](https://reactrally.com) - [Twitter](https://twitter.com/ReactRally) - [YouTube](https://www.youtube.com/channel/UCXBhQ05nu3L1abBUGeQ0ahw) - ### React Universe Conf 2024 {/*react-universe-conf-2024*/} September 5-6, 2024. Wrocław, Poland. @@ -55,13 +35,48 @@ October 18, 2024. In-person in Brussels, Belgium (hybrid event) [Website](https://www.react.brussels/) - [Twitter](https://x.com/BrusselsReact) +### React Advanced London 2024 {/*react-advanced-london-2024*/} +October 25 & 28, 2024. In-person in London, UK + online (hybrid event) + +[Website](https://reactadvanced.com/) - [Twitter](https://x.com/reactadvanced) + +### React Summit US 2024 {/*react-summit-us-2024*/} +November 19 & 22, 2024. In-person in New York, USA + online (hybrid event) + +[Website](https://reactsummit.us/) - [Twitter](https://twitter.com/reactsummit) - [Videos](https://portal.gitnation.org/) + ### React Africa 2024 {/*react-africa-2024*/} November 29, 2024. In-person in Casablanca, Morocco (hybrid event) [Website](https://react-africa.com/) - [Twitter](https://x.com/BeJS_) +### React Day Berlin 2024 {/*react-day-berlin-2024*/} +December 13 & 16, 2024. In-person in Berlin, Germany + remote (hybrid event) + +[Website](https://reactday.berlin/) - [Twitter](https://x.com/reactdayberlin) + ## Past Conferences {/*past-conferences*/} +### React Rally 2024 🐙 {/*react-rally-2024*/} +August 12-13, 2024. Park City, UT, USA + +[Website](https://reactrally.com) - [Twitter](https://twitter.com/ReactRally) - [YouTube](https://www.youtube.com/channel/UCXBhQ05nu3L1abBUGeQ0ahw) + +### The Geek Conf 2024 {/*the-geek-conf-2024*/} +July 25, 2024. In-person in Berlin, Germany + remote (hybrid event) + +[Website](https://thegeekconf.com) - [Twitter](https://twitter.com/thegeekconf) + +### Chain React 2024 {/*chain-react-2024*/} +July 17-19, 2024. In-person in Portland, OR, USA + +[Website](https://chainreactconf.com) - [Twitter](https://twitter.com/ChainReactConf) + +### React Nexus 2024 {/*react-nexus-2024*/} +July 04 & 05, 2024. Bangalore, India (In-person event) + +[Website](https://reactnexus.com/) - [Twitter](https://twitter.com/ReactNexus) - [Linkedin](https://www.linkedin.com/company/react-nexus) - [YouTube](https://www.youtube.com/reactify_in) + ### React Summit 2024 {/*react-summit-2024*/} June 14 & 18, 2024. In-person in Amsterdam, Netherlands + remote (hybrid event) diff --git a/src/content/learn/conditional-rendering.md b/src/content/learn/conditional-rendering.md index 284c4bc08..4b21012e3 100644 --- a/src/content/learn/conditional-rendering.md +++ b/src/content/learn/conditional-rendering.md @@ -52,13 +52,17 @@ export default function PackingList() { +<<<<<<< HEAD 複数の `Item` コンポーネントのうち一部のみで、props である `isPacked` が `false` ではなく `true` になっていることに注意してください。目的は、`isPacked={true}` の場合にのみチェックマーク (✔) を表示させることです。 +======= +Notice that some of the `Item` components have their `isPacked` prop set to `true` instead of `false`. You want to add a checkmark (✅) to packed items if `isPacked={true}`. +>>>>>>> c003ac4eb130fca70b88cf3a1b80ce5f76c51ae3 これは [`if`/`else` 文](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else)を使って、以下のように書くことができます。 ```js if (isPacked) { - return
  • {name} ✔
  • ; + return
  • {name} ✅
  • ; } return
  • {name}
  • ; ``` @@ -70,7 +74,7 @@ return
  • {name}
  • ; ```js function Item({ name, isPacked }) { if (isPacked) { - return
  • {name} ✔
  • ; + return
  • {name} ✅
  • ; } return
  • {name}
  • ; } @@ -159,7 +163,7 @@ export default function PackingList() { 前の例では、コンポーネントが複数の JSX ツリーのうちどれを返すのか(あるいは何も返さないのか)をコントロールしていました。しかし、レンダー出力に重複があることに気付かれたでしょう。 ```js -
  • {name} ✔
  • +
  • {name} ✅
  • ``` これは以下とほとんど同じです。 @@ -172,7 +176,7 @@ export default function PackingList() { ```js if (isPacked) { - return
  • {name} ✔
  • ; + return
  • {name} ✅
  • ; } return
  • {name}
  • ; ``` @@ -187,7 +191,7 @@ JavaScript には、条件式を書くためのコンパクトな構文があり ```js if (isPacked) { - return
  • {name} ✔
  • ; + return
  • {name} ✅
  • ; } return
  • {name}
  • ; ``` @@ -197,12 +201,16 @@ return
  • {name}
  • ; ```js return (
  • - {isPacked ? name + ' ✔' : name} + {isPacked ? name + ' ✅' : name}
  • ); ``` +<<<<<<< HEAD これは「*`isPacked` が true なら `name + ' ✔'` をレンダーし、それ以外 (`:`) の場合は `name` をレンダーする*」というように読んでください。 +======= +You can read it as *"if `isPacked` is true, then (`?`) render `name + ' ✅'`, otherwise (`:`) render `name`"*. +>>>>>>> c003ac4eb130fca70b88cf3a1b80ce5f76c51ae3 @@ -222,7 +230,7 @@ function Item({ name, isPacked }) {
  • {isPacked ? ( - {name + ' ✔'} + {name + ' ✅'} ) : ( name @@ -265,7 +273,7 @@ export default function PackingList() { ```js return (
  • - {name} {isPacked && '✔'} + {name} {isPacked && '✅'}
  • ); ``` @@ -280,7 +288,7 @@ return ( function Item({ name, isPacked }) { return (
  • - {name} {isPacked && '✔'} + {name} {isPacked && '✅'}
  • ); } @@ -337,7 +345,7 @@ let itemContent = name; ```js if (isPacked) { - itemContent = name + " ✔"; + itemContent = name + " ✅"; } ``` @@ -357,7 +365,7 @@ if (isPacked) { function Item({ name, isPacked }) { let itemContent = name; if (isPacked) { - itemContent = name + " ✔"; + itemContent = name + " ✅"; } return (
  • @@ -401,7 +409,7 @@ function Item({ name, isPacked }) { if (isPacked) { itemContent = ( - {name + " ✔"} + {name + " ✅"} ); } @@ -464,7 +472,7 @@ JavaScript に慣れていない場合、これだけ多様なスタイルがあ function Item({ name, isPacked }) { return (
  • - {name} {isPacked && '✔'} + {name} {isPacked && '✅'}
  • ); } @@ -502,7 +510,7 @@ export default function PackingList() { function Item({ name, isPacked }) { return (
  • - {name} {isPacked ? '✔' : '❌'} + {name} {isPacked ? '✅' : '❌'}
  • ); } diff --git a/src/content/learn/describing-the-ui.md b/src/content/learn/describing-the-ui.md index 799d8c8d0..b3aaf1182 100644 --- a/src/content/learn/describing-the-ui.md +++ b/src/content/learn/describing-the-ui.md @@ -327,7 +327,7 @@ export function getImageUrl(person, size = 's') { function Item({ name, isPacked }) { return (
  • - {name} {isPacked && '✔'} + {name} {isPacked && '✅'}
  • ); } diff --git a/src/content/learn/react-compiler.md b/src/content/learn/react-compiler.md index 7fc1680d7..019d8ed60 100644 --- a/src/content/learn/react-compiler.md +++ b/src/content/learn/react-compiler.md @@ -121,7 +121,7 @@ React Comiler は多くの React のルールを静的に検証でき、エラ コンパイラをインストールする前に、まずコードベースが互換性があるかどうかを確認してください。 -npx react-compiler-healthcheck@latest +npx react-compiler-healthcheck@experimental このスクリプトは以下をチェックします。 @@ -143,7 +143,7 @@ Found no usage of incompatible libraries. React Compiler は eslint プラグインも提供しています。eslint プラグインはコンパイラとは**独立して**使用できるため、コンパイラを使用しなくても eslint プラグインだけを使用できます。 -npm install eslint-plugin-react-compiler +npm install eslint-plugin-react-compiler@experimental 次に、eslint の設定に以下を追加します。 @@ -203,7 +203,7 @@ export default function App() { ### Babel {/*usage-with-babel*/} -npm install babel-plugin-react-compiler +npm install babel-plugin-react-compiler@experimental コンパイラには、ビルドパイプラインでコンパイラを実行するために使用できる Babel プラグインが含まれています。 @@ -258,7 +258,7 @@ Next.js には React Compiler を有効にするための実験的な設定が - `babel-plugin-react-compiler` をインストールする -npm install next@canary babel-plugin-react-compiler +npm install next@canary babel-plugin-react-compiler@experimental 次に以下のようにして `next.config.js` 内で実験的オプションを設定します。 diff --git a/src/content/learn/you-might-not-need-an-effect.md b/src/content/learn/you-might-not-need-an-effect.md index 3058a38e3..82d161e1e 100644 --- a/src/content/learn/you-might-not-need-an-effect.md +++ b/src/content/learn/you-might-not-need-an-effect.md @@ -408,9 +408,15 @@ function Game() { このコードには 2 つの問題があります。 +<<<<<<< HEAD 1 つ目の問題は、非常に効率が悪いことです。コンポーネント(およびその子)は、連鎖内の各 `set` コールの間で毎回再レンダーする必要があります。上記の例では、最悪の場合、下位のツリーに 3 回の不要な再レンダー(`setCard` → レンダー → `setGoldCardCount` → レンダー → `setRound` → レンダー → `setIsGameOver` → レンダー)が発生することになります。 たとえこれが遅くなかったとしても、コードが発展するにつれ、書いた「チェイン」が新しい要件に適合しないケースが出てきます。例えばゲームの手順を遡る機能を追加しているとしましょう。このためには、各 state 変数を過去のある時点の値に再セットしていくことになります。しかし過去の値から `card` の state をセットした時点で再びエフェクトの連鎖処理がトリガされ、表示されるデータが変更されてしまいます。このようなコードは、硬直的で壊れやすいものです。 +======= +The first problem is that it is very inefficient: the component (and its children) have to re-render between each `set` call in the chain. In the example above, in the worst case (`setCard` → render → `setGoldCardCount` → render → `setRound` → render → `setIsGameOver` → render) there are three unnecessary re-renders of the tree below. + +The second problem is that even if it weren't slow, as your code evolves, you will run into cases where the "chain" you wrote doesn't fit the new requirements. Imagine you are adding a way to step through the history of the game moves. You'd do it by updating each state variable to a value from the past. However, setting the `card` state to a value from the past would trigger the Effect chain again and change the data you're showing. Such code is often rigid and fragile. +>>>>>>> c003ac4eb130fca70b88cf3a1b80ce5f76c51ae3 このような場合、レンダー中に計算できるものはそこで行い、イベントハンドラで state の調整を終わらせる方が良いでしょう。 diff --git a/src/content/reference/react-dom/components/index.md b/src/content/reference/react-dom/components/index.md index 5429a3473..bbea3fcdd 100644 --- a/src/content/reference/react-dom/components/index.md +++ b/src/content/reference/react-dom/components/index.md @@ -34,7 +34,11 @@ React は、ブラウザ組み込みのすべての [HTML](https://developer.moz ## リソース・メタデータ関連コンポーネント {/*resource-and-metadata-components*/} +<<<<<<< HEAD 以下のブラウザ組み込みコンポーネントを用いて、外部リソースを読み込んだり、ドキュメントにメタデータを付与したりすることができます。 +======= +These built-in browser components let you load external resources or annotate the document with metadata: +>>>>>>> c003ac4eb130fca70b88cf3a1b80ce5f76c51ae3 * [``](/reference/react-dom/components/link) * [``](/reference/react-dom/components/meta) diff --git a/src/content/reference/react/cache.md b/src/content/reference/react/cache.md index 68a44eb53..dc22f8d11 100644 --- a/src/content/reference/react/cache.md +++ b/src/content/reference/react/cache.md @@ -226,7 +226,7 @@ async function AnimatedWeatherCard({city}) { ```jsx [[2, 6, "await getUser(id)"], [1, 17, "getUser(id)"]] const getUser = cache(async (id) => { return await db.user.query(id); -}) +}); async function Profile({id}) { const user = await getUser(id); @@ -327,7 +327,7 @@ React がメモ化された関数に対してキャッシュアクセスを提 'use client'; function WeatherReport({record}) { - const avgTemp = useMemo(() => calculateAvg(record)), record); + const avgTemp = useMemo(() => calculateAvg(record), record); // ... } diff --git a/src/content/reference/react/index.md b/src/content/reference/react/index.md index f1708c84d..4dca61450 100644 --- a/src/content/reference/react/index.md +++ b/src/content/reference/react/index.md @@ -14,10 +14,17 @@ React リファレンスは機能別にいくつかのサブセクションに プログラムから利用する React の機能です。 +<<<<<<< HEAD * [フック](/reference/react/hooks) - コンポーネント内から使用する様々な React の機能 * [コンポーネント](/reference/react/components) - JSX 内で用いる組み込みコンポーネント * [API](/reference/react/apis) - コンポーネントの定義に用いる API * [ディレクティブ](/reference/rsc/directives) - React Server Components 互換のバンドラに与えるための指示情報 +======= +* [Hooks](/reference/react/hooks) - Use different React features from your components. +* [Components](/reference/react/components) - Built-in components that you can use in your JSX. +* [APIs](/reference/react/apis) - APIs that are useful for defining components. +* [Directives](/reference/rsc/directives) - Provide instructions to bundlers compatible with React Server Components. +>>>>>>> c003ac4eb130fca70b88cf3a1b80ce5f76c51ae3 ## React DOM {/*react-dom*/} diff --git a/src/content/reference/react/lazy.md b/src/content/reference/react/lazy.md index 0a7f91408..c75f3a4c5 100644 --- a/src/content/reference/react/lazy.md +++ b/src/content/reference/react/lazy.md @@ -78,7 +78,7 @@ const MarkdownPreview = lazy(() => import('./MarkdownPreview.js')); }>

    Preview

    -
    + ``` この例では、`MarkdownPreview` のコードはレンダーしようとするまで読み込まれません。もし `MarkdownPreview` がまだ読み込まれていない場合、その代わりに `Loading` が表示されます。チェックボックスをオンにしてみてください。 diff --git a/src/content/reference/react/useCallback.md b/src/content/reference/react/useCallback.md index 210f2933d..864935d4b 100644 --- a/src/content/reference/react/useCallback.md +++ b/src/content/reference/react/useCallback.md @@ -711,7 +711,7 @@ function ChatRoom({ roomId }) { useEffect(() => { const options = createOptions(); - const connection = createConnection(); + const connection = createConnection(options); connection.connect(); // ... ``` @@ -722,7 +722,7 @@ function ChatRoom({ roomId }) { ```js {6} useEffect(() => { const options = createOptions(); - const connection = createConnection(); + const connection = createConnection(options); connection.connect(); return () => connection.disconnect(); }, [createOptions]); // 🔴 Problem: This dependency changes on every render @@ -744,7 +744,7 @@ function ChatRoom({ roomId }) { useEffect(() => { const options = createOptions(); - const connection = createConnection(); + const connection = createConnection(options); connection.connect(); return () => connection.disconnect(); }, [createOptions]); // ✅ Only changes when createOptions changes @@ -766,7 +766,7 @@ function ChatRoom({ roomId }) { } const options = createOptions(); - const connection = createConnection(); + const connection = createConnection(options); connection.connect(); return () => connection.disconnect(); }, [roomId]); // ✅ Only changes when roomId changes diff --git a/src/content/reference/react/useLayoutEffect.md b/src/content/reference/react/useLayoutEffect.md index 1911b779d..f9e1b2ea3 100644 --- a/src/content/reference/react/useLayoutEffect.md +++ b/src/content/reference/react/useLayoutEffect.md @@ -67,6 +67,8 @@ function Tooltip() { * `useLayoutEffect` 内のコードと、そこでスケジュールされたすべての state 更新は、**ブラウザによる画面の再描画をブロックします**。過度に使用すると、アプリが遅くなります。可能な限り [`useEffect` を使用してください](/reference/react/useEffect)。 +* If you trigger a state update inside `useLayoutEffect`, React will execute all remaining Effects immediately including `useEffect`. + --- ## 使用法 {/*usage*/} diff --git a/src/content/reference/react/useMemo.md b/src/content/reference/react/useMemo.md index 43e173e4f..a3df19c04 100644 --- a/src/content/reference/react/useMemo.md +++ b/src/content/reference/react/useMemo.md @@ -1056,7 +1056,88 @@ label { --- +<<<<<<< HEAD ### 他のフックに渡す依存値をメモ化する {/*memoizing-a-dependency-of-another-hook*/} +======= +### Preventing an Effect from firing too often {/*preventing-an-effect-from-firing-too-often*/} + +Sometimes, you might want to use a value inside an [Effect:](/learn/synchronizing-with-effects) + +```js {4-7,10} +function ChatRoom({ roomId }) { + const [message, setMessage] = useState(''); + + const options = { + serverUrl: 'https://localhost:1234', + roomId: roomId + } + + useEffect(() => { + const connection = createConnection(options); + connection.connect(); + // ... +``` + +This creates a problem. [Every reactive value must be declared as a dependency of your Effect.](/learn/lifecycle-of-reactive-effects#react-verifies-that-you-specified-every-reactive-value-as-a-dependency) However, if you declare `options` as a dependency, it will cause your Effect to constantly reconnect to the chat room: + + +```js {5} + useEffect(() => { + const connection = createConnection(options); + connection.connect(); + return () => connection.disconnect(); + }, [options]); // 🔴 Problem: This dependency changes on every render + // ... +``` + +To solve this, you can wrap the object you need to call from an Effect in `useMemo`: + +```js {4-9,16} +function ChatRoom({ roomId }) { + const [message, setMessage] = useState(''); + + const options = useMemo(() => { + return { + serverUrl: 'https://localhost:1234', + roomId: roomId + }; + }, [roomId]); // ✅ Only changes when roomId changes + + useEffect(() => { + const options = createOptions(); + const connection = createConnection(options); + connection.connect(); + return () => connection.disconnect(); + }, [options]); // ✅ Only changes when createOptions changes + // ... +``` + +This ensures that the `options` object is the same between re-renders if `useMemo` returns the cached object. + +However, since `useMemo` is performance optimization, not a semantic guarantee, React may throw away the cached value if [there is a specific reason to do that](#caveats). This will also cause the effect to re-fire, **so it's even better to remove the need for a function dependency** by moving your object *inside* the Effect: + +```js {5-8,13} +function ChatRoom({ roomId }) { + const [message, setMessage] = useState(''); + + useEffect(() => { + const options = { // ✅ No need for useMemo or object dependencies! + serverUrl: 'https://localhost:1234', + roomId: roomId + } + + const connection = createConnection(options); + connection.connect(); + return () => connection.disconnect(); + }, [roomId]); // ✅ Only changes when roomId changes + // ... +``` + +Now your code is simpler and doesn't need `useMemo`. [Learn more about removing Effect dependencies.](/learn/removing-effect-dependencies#move-dynamic-objects-and-functions-inside-your-effect) + + +### Memoizing a dependency of another Hook {/*memoizing-a-dependency-of-another-hook*/} +>>>>>>> c003ac4eb130fca70b88cf3a1b80ce5f76c51ae3 ある計算が、コンポーネントの本体で直接作成されたオブジェクトに依存しているとしましょう。 diff --git a/src/content/reference/react/useReducer.md b/src/content/reference/react/useReducer.md index 10619ad8f..0bf164221 100644 --- a/src/content/reference/react/useReducer.md +++ b/src/content/reference/react/useReducer.md @@ -51,8 +51,14 @@ function MyComponent() { #### 注意点 {/*caveats*/} +<<<<<<< HEAD * `useReducer` はフックなので、**コンポーネントのトップレベル**または独自のカスタムフック内でのみ呼び出すことができます。ループや条件の中で呼び出すことはできません。必要な場合は、新しいコンポーネントとして抜き出し、その中に state を移動させてください。 * Strict Mode では、React は[純粋でない関数を見つけやすくするために](#my-reducer-or-initializer-function-runs-twice)、リデューサと初期化関数を 2 回呼び出します。これは開発時の動作であり、本番には影響しません。リデューサと初期化関数が純粋であれば(そうあるべきです)、これはロジックに影響しません。片方の呼び出しの結果は無視されます。 +======= +* `useReducer` is a Hook, so you can only call it **at the top level of your component** or your own Hooks. You can't call it inside loops or conditions. If you need that, extract a new component and move the state into it. +* The `dispatch` function has a stable identity, so you will often see it omitted from effect dependencies, but including it will not cause the effect to fire. If the linter lets you omit a dependency without errors, it is safe to do. [Learn more about removing Effect dependencies.](/learn/removing-effect-dependencies#move-dynamic-objects-and-functions-inside-your-effect) +* In Strict Mode, React will **call your reducer and initializer twice** in order to [help you find accidental impurities.](#my-reducer-or-initializer-function-runs-twice) This is development-only behavior and does not affect production. If your reducer and initializer are pure (as they should be), this should not affect your logic. The result from one of the calls is ignored. +>>>>>>> c003ac4eb130fca70b88cf3a1b80ce5f76c51ae3 --- diff --git a/src/content/reference/react/useState.md b/src/content/reference/react/useState.md index 617db3bbe..7db5c92f9 100644 --- a/src/content/reference/react/useState.md +++ b/src/content/reference/react/useState.md @@ -85,7 +85,13 @@ function handleClick() { * React は [state の更新をまとめて行います(バッチ処理)](/learn/queueing-a-series-of-state-updates)。**すべてのイベントハンドラを実行し終え**、`set` 関数が呼び出された後に、画面を更新します。これにより、1 つのイベント中に複数回の再レンダーが発生することはありません。まれに、早期に画面を更新する必要がある場合(例えば DOM にアクセスする場合など)がありますが、その場合は [`flushSync`](/reference/react-dom/flushSync) を利用できます。 +<<<<<<< HEAD * レンダー中に `set` 関数を呼び出すことは、*現在レンダー中の*コンポーネント内からのみ許されています。その場合、React はその出力を破棄し、新しい state で再レンダーを試みます。このパターンが必要になることはほとんどありませんが、**前回のレンダーからの情報を保存**するために使用できます。[例を見る](#storing-information-from-previous-renders) +======= +* The `set` function has a stable identity, so you will often see it omitted from effect dependencies, but including it will not cause the effect to fire. If the linter lets you omit a dependency without errors, it is safe to do. [Learn more about removing Effect dependencies.](/learn/removing-effect-dependencies#move-dynamic-objects-and-functions-inside-your-effect) + +* Calling the `set` function *during rendering* is only allowed from within the currently rendering component. React will discard its output and immediately attempt to render it again with the new state. This pattern is rarely needed, but you can use it to **store information from the previous renders**. [See an example below.](#storing-information-from-previous-renders) +>>>>>>> c003ac4eb130fca70b88cf3a1b80ce5f76c51ae3 * Strict Mode では、[純粋でない関数を見つけやすくするために](#my-initializer-or-updater-function-runs-twice)**更新用関数が 2 回呼び出されます**。これは開発時のみの振る舞いであり、本番には影響しません。更新用関数が純粋であれば(そうであるべきです)、2 回呼び出されてもコードに影響はありません。2 回の呼び出しのうち 1 回の呼び出し結果は無視されます。 diff --git a/src/content/reference/react/useSyncExternalStore.md b/src/content/reference/react/useSyncExternalStore.md index b548ee002..ea86e4b44 100644 --- a/src/content/reference/react/useSyncExternalStore.md +++ b/src/content/reference/react/useSyncExternalStore.md @@ -41,7 +41,11 @@ function TodosApp() { #### 引数 {/*parameters*/} +<<<<<<< HEAD * `subscribe`: ストアにサブスクライブを開始し、また callback 引数を受け取る関数。ストアが変更された際に渡された callback を呼び出す必要があります。これにより、コンポーネントが再レンダーされます。`subscribe` 関数は、サブスクリプションをクリーンアップする関数を返す必要があります。 +======= +* `subscribe`: A function that takes a single `callback` argument and subscribes it to the store. When the store changes, it should invoke the provided `callback`, which will cause React to re-call `getSnapshot` and (if needed) re-render the component. The `subscribe` function should return a function that cleans up the subscription. +>>>>>>> c003ac4eb130fca70b88cf3a1b80ce5f76c51ae3 * `getSnapshot`: コンポーネントが必要とするストアにあるデータのスナップショットを返す関数。ストアが変更されていない場合、`getSnapshot` への再呼び出しは同じ値を返す必要があります。ストアが変更されて返された値が([`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) で比較して)異なる場合、React はコンポーネントを再レンダーします。 diff --git a/src/content/reference/react/useTransition.md b/src/content/reference/react/useTransition.md index b21951509..438330c75 100644 --- a/src/content/reference/react/useTransition.md +++ b/src/content/reference/react/useTransition.md @@ -80,7 +80,13 @@ function TabContainer() { * `startTransition` に渡す関数は同期的でなければなりません。React はこの関数を直ちに実行し、その実行中に行われるすべての state 更新をトランジションとしてマークします。後になって(例えばタイムアウト内で)さらに state 更新をしようとすると、それらはトランジションとしてマークされません。 +<<<<<<< HEAD * トランジションとしてマークされた state 更新は、他の state 更新によって中断されます。例えば、トランジション内でチャートコンポーネントを更新した後、チャートの再レンダーの途中で入力フィールドに入力を始めた場合、React は入力欄の更新の処理後にチャートコンポーネントのレンダー作業を再開します。 +======= +* The `startTransition` function has a stable identity, so you will often see it omitted from effect dependencies, but including it will not cause the effect to fire. If the linter lets you omit a dependency without errors, it is safe to do. [Learn more about removing Effect dependencies.](/learn/removing-effect-dependencies#move-dynamic-objects-and-functions-inside-your-effect) + +* A state update marked as a Transition will be interrupted by other state updates. For example, if you update a chart component inside a Transition, but then start typing into an input while the chart is in the middle of a re-render, React will restart the rendering work on the chart component after handling the input update. +>>>>>>> c003ac4eb130fca70b88cf3a1b80ce5f76c51ae3 * トランジションによる更新はテキスト入力欄の制御には使用できません。 diff --git a/src/content/reference/rsc/server-actions.md b/src/content/reference/rsc/server-actions.md index 829dad867..c54b06ef4 100644 --- a/src/content/reference/rsc/server-actions.md +++ b/src/content/reference/rsc/server-actions.md @@ -53,7 +53,7 @@ React がサーバコンポーネントである `EmptyNote` をレンダーす export default function Button({onClick}) { console.log(onClick); // {$$typeof: Symbol.for("react.server.reference"), $$id: 'createNoteAction'} - return + return } ``` diff --git a/vercel.json b/vercel.json index eac0efb9c..8b0546e37 100644 --- a/vercel.json +++ b/vercel.json @@ -24,6 +24,11 @@ "destination": "/learn/rendering-lists#keeping-list-items-in-order-with-key", "permanent": false }, + { + "source": "/docs/lists-and-keys", + "destination": "/learn/rendering-lists#keeping-list-items-in-order-with-key", + "permanent": false + }, { "source": "/link/invalid-hook-call", "destination": "/warnings/invalid-hook-call-warning",