From a6d3bc6837617b089a2205e3194b6d9f907dd129 Mon Sep 17 00:00:00 2001 From: yuta-ike <38308823+yuta-ike@users.noreply.github.com> Date: Thu, 25 May 2023 22:31:55 +0900 Subject: [PATCH 1/5] Translate "useState" --- src/content/reference/react/useState.md | 254 ++++++++++++------------ 1 file changed, 127 insertions(+), 127 deletions(-) diff --git a/src/content/reference/react/useState.md b/src/content/reference/react/useState.md index d23fa489b..16affb2de 100644 --- a/src/content/reference/react/useState.md +++ b/src/content/reference/react/useState.md @@ -4,7 +4,7 @@ title: useState -`useState` is a React Hook that lets you add a [state variable](/learn/state-a-components-memory) to your component. +`useState` は、コンポーネントに [state 変数](/learn/state-a-components-memory) を追加するための React フックです。 ```js const [state, setState] = useState(initialState); @@ -16,11 +16,11 @@ const [state, setState] = useState(initialState); --- -## Reference {/*reference*/} +## リファレンス {/*reference*/} ### `useState(initialState)` {/*usestate*/} -Call `useState` at the top level of your component to declare a [state variable.](/learn/state-a-components-memory) +コンポーネントのトップレベルで `useState` を呼び出し、[state 変数](/learn/state-a-components-memory) を宣言します。 ```js import { useState } from 'react'; @@ -32,32 +32,32 @@ function MyComponent() { // ... ``` -The convention is to name state variables like `[something, setSomething]` using [array destructuring.](https://javascript.info/destructuring-assignment) +慣習として state 変数は、[分割代入](https://javascript.info/destructuring-assignment)を利用して `[something, setSomething]` のように命名します。 -[See more examples below.](#usage) +[さらに例を見る](#usage) -#### Parameters {/*parameters*/} +#### 引数 {/*parameters*/} -* `initialState`: The value you want the state to be initially. It can be a value of any type, but there is a special behavior for functions. This argument is ignored after the initial render. - * If you pass a function as `initialState`, it will be treated as an _initializer function_. It should be pure, should take no arguments, and should return a value of any type. React will call your initializer function when initializing the component, and store its return value as the initial state. [See an example below.](#avoiding-recreating-the-initial-state) +* `initialState`: state を初期化する値です。どんな型の値でも渡すことができますが、関数を渡した場合は特別な振る舞いがあります。この引数は初回レンダー後は無視されます。 + * `initialState` に関数を渡した場合、その関数は _初期化関数_ として扱われます。初期化関数は、純粋で、引数を取らず、何らかの型の値を返す必要があります。React はコンポーネントを初期化するときに初期化関数を呼び出し、その返り値を初期 state として保存します。[例を見る](#avoiding-recreating-the-initial-state) -#### Returns {/*returns*/} +#### 返り値 {/*returns*/} -`useState` returns an array with exactly two values: +`useState` は以下の 2 つの値を持つ配列を返します。 -1. The current state. During the first render, it will match the `initialState` you have passed. -2. The [`set` function](#setstate) that lets you update the state to a different value and trigger a re-render. +1. 現在の state。初回レンダー中では、`initialState` と同じ値になります。 +2. state を別の値に更新し、再レンダーをトリガする [`set` 関数](#setstate)。 -#### Caveats {/*caveats*/} +#### 注意点 {/*caveats*/} -* `useState` 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. -* In Strict Mode, React will **call your initializer function twice** in order to [help you find accidental impurities.](#my-initializer-or-updater-function-runs-twice) This is development-only behavior and does not affect production. If your initializer function is pure (as it should be), this should not affect the behavior. The result from one of the calls will be ignored. +* `useState` はフックであるため、**コンポーネントのトップレベル**またはカスタムフック内でのみ呼び出すことができます。ループや条件文の中で呼び出すことはできません。これが必要な場合は、新しいコンポーネントを抽出し、state を移動させてください。 +* Strict Mode では、[純粋でない関数を見つけやすくするために](#my-initializer-or-updater-function-runs-twice)、**初期化関数が 2 回呼び出されます**。これは開発時のみの振る舞いであり、本番には影響しません。初期化関数が純粋であれば(そうであるべきです)、2 回呼び出されてもコードに影響はありません。2 回の呼び出しのうち 1 回の呼び出し結果は無視されます。 --- -### `set` functions, like `setSomething(nextState)` {/*setstate*/} +### `setSomething(nextState)` のように利用する `set` 関数 {/*setstate*/} -The `set` function returned by `useState` lets you update the state to a different value and trigger a re-render. You can pass the next state directly, or a function that calculates it from the previous state: +`useState` が返す `set` 関数を利用して、state を別の値に更新し、再レンダーをトリガすることができます。直接次の state を渡すことも、前の state から次の state を導出する関数を渡すこともできます。 ```js const [name, setName] = useState('Edward'); @@ -68,34 +68,34 @@ function handleClick() { // ... ``` -#### Parameters {/*setstate-parameters*/} +#### 引数 {/*setstate-parameters*/} -* `nextState`: The value that you want the state to be. It can be a value of any type, but there is a special behavior for functions. - * If you pass a function as `nextState`, it will be treated as an _updater function_. It must be pure, should take the pending state as its only argument, and should return the next state. React will put your updater function in a queue and re-render your component. During the next render, React will calculate the next state by applying all of the queued updaters to the previous state. [See an example below.](#updating-state-based-on-the-previous-state) +* `nextState`: 次に state にセットしたい値です。どんな型の値でも渡すことができますが、関数を渡した場合は特別な振る舞いがあります。 + * `nextState` に関数を渡した場合は、_更新関数_ として扱われます。更新関数は、純粋で、未確定の state (pending state) を唯一の引数として受け取り、次の state を返す必要があります。React は更新関数をキューに入れ、コンポーネントを再レンダーします。次のレンダーで、React はキューに入れられたすべての更新関数を前の state に対して適用し、次の state を導出します。[例を見る](#updating-state-based-on-the-previous-state) -#### Returns {/*setstate-returns*/} +#### 返り値 {/*setstate-returns*/} -`set` functions do not have a return value. +`set` 関数は返り値を持ちません。 -#### Caveats {/*setstate-caveats*/} +#### 注意点 {/*setstate-caveats*/} -* The `set` function **only updates the state variable for the *next* render**. If you read the state variable after calling the `set` function, [you will still get the old value](#ive-updated-the-state-but-logging-gives-me-the-old-value) that was on the screen before your call. +* `set` 関数は**_次の_****レンダーのための state 変数のみを更新**します。`set` 関数を呼び出した後に state 変数を読み取っても、呼び出し前の画面に表示されていた[古い値が返されます](#ive-updated-the-state-but-logging-gives-me-the-old-value)。 -* If the new value you provide is identical to the current `state`, as determined by an [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) comparison, React will **skip re-rendering the component and its children.** This is an optimization. Although in some cases React may still need to call your component before skipping the children, it shouldn't affect your code. +* 新しい値が現在の `state` と同一の場合、React は最適化のために、**コンポーネントとその子コンポーネントの再レンダーをスキップ**します。state の同一性の比較は、[`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) によって行われます。一部のケースでは、React は子コンポーネントをスキップする前にコンポーネントを呼び出す必要がありますが、あなたのコードに影響を与えることはないはずです。 -* React [batches state updates.](/learn/queueing-a-series-of-state-updates) It updates the screen **after all the event handlers have run** and have called their `set` functions. This prevents multiple re-renders during a single event. In the rare case that you need to force React to update the screen earlier, for example to access the DOM, you can use [`flushSync`.](/reference/react-dom/flushSync) +* React は [state の更新をまとめて行います(バッチ処理)](/learn/queueing-a-series-of-state-updates)。**すべてのイベントハンドラを実行し終え**、`set` 関数が呼び出された後に、画面を更新します。これにより、1 つのイベント中に複数回の再レンダーが発生することはありません。まれに早期に画面を更新する必要がある場合(例えば DOM にアクセスする場合など)がありますが、その場合は [`flushSync`](/reference/react-dom/flushSync) を利用できます。 -* 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) +* レンダリング中に `set` 関数を呼び出すことは、*現在レンダリング中の*コンポーネント内からのみ許されています。React は出力を破棄し、新しい state で再レンダーを試みます。このパターンはほとんど必要ありませんが、**前回のレンダーからの情報を保存**するために使用できます。[例を見る](#storing-information-from-previous-renders) -* In Strict Mode, React will **call your updater function twice** in order to [help you find accidental impurities.](#my-initializer-or-updater-function-runs-twice) This is development-only behavior and does not affect production. If your updater function is pure (as it should be), this should not affect the behavior. The result from one of the calls will be ignored. +* Strict Mode では、[純粋でない関数を見つけやすくするために](#my-initializer-or-updater-function-runs-twice)**更新関数が 2 回呼び出されます**。これは開発時のみの振る舞いであり、本番には影響しません。更新関数が純粋であれば(そうであるべきです)、2 回呼び出されてもコードに影響はありません。2 回の呼び出しのうち 1 回の呼び出し結果は無視されます。 --- -## Usage {/*usage*/} +## 使用法 {/*usage*/} -### Adding state to a component {/*adding-state-to-a-component*/} +### state をコンポーネントに追加する {/*adding-state-to-a-component*/} -Call `useState` at the top level of your component to declare one or more [state variables.](/learn/state-a-components-memory) +コンポーネントのトップレベルで `useState` を呼び出し、1 つ以上の [state 変数](/learn/state-a-components-memory)を宣言します。 ```js [[1, 4, "age"], [2, 4, "setAge"], [3, 4, "42"], [1, 5, "name"], [2, 5, "setName"], [3, 5, "'Taylor'"]] import { useState } from 'react'; @@ -106,14 +106,14 @@ function MyComponent() { // ... ``` -The convention is to name state variables like `[something, setSomething]` using [array destructuring.](https://javascript.info/destructuring-assignment) +慣習として state 変数は、[分割代入](https://javascript.info/destructuring-assignment)を利用して `[something, setSomething]` のように命名します。 -`useState` returns an array with exactly two items: +`useState` は、以下の 2 つの値を持つ配列を返します。 -1. The current state of this state variable, initially set to the initial state you provided. -2. The `set` function that lets you change it to any other value in response to interaction. +1. この state 変数の現在の値。最初は、初期 state に設定されます。 +1. インタラクションに応じて、state を他の値に変更するための`set` 関数。 -To update what’s on the screen, call the `set` function with some next state: +スクリーン上の表示を更新するには、次の state を引数として `set` 関数を呼び出します。 ```js [[2, 2, "setName"]] function handleClick() { @@ -121,11 +121,11 @@ function handleClick() { } ``` -React will store the next state, render your component again with the new values, and update the UI. +React は次の state を保存したあと、新しい値でコンポーネントを再レンダーし、UI を更新します。 -Calling the `set` function [**does not** change the current state in the already executing code](#ive-updated-the-state-but-logging-gives-me-the-old-value): +`set` 関数の呼び出しは、[既に実行されているコードの現在の state を変更するわけでは**ありません**](#ive-updated-the-state-but-logging-gives-me-the-old-value)。 ```js {3} function handleClick() { @@ -134,15 +134,15 @@ function handleClick() { } ``` -It only affects what `useState` will return starting from the *next* render. +この呼び出しは、*次の*レンダーから `useState` が返す値にのみ影響を与えます。 -#### Counter (number) {/*counter-number*/} +#### カウンタ (number) {/*counter-number*/} -In this example, the `count` state variable holds a number. Clicking the button increments it. +この例では、`count` state 変数が数値 (number) を保持しています。ボタンをクリックすることで、数値が増加します。 @@ -168,9 +168,9 @@ export default function Counter() { -#### Text field (string) {/*text-field-string*/} +#### テキストフィールド (string) {/*text-field-string*/} -In this example, the `text` state variable holds a string. When you type, `handleChange` reads the latest input value from the browser input DOM element, and calls `setText` to update the state. This allows you to display the current `text` below. +この例では、`text` state 変数が文字列 (string) を保持しています。ブラウザの DOM の input 要素に文字を入力すると、`handleChange` は input 要素から最新の値を読み出し、`setText` を呼び出して state を更新します。これにより、下部に、現在の `text` を表示できます。 @@ -200,9 +200,9 @@ export default function MyInput() { -#### Checkbox (boolean) {/*checkbox-boolean*/} +#### チェックボックス (boolean) {/*checkbox-boolean*/} -In this example, the `liked` state variable holds a boolean. When you click the input, `setLiked` updates the `liked` state variable with whether the browser checkbox input is checked. The `liked` variable is used to render the text below the checkbox. +この例では、`linked` state 変数が真偽値 (boolean) を保持しています。input をクリックすると、`setLiked` はブラウザのチェックボックスの input がチェックされているかどうかで、`liked` state 変数を更新します。`liked` 変数は、チェックボックスの下のテキストをレンダーするために使用されます。 @@ -236,9 +236,9 @@ export default function MyCheckbox() { -#### Form (two variables) {/*form-two-variables*/} +#### フォーム (2 つの変数) {/*form-two-variables*/} -You can declare more than one state variable in the same component. Each state variable is completely independent. +同じコンポーネントで、複数の state 変数を宣言することができます。それぞれの state 変数は、完全に独立しています。 @@ -276,9 +276,9 @@ button { display: block; margin-top: 10px; } --- -### Updating state based on the previous state {/*updating-state-based-on-the-previous-state*/} +### 直前の state に応じて更新する {/*updating-state-based-on-the-previous-state*/} -Suppose the `age` is `42`. This handler calls `setAge(age + 1)` three times: +`age` が `42` である場合を考えましょう。このハンドラは、`setAge(age + 1)` を 3 回呼び出します。 ```js function handleClick() { @@ -288,9 +288,9 @@ function handleClick() { } ``` -However, after one click, `age` will only be `43` rather than `45`! This is because calling the `set` function [does not update](/learn/state-as-a-snapshot) the `age` state variable in the already running code. So each `setAge(age + 1)` call becomes `setAge(43)`. +しかし、1 回クリックしたあと、`age` は `45` ではなく `43` になります! これは、`set` 関数を呼び出しても、既に実行されているコードの `age` state 変数を[更新するわけではないためです](/learn/state-as-a-snapshot)。そのため、`setAge(age + 1)` の呼び出しは全て `setAge(43)` になります。 -To solve this problem, **you may pass an *updater function*** to `setAge` instead of the next state: +この問題を解消するため、次の state の代わりに、***更新関数*を `setAge` に渡す**ことができます。 ```js [[1, 2, "a", 0], [2, 2, "a + 1"], [1, 3, "a", 0], [2, 3, "a + 1"], [1, 4, "a", 0], [2, 4, "a + 1"]] function handleClick() { @@ -300,39 +300,39 @@ function handleClick() { } ``` -Here, `a => a + 1` is your updater function. It takes the pending state and calculates the next state from it. +ここで、`a => a + 1` は更新関数です。更新関数は、未確定の state (pending state) を受け取り、そこから次の state を導出します。 -React puts your updater functions in a [queue.](/learn/queueing-a-series-of-state-updates) Then, during the next render, it will call them in the same order: +React は更新関数を[キュー](/learn/queueing-a-series-of-state-updates)に入れます。そして、次のレンダー中に、同じ順番で更新関数を呼び出します。 -1. `a => a + 1` will receive `42` as the pending state and return `43` as the next state. -1. `a => a + 1` will receive `43` as the pending state and return `44` as the next state. -1. `a => a + 1` will receive `44` as the pending state and return `45` as the next state. +1. `a => a + 1` は未確定の state として `42` を受け取り、次の state として `43` を返します。 +1. `a => a + 1` は未確定の state として `43` を受け取り、次の state として `44` を返します。 +1. `a => a + 1` は未確定の state として `44` を受け取り、次の state として `45` を返します。 -There are no other queued updates, so React will store `45` as the current state in the end. +キューにはこれ以上の更新関数はないので、React は最終的に `45` を現在の state として保存します。 -By convention, it's common to name the pending state argument for the first letter of the state variable name, like `a` for `age`. However, you may also call it like `prevAge` or something else that you find clearer. +慣習として、未確定の state の引数名には、state 変数名の頭文字 1 文字を利用することが一般的です(例えば、`age` という state 変数に対して、`a` という引数名など)。しかし、`prevAge` など、他の分かりやすい名前を使うこともできます。 -React may [call your updaters twice](#my-initializer-or-updater-function-runs-twice) in development to verify that they are [pure.](/learn/keeping-components-pure) +開発時に[更新関数が 2 回呼び出される](#my-initializer-or-updater-function-runs-twice)ことがあります。これは、更新関数が[純粋](/learn/keeping-components-pure)であることを確認するためです。 -#### Is using an updater always preferred? {/*is-using-an-updater-always-preferred*/} +#### 常に更新関数を利用すべきか {/*is-using-an-updater-always-preferred*/} -You might hear a recommendation to always write code like `setAge(a => a + 1)` if the state you're setting is calculated from the previous state. There is no harm in it, but it is also not always necessary. +新しくセットする値が直前の state から導出される場合には、常に `setAge(a => a + 1)` という書き方をすべきだという意見があります。悪いことではありませんが、必ずしも必要なわけではありません。 -In most cases, there is no difference between these two approaches. React always makes sure that for intentional user actions, like clicks, the `age` state variable would be updated before the next click. This means there is no risk of a click handler seeing a "stale" `age` at the beginning of the event handler. +ほとんどのケースでは、どちらのアプローチでも違いはありません。React は、クリックなどのユーザの意図的な動作に対して、`age` state 変数の更新が次のクリックの前に発生することを保証しています。すなわち、イベントハンドラの開始時に、クリックハンドラが"古い (stale)" `age` を参照してしまうことはありません。 -However, if you do multiple updates within the same event, updaters can be helpful. They're also helpful if accessing the state variable itself is inconvenient (you might run into this when optimizing re-renders). +一方で、同じイベント内で複数回の更新を行う場合、更新関数が役に立ちます。また、state 変数自身を参照することが難しいケースにも有用です(再レンダーの発生を最適化する際に、このケースに遭遇するかもしれません)。 -If you prefer consistency over slightly more verbose syntax, it's reasonable to always write an updater if the state you're setting is calculated from the previous state. If it's calculated from the previous state of some *other* state variable, you might want to combine them into one object and [use a reducer.](/learn/extracting-state-logic-into-a-reducer) +文法のわずかな冗長性よりも一貫性を優先するのであれば、state が直前の state から導出される場合には常に更新関数を書くようにすることも合理的です。もし、state が、他の state 変数の直前の値から導出される場合は、それらを 1 つのオブジェクトにまとめて [reducer を利用する](/learn/extracting-state-logic-into-a-reducer)ことを検討してください。 -#### Passing the updater function {/*passing-the-updater-function*/} +#### 更新関数を渡す {/*passing-the-updater-function*/} -This example passes the updater function, so the "+3" button works. +この例では更新関数を渡しているため、"+3"ボタンはうまく動きます。 @@ -371,9 +371,9 @@ h1 { display: block; margin: 10px; } -#### Passing the next state directly {/*passing-the-next-state-directly*/} +#### 次の state を直接渡す {/*passing-the-next-state-directly*/} -This example **does not** pass the updater function, so the "+3" button **doesn't work as intended**. +この例では更新関数を渡して**いません**。そのため"+3"ボタンは**意図した通りには動きません**。 @@ -416,16 +416,16 @@ h1 { display: block; margin: 10px; } --- -### Updating objects and arrays in state {/*updating-objects-and-arrays-in-state*/} +### オブジェクトや配列の state を更新する {/*updating-objects-and-arrays-in-state*/} -You can put objects and arrays into state. In React, state is considered read-only, so **you should *replace* it rather than *mutate* your existing objects**. For example, if you have a `form` object in state, don't mutate it: +state にオブジェクトや配列をセットすることができます。ただし、React では、state は読み取り専用 (read-only) として扱う必要があります。そのため、state を更新する場合は、**既存のオブジェクトを直接*変更する (mutate)* のではなく、*置き換える (replace)* 必要があります**。例えば、state として `form` オブジェクトを保持している場合、以下のように書き換えてはいけません。 ```js // 🚩 Don't mutate an object in state like this: form.firstName = 'Taylor'; ``` -Instead, replace the whole object by creating a new one: +代わりに、新しいオブジェクトを作成してオブジェクト全体を置き換えてください。 ```js // ✅ Replace state with a new object @@ -435,13 +435,13 @@ setForm({ }); ``` -Read [updating objects in state](/learn/updating-objects-in-state) and [updating arrays in state](/learn/updating-arrays-in-state) to learn more. +詳しくは、[オブジェクトの state を更新する](/learn/updating-objects-in-state)や、[配列の state を更新する](/learn/updating-arrays-in-state)を参照してください。 -#### Form (object) {/*form-object*/} +#### フォーム (オブジェクト) {/*form-object*/} -In this example, the `form` state variable holds an object. Each input has a change handler that calls `setForm` with the next state of the entire form. The `{ ...form }` spread syntax ensures that the state object is replaced rather than mutated. +この例では、`form` state 変数はオブジェクトを保持しています。それぞれの input 要素は change ハンドラを持っており、新しい `form` オブジェクトを引数として `setForm` を呼び出します。`{...form}` のようにスプレッド構文を用いることで、state オブジェクトを(書き換えではなく)確実に置換することができます。 @@ -512,9 +512,9 @@ input { margin-left: 5px; } -#### Form (nested object) {/*form-nested-object*/} +#### フォーム (ネストされたオブジェクト) {/*form-nested-object*/} -In this example, the state is more nested. When you update nested state, you need to create a copy of the object you're updating, as well as any objects "containing" it on the way upwards. Read [updating a nested object](/learn/updating-objects-in-state#updating-a-nested-object) to learn more. +この例では、state がネストされたオブジェクトになっています。ネストされたオブジェクトの state を更新する場合、更新するオブジェクトのコピーを作成する必要があります。さらに、そのオブジェクトを内包する上位のオブジェクトも同様に、コピーを作成する必要があります。詳しくは、[ネストされたオブジェクトの更新](/learn/updating-objects-in-state#updating-a-nested-object)を参照してください。 @@ -624,9 +624,9 @@ img { width: 200px; height: 200px; } -#### List (array) {/*list-array*/} +#### リスト (配列) {/*list-array*/} -In this example, the `todos` state variable holds an array. Each button handler calls `setTodos` with the next version of that array. The `[...todos]` spread syntax, `todos.map()` and `todos.filter()` ensure the state array is replaced rather than mutated. +この例では、`todos` state 変数が配列を保持しています。各ボタンのハンドラは、新しい `todos` state の配列を引数として `setTodos` を呼び出します。スプレッド構文(`[...todos]`)や、`todos.map()`、`todos.filter()` などを利用すると、state の配列を(書き換えではなく)確実に置換することができます。 @@ -791,9 +791,9 @@ ul, li { margin: 0; padding: 0; } -#### Writing concise update logic with Immer {/*writing-concise-update-logic-with-immer*/} +#### Immer で簡潔な更新ロジックを書く {/*writing-concise-update-logic-with-immer*/} -If updating arrays and objects without mutation feels tedious, you can use a library like [Immer](https://github.com/immerjs/use-immer) to reduce repetitive code. Immer lets you write concise code as if you were mutating objects, but under the hood it performs immutable updates: +配列やオブジェクトの state の更新を、書き換えではなく置換で行うことが煩雑に感じる場合、[Immer](https://github.com/immerjs/use-immer) のようなライブラリを用いて繰り返しのコードを減らすことができます。Immer を利用することで、オブジェクトを直接書き換えるようなコードを書くことができます。しかし内部では、イミュータブル(不変, immutable)な更新、すなわち配列やオブジェクトの置換として実行されます。 @@ -882,9 +882,9 @@ function ItemList({ artworks, onToggle }) { --- -### Avoiding recreating the initial state {/*avoiding-recreating-the-initial-state*/} +### 初期 state が再生成されることを防ぐ {/*avoiding-recreating-the-initial-state*/} -React saves the initial state once and ignores it on the next renders. +React は一度だけ初期 state を保存し、以降のレンダーではそれを無視します。 ```js function TodoList() { @@ -892,9 +892,9 @@ function TodoList() { // ... ``` -Although the result of `createInitialTodos()` is only used for the initial render, you're still calling this function on every render. This can be wasteful if it's creating large arrays or performing expensive calculations. +`createInitialTodos()` は全てのレンダーで呼び出されるものの、その結果は初回レンダーでのみ利用されます。これは、`createInitialTodos()`が巨大な配列の生成やコストの高い計算を行っている場合に、無駄が多くなります。 -To solve this, you may **pass it as an _initializer_ function** to `useState` instead: +これを解決するため、以下のように**_初期化関数_****を渡す**ことができます。 ```js function TodoList() { @@ -902,15 +902,15 @@ function TodoList() { // ... ``` -Notice that you’re passing `createInitialTodos`, which is the *function itself*, and not `createInitialTodos()`, which is the result of calling it. If you pass a function to `useState`, React will only call it during initialization. +関数を呼び出した結果である `createInitialTodos()` ではなく、`createInitialTodos` という*関数それ自体*を渡していることに注意してください。`useState` に関数が渡された場合、React は初期化時に、関数を一度だけ呼び出します。 -React may [call your initializers twice](#my-initializer-or-updater-function-runs-twice) in development to verify that they are [pure.](/learn/keeping-components-pure) +初期化関数が[純粋](/learn/keeping-components-pure)であることを確認するため、開発時に[初期化関数が 2 回呼び出される](#my-initializer-or-updater-function-runs-twice)ことがあります。 -#### Passing the initializer function {/*passing-the-initializer-function*/} +#### 初期化関数を渡す {/*passing-the-initializer-function*/} -This example passes the initializer function, so the `createInitialTodos` function only runs during initialization. It does not run when component re-renders, such as when you type into the input. +この例では、初期化関数を利用しています。そのため、`createInitialTodos` 関数は初期化時のみ実行されます。input に文字を入力した場合など、コンポーネントの再レンダー時には実行されません。 @@ -961,9 +961,9 @@ export default function TodoList() { -#### Passing the initial state directly {/*passing-the-initial-state-directly*/} +#### 初期 state を直接渡す {/*passing-the-initial-state-directly*/} -This example **does not** pass the initializer function, so the `createInitialTodos` function runs on every render, such as when you type into the input. There is no observable difference in behavior, but this code is less efficient. +この例では、初期化関数を利用して**いません**。そのため、`createInitialTodos` 関数は、input に文字を入力したときなどの、全てのレンダーで実行されます。挙動に目に見える違いはありませんが、少し効率が悪くなります。 @@ -1018,13 +1018,13 @@ export default function TodoList() { --- -### Resetting state with a key {/*resetting-state-with-a-key*/} +### key を利用して state をリセットする {/*resetting-state-with-a-key*/} -You'll often encounter the `key` attribute when [rendering lists.](/learn/rendering-lists) However, it also serves another purpose. +`key` 属性は、[リストをレンダーする場合](/learn/rendering-lists)によく耳にします。しかし、もう 1 つの使い道があります。 -You can **reset a component's state by passing a different `key` to a component.** In this example, the Reset button changes the `version` state variable, which we pass as a `key` to the `Form`. When the `key` changes, React re-creates the `Form` component (and all of its children) from scratch, so its state gets reset. +**コンポーネントに異なる `key` を渡すことで、コンポーネントの state をリセットすることができます**。この例では、`version` state 変数を `Form` に `key` として渡しています。"Reset" ボタンをクリックすると、`version` state 変数が変化します。`key` が変化したとき、React は `Form` コンポーネント(と、その全ての子コンポーネント)を一から再生成するため、`Form` の state がリセットされます。 -Read [preserving and resetting state](/learn/preserving-and-resetting-state) to learn more. +詳しくは、[state の保存とリセット](/learn/preserving-and-resetting-state)を参照してください。 @@ -1069,19 +1069,19 @@ button { display: block; margin-bottom: 20px; } --- -### Storing information from previous renders {/*storing-information-from-previous-renders*/} +### 直前のレンダーの情報を保存する {/*storing-information-from-previous-renders*/} -Usually, you will update state in event handlers. However, in rare cases you might want to adjust state in response to rendering -- for example, you might want to change a state variable when a prop changes. +通常、state の更新はイベントハンドラの中で行われます。しかし、まレンダーに応じて state を設定したい場合があります。例えば、prop が変化したときに state 変数を変化させたい場合です。 -In most cases, you don't need this: +以下に示すように、ほとんどのケースでは不要です。 -* **If the value you need can be computed entirely from the current props or other state, [remove that redundant state altogether.](/learn/choosing-the-state-structure#avoid-redundant-state)** If you're worried about recomputing too often, the [`useMemo` Hook](/reference/react/useMemo) can help. -* If you want to reset the entire component tree's state, [pass a different `key` to your component.](#resetting-state-with-a-key) -* If you can, update all the relevant state in the event handlers. +* **もし必要な値が現在の props と他の state のみから導出される場合、[冗長な state を削除してください](/learn/choosing-the-state-structure#avoid-redundant-state)。**もし再計算されることが気になる場合は、[`useMemo` フック](/reference/react/useMemo)が役に立ちます。 +* もしコンポーネントツリーの state 全体をリセットしたい場合、[コンポーネントに異なる `key` を渡してください](#resetting-state-with-a-key)。 +* 可能であれば、関連するすべての state をイベントハンドラの中で更新してください。 -In the rare case that none of these apply, there is a pattern you can use to update state based on the values that have been rendered so far, by calling a `set` function while your component is rendering. +これらがどれも適用できない稀なケースで、コンポーネントのレンダー中に `set` 関数を呼び出し、それまでにレンダーされた値に基づいて state を更新するパターンが利用できます。 -Here's an example. This `CountLabel` component displays the `count` prop passed to it: +以下の例では、`CountLabel` コンポーネントは、渡された `count` プロパティを表示しています。 ```js CountLabel.js export default function CountLabel({ count }) { @@ -1089,7 +1089,7 @@ export default function CountLabel({ count }) { } ``` -Say you want to show whether the counter has *increased or decreased* since the last change. The `count` prop doesn't tell you this -- you need to keep track of its previous value. Add the `prevCount` state variable to track it. Add another state variable called `trend` to hold whether the count has increased or decreased. Compare `prevCount` with `count`, and if they're not equal, update both `prevCount` and `trend`. Now you can show both the current count prop and *how it has changed since the last render*. +直近の変更で、counter の値が*増えたのか減ったのか*を表示したいとします。`count` プロパティだけでは知ることができないため、前回の値を追跡する必要があります。前回の値を保持するために、`prevCount` state 変数を追加します。さらに、`trend` state 変数を追加し、count が増えたのか減ったのかを保持します。`prevCount` と `count` を比較し、もしこれらが一致しない場合に、`prevCount` と `trend` を更新します。これで、現在の count プロパティと、*前回のレンダーからどのように変化したのか*の両方を表示することができます。 @@ -1138,17 +1138,17 @@ button { margin-bottom: 10px; } -Note that if you call a `set` function while rendering, it must be inside a condition like `prevCount !== count`, and there must be a call like `setPrevCount(count)` inside of the condition. Otherwise, your component would re-render in a loop until it crashes. Also, you can only update the state of the *currently rendering* component like this. Calling the `set` function of *another* component during rendering is an error. Finally, your `set` call should still [update state without mutation](#updating-objects-and-arrays-in-state) -- this doesn't mean you can break other rules of [pure functions.](/learn/keeping-components-pure) +レンダー中に `set` 関数を呼び出す場合、`prevCount !== count` のような条件節の中で、`setPrevCount(count)` のような呼び出しが必要なことに注意してください。さもないと、再レンダーのループに陥り、コンポーネントがクラッシュします。また、例のように、*現在レンダーしている*コンポーネントの state のみ更新することができます。レンダー中に*別の*コンポーネントの `set` 関数を呼び出すこと、エラーになります。最後に、`set` 関数の呼び出しは、[書き換えなしで state を更新](#updating-objects-and-arrays-in-state)する必要があります。これは、[純関数](/learn/keeping-components-pure)の他のルールを破ることができないことを意味します。 -This pattern can be hard to understand and is usually best avoided. However, it's better than updating state in an effect. When you call the `set` function during render, React will re-render that component immediately after your component exits with a `return` statement, and before rendering the children. This way, children don't need to render twice. The rest of your component function will still execute (and the result will be thrown away). If your condition is below all the Hook calls, you may add an early `return;` to restart rendering earlier. +このパターンは理解するのが難しいため、通常は避けられます。しかし、これは、エフェクト内で state を更新するよりは良い方法です。レンダー中に `set` 関数を呼び出すと、React は、コンポーネントが `return` 文で終了した直後に、そのコンポーネントを再レンダーします。これは、子コンポーネントをレンダーする前に行われます。この方法では、子コンポーネントが 2 回レンダーされることはありません。コンポーネント関数の残りの部分は引き続き実行されます(その結果は破棄されます)。もし、`set` 関数の呼び出すを含む条件節が、全てのフックの呼び出しより下にある場合は、早期に `return;` を追加して、再レンダーを早めることができます。 --- -## Troubleshooting {/*troubleshooting*/} +## トラブルシューティング {/*troubleshooting*/} -### I've updated the state, but logging gives me the old value {/*ive-updated-the-state-but-logging-gives-me-the-old-value*/} +### state を更新したのに、古い値がログに表示される {/*ive-updated-the-state-but-logging-gives-me-the-old-value*/} -Calling the `set` function **does not change state in the running code**: +`set` 関数の呼び出しは、実行中のコードの state を変化**させません**。 ```js {4,5,8} function handleClick() { @@ -1163,9 +1163,9 @@ function handleClick() { } ``` -This is because [states behaves like a snapshot.](/learn/state-as-a-snapshot) Updating state requests another render with the new state value, but does not affect the `count` JavaScript variable in your already-running event handler. +これは、[state がスナップショットのように振る舞う](/learn/state-as-a-snapshot)ためです。state の更新は、新しい state の値での再レンダーをリクエストします。すでに実行中のイベントハンドラ内の `count` という JavaScript 変数には影響を与えません。 -If you need to use the next state, you can save it in a variable before passing it to the `set` function: +次の state が必要な場合は、`set` 関数に渡す前に変数に保存することができます。 ```js const nextCount = count + 1; @@ -1177,16 +1177,16 @@ console.log(nextCount); // 1 --- -### I've updated the state, but the screen doesn't update {/*ive-updated-the-state-but-the-screen-doesnt-update*/} +### state を更新したのに、画面が更新されない {/*ive-updated-the-state-but-the-screen-doesnt-update*/} -React will **ignore your update if the next state is equal to the previous state,** as determined by an [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) comparison. This usually happens when you change an object or an array in state directly: +React では、**更新の前後で state の値が変化しない場合、変更は無視されます**。state の値の変化は、[`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) によって判断されます。これは、state のオブジェクトや配列を直接変更した場合によく起こります。 ```js obj.x = 10; // 🚩 Wrong: mutating existing object setObj(obj); // 🚩 Doesn't do anything ``` -You mutated an existing `obj` object and passed it back to `setObj`, so React ignored the update. To fix this, you need to ensure that you're always [_replacing_ objects and arrays in state instead of _mutating_ them](#updating-objects-and-arrays-in-state): +既存の `obj` オブジェクトを書き換えて、`setObj` に戻したため、この更新は無視されます。修正するには、state のオブジェクトや配列を[*書き換える*のではなく、*置き換える*](#updating-objects-and-arrays-in-state)必要があります。 ```js // ✅ Correct: creating a new object @@ -1198,9 +1198,9 @@ setObj({ --- -### I'm getting an error: "Too many re-renders" {/*im-getting-an-error-too-many-re-renders*/} +### "Too many re-renders" というエラーが出る {/*im-getting-an-error-too-many-re-renders*/} -You might get an error that says: `Too many re-renders. React limits the number of renders to prevent an infinite loop.` Typically, this means that you're unconditionally setting state *during render*, so your component enters a loop: render, set state (which causes a render), render, set state (which causes a render), and so on. Very often, this is caused by a mistake in specifying an event handler: +`Too many re-renders. React limits the number of renders to prevent an infinite loop.` というエラーが出ることがあります。これは、通常、*レンダー中に*無条件に `set` 関数を呼び出しているため、コンポーネントがループに入っていることを意味します。レンダー、`set` 関数の呼び出し(レンダーを引き起こす)、レンダー、`set` 関数の呼び出し(レンダーを引き起こす)、というように続きます。これは、イベントハンドラの指定に間違いがあることが多いです。 ```js {1-2} // 🚩 Wrong: calls the handler during render @@ -1213,13 +1213,13 @@ return return ``` -If you can't find the cause of this error, click on the arrow next to the error in the console and look through the JavaScript stack to find the specific `set` function call responsible for the error. +このエラーの原因がわからない場合は、コンソールのエラーの横にある矢印をクリックして、JavaScript スタックを調べ、エラーの原因となる `set` 関数の呼び出しを特定します。 --- -### My initializer or updater function runs twice {/*my-initializer-or-updater-function-runs-twice*/} +### 初期化関数や更新関数が2度呼ばれる {/*my-initializer-or-updater-function-runs-twice*/} -In [Strict Mode](/reference/react/StrictMode), React will call some of your functions twice instead of once: +[Strict Mode](/reference/react/StrictMode) では、React はいくつかの関数を、本来 1 回のところを 2 回呼び出すことがあります。 ```js {2,5-6,11-12} function TodoList() { @@ -1239,11 +1239,11 @@ function TodoList() { // ... ``` -This is expected and shouldn't break your code. +これは予想される動作であり、コードを壊すことはありません。 -This **development-only** behavior helps you [keep components pure.](/learn/keeping-components-pure) React uses the result of one of the calls, and ignores the result of the other call. As long as your component, initializer, and updater functions are pure, this shouldn't affect your logic. However, if they are accidentally impure, this helps you notice the mistakes. +この **開発時のみ** の挙動は、[コンポーネントを純粋に保つ](/learn/keeping-components-pure)ために役立ちます。React は、2 つの呼び出しのうちの 1 つの結果を利用し、もう 1 つの呼び出しの結果を無視します。コンポーネント、初期化関数、更新関数が純粋であれば、これはロジックに影響しません。ただし、誤って純粋でない関数を指定した場合は、これにより間違いに気付くことができます。 -For example, this impure updater function mutates an array in state: +例えば、この純粋でない更新関数は、state の配列を変更します。 ```js {2,3} setTodos(prevTodos => { @@ -1252,7 +1252,7 @@ setTodos(prevTodos => { }); ``` -Because React calls your updater function twice, you'll see the todo was added twice, so you'll know that there is a mistake. In this example, you can fix the mistake by [replacing the array instead of mutating it](#updating-objects-and-arrays-in-state): +React は更新関数を 2 回呼び出すため、todo が 2 回追加されたことがわかり、間違いに気付くことができます。この例では、[配列を書き換えるのではなく、配列を置き換える](#updating-objects-and-arrays-in-state)ことで間違いを修正できます。 ```js {2,3} setTodos(prevTodos => { @@ -1261,15 +1261,15 @@ setTodos(prevTodos => { }); ``` -Now that this updater function is pure, calling it an extra time doesn't make a difference in behavior. This is why React calling it twice helps you find mistakes. **Only component, initializer, and updater functions need to be pure.** Event handlers don't need to be pure, so React will never call your event handlers twice. +この更新関数が純粋になったので、複数回呼び出しても動作に影響しません。これが、React が 2 回呼び出すことで間違いに気付くことができる理由です。**コンポーネント、初期化関数、更新関数のみが純粋である必要があります。**イベントハンドラは純粋である必要はないため、React がイベントハンドラを 2 回呼び出すことはありません。 -Read [keeping components pure](/learn/keeping-components-pure) to learn more. +詳しくは、[コンポーネントを純粋に保つ](/learn/keeping-components-pure)を参照してください。 --- -### I'm trying to set state to a function, but it gets called instead {/*im-trying-to-set-state-to-a-function-but-it-gets-called-instead*/} +### 関数を state にセットしようとすると、関数が呼び出されてしまう {/*im-trying-to-set-state-to-a-function-but-it-gets-called-instead*/} -You can't put a function into state like this: +このような形で関数を state に設定することはできません。 ```js const [fn, setFn] = useState(someFunction); @@ -1279,7 +1279,7 @@ function handleClick() { } ``` -Because you're passing a function, React assumes that `someFunction` is an [initializer function](#avoiding-recreating-the-initial-state), and that `someOtherFunction` is an [updater function](#updating-state-based-on-the-previous-state), so it tries to call them and store the result. To actually *store* a function, you have to put `() =>` before them in both cases. Then React will store the functions you pass. +関数を渡すと、React は `someFunction` を [初期化関数](#avoiding-recreating-the-initial-state) 、`someOtherFunction` を [更新関数](#updating-state-based-on-the-previous-state) として扱います。そのため、それらを呼び出し、その結果を保存しようとします。関数自体を *保存* するには、どちらの場合も `() =>` を前に付ける必要があります。こうすると、React は関数自体を保存します。 ```js {1,4} const [fn, setFn] = useState(() => someFunction); From 7f8ce21161480db415b30445bc4e05b4a05061bb Mon Sep 17 00:00:00 2001 From: yuta-ike <38308823+yuta-ike@users.noreply.github.com> Date: Fri, 26 May 2023 09:23:26 +0900 Subject: [PATCH 2/5] fix "useState" translation --- src/content/reference/react/useState.md | 96 ++++++++++++------------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/src/content/reference/react/useState.md b/src/content/reference/react/useState.md index 16affb2de..0360711bc 100644 --- a/src/content/reference/react/useState.md +++ b/src/content/reference/react/useState.md @@ -20,7 +20,7 @@ const [state, setState] = useState(initialState); ### `useState(initialState)` {/*usestate*/} -コンポーネントのトップレベルで `useState` を呼び出し、[state 変数](/learn/state-a-components-memory) を宣言します。 +コンポーネントのトップレベルで `useState` を呼び出して、[state 変数](/learn/state-a-components-memory) を宣言します。 ```js import { useState } from 'react'; @@ -32,14 +32,14 @@ function MyComponent() { // ... ``` -慣習として state 変数は、[分割代入](https://javascript.info/destructuring-assignment)を利用して `[something, setSomething]` のように命名します。 +state 変数は慣習として、[分割代入](https://javascript.info/destructuring-assignment)を利用して `[something, setSomething]` のように命名します。 [さらに例を見る](#usage) #### 引数 {/*parameters*/} -* `initialState`: state を初期化する値です。どんな型の値でも渡すことができますが、関数を渡した場合は特別な振る舞いがあります。この引数は初回レンダー後は無視されます。 - * `initialState` に関数を渡した場合、その関数は _初期化関数_ として扱われます。初期化関数は、純粋で、引数を取らず、何らかの型の値を返す必要があります。React はコンポーネントを初期化するときに初期化関数を呼び出し、その返り値を初期 state として保存します。[例を見る](#avoiding-recreating-the-initial-state) +* `initialState`: state の初期値です。どんな型の値でも渡すことができますが、関数を渡した場合は特別な振る舞いをします。この引数は初回レンダー後は無視されます。 + * `initialState` に関数を渡した場合、その関数は*初期化関数*として扱われます。初期化関数は、純粋で、引数を取らず、何らかの型の値を返す必要があります。React はコンポーネントを初期化するときに初期化関数を呼び出し、その返り値を初期 state として保存します。[例を見る](#avoiding-recreating-the-initial-state) #### 返り値 {/*returns*/} @@ -57,7 +57,7 @@ function MyComponent() { ### `setSomething(nextState)` のように利用する `set` 関数 {/*setstate*/} -`useState` が返す `set` 関数を利用して、state を別の値に更新し、再レンダーをトリガすることができます。直接次の state を渡すことも、前の state から次の state を導出する関数を渡すこともできます。 +`useState` が返す `set` 関数を利用して、state を別の値に更新し、再レンダーをトリガすることができます。直接次の state を渡すか、前の state から次の state を導出する関数を渡します。 ```js const [name, setName] = useState('Edward'); @@ -70,8 +70,8 @@ function handleClick() { #### 引数 {/*setstate-parameters*/} -* `nextState`: 次に state にセットしたい値です。どんな型の値でも渡すことができますが、関数を渡した場合は特別な振る舞いがあります。 - * `nextState` に関数を渡した場合は、_更新関数_ として扱われます。更新関数は、純粋で、未確定の state (pending state) を唯一の引数として受け取り、次の state を返す必要があります。React は更新関数をキューに入れ、コンポーネントを再レンダーします。次のレンダーで、React はキューに入れられたすべての更新関数を前の state に対して適用し、次の state を導出します。[例を見る](#updating-state-based-on-the-previous-state) +* `nextState`: 次に state にセットしたい値です。どんな型の値でも渡すことができますが、関数を渡した場合は特別な振る舞いをします。 + * `nextState` に関数を渡した場合、その関数は*更新関数*として扱われます。更新関数は、純粋で、未確定の state (pending state) を唯一の引数として受け取り、次の state を返す必要があります。React は更新関数をキューに入れ、コンポーネントを再レンダーします。次のレンダーで、React はキューに入れられたすべての更新関数を前の state に対して適用し、次の state を導出します。[例を見る](#updating-state-based-on-the-previous-state) #### 返り値 {/*setstate-returns*/} @@ -79,13 +79,13 @@ function handleClick() { #### 注意点 {/*setstate-caveats*/} -* `set` 関数は**_次の_****レンダーのための state 変数のみを更新**します。`set` 関数を呼び出した後に state 変数を読み取っても、呼び出し前の画面に表示されていた[古い値が返されます](#ive-updated-the-state-but-logging-gives-me-the-old-value)。 +* `set` 関数は***次の*レンダーのための state 変数のみを更新**します。`set` 関数を呼び出した後に state 変数を読み取っても、呼び出し前の画面に表示されていた[古い値が返されます](#ive-updated-the-state-but-logging-gives-me-the-old-value)。 * 新しい値が現在の `state` と同一の場合、React は最適化のために、**コンポーネントとその子コンポーネントの再レンダーをスキップ**します。state の同一性の比較は、[`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) によって行われます。一部のケースでは、React は子コンポーネントをスキップする前にコンポーネントを呼び出す必要がありますが、あなたのコードに影響を与えることはないはずです。 -* React は [state の更新をまとめて行います(バッチ処理)](/learn/queueing-a-series-of-state-updates)。**すべてのイベントハンドラを実行し終え**、`set` 関数が呼び出された後に、画面を更新します。これにより、1 つのイベント中に複数回の再レンダーが発生することはありません。まれに早期に画面を更新する必要がある場合(例えば DOM にアクセスする場合など)がありますが、その場合は [`flushSync`](/reference/react-dom/flushSync) を利用できます。 +* React は [state の更新をまとめて行います(バッチ処理)](/learn/queueing-a-series-of-state-updates)。**すべてのイベントハンドラを実行し終え**、`set` 関数が呼び出された後に、画面を更新します。これにより、1 つのイベント中に複数回の再レンダーが発生することはありません。まれに、早期に画面を更新する必要がある場合(例えば DOM にアクセスする場合など)がありますが、その場合は [`flushSync`](/reference/react-dom/flushSync) を利用できます。 -* レンダリング中に `set` 関数を呼び出すことは、*現在レンダリング中の*コンポーネント内からのみ許されています。React は出力を破棄し、新しい state で再レンダーを試みます。このパターンはほとんど必要ありませんが、**前回のレンダーからの情報を保存**するために使用できます。[例を見る](#storing-information-from-previous-renders) +* レンダリング中に `set` 関数を呼び出すことは、*現在レンダリング中の*コンポーネント内からのみ許されています。その場合、React はその出力を破棄し、新しい state で再レンダーを試みます。このパターンが必要になることはほとんどありませんが、**前回のレンダーからの情報を保存**するために使用できます。[例を見る](#storing-information-from-previous-renders) * Strict Mode では、[純粋でない関数を見つけやすくするために](#my-initializer-or-updater-function-runs-twice)**更新関数が 2 回呼び出されます**。これは開発時のみの振る舞いであり、本番には影響しません。更新関数が純粋であれば(そうであるべきです)、2 回呼び出されてもコードに影響はありません。2 回の呼び出しのうち 1 回の呼び出し結果は無視されます。 @@ -106,7 +106,7 @@ function MyComponent() { // ... ``` -慣習として state 変数は、[分割代入](https://javascript.info/destructuring-assignment)を利用して `[something, setSomething]` のように命名します。 +state 変数は慣習として、[分割代入](https://javascript.info/destructuring-assignment)を利用して `[something, setSomething]` のように命名します。 `useState` は、以下の 2 つの値を持つ配列を返します。 @@ -134,7 +134,7 @@ function handleClick() { } ``` -この呼び出しは、*次の*レンダーから `useState` が返す値にのみ影響を与えます。 +この呼び出しは、*次の*レンダー以降に `useState` が返す値にのみ影響を与えます。 @@ -288,7 +288,7 @@ function handleClick() { } ``` -しかし、1 回クリックしたあと、`age` は `45` ではなく `43` になります! これは、`set` 関数を呼び出しても、既に実行されているコードの `age` state 変数を[更新するわけではないためです](/learn/state-as-a-snapshot)。そのため、`setAge(age + 1)` の呼び出しは全て `setAge(43)` になります。 +しかし、1 回クリックしたあと、`age` は `45` ではなく `43` になります! これは、`set` 関数を呼び出しても、既に実行されているコードの `age` state 変数を[更新するわけではない](/learn/state-as-a-snapshot)ためです。そのため、`setAge(age + 1)` の呼び出しは全て `setAge(43)` になります。 この問題を解消するため、次の state の代わりに、***更新関数*を `setAge` に渡す**ことができます。 @@ -310,7 +310,7 @@ React は更新関数を[キュー](/learn/queueing-a-series-of-state-updates) キューにはこれ以上の更新関数はないので、React は最終的に `45` を現在の state として保存します。 -慣習として、未確定の state の引数名には、state 変数名の頭文字 1 文字を利用することが一般的です(例えば、`age` という state 変数に対して、`a` という引数名など)。しかし、`prevAge` など、他の分かりやすい名前を使うこともできます。 +慣習として、未確定の state の引数名には、state 変数名の頭文字 1 文字を利用することが一般的です(例えば、`age` という state 変数に対して、`a` という引数名)。しかし、`prevAge` など、他の分かりやすい名前を使うこともできます。 開発時に[更新関数が 2 回呼び出される](#my-initializer-or-updater-function-runs-twice)ことがあります。これは、更新関数が[純粋](/learn/keeping-components-pure)であることを確認するためです。 @@ -318,21 +318,21 @@ React は更新関数を[キュー](/learn/queueing-a-series-of-state-updates) #### 常に更新関数を利用すべきか {/*is-using-an-updater-always-preferred*/} -新しくセットする値が直前の state から導出される場合には、常に `setAge(a => a + 1)` という書き方をすべきだという意見があります。悪いことではありませんが、必ずしも必要なわけではありません。 +新しくセットする値が直前の state から導出される場合、常に `setAge(a => a + 1)` という書き方をすべきだという意見があります。悪いことではありませんが、必ずしも必要なわけではありません。 -ほとんどのケースでは、どちらのアプローチでも違いはありません。React は、クリックなどのユーザの意図的な動作に対して、`age` state 変数の更新が次のクリックの前に発生することを保証しています。すなわち、イベントハンドラの開始時に、クリックハンドラが"古い (stale)" `age` を参照してしまうことはありません。 +ほとんどのケースでは、どちらのアプローチでも違いはありません。React は、クリックなどのユーザの意図的なアクションに対して、`age` state 変数の更新が次のクリックの前に発生することを保証しています。すなわち、イベントハンドラの開始時に、クリックハンドラが"古い (stale)" `age` を参照してしまうことはありません。 -一方で、同じイベント内で複数回の更新を行う場合、更新関数が役に立ちます。また、state 変数自身を参照することが難しいケースにも有用です(再レンダーの発生を最適化する際に、このケースに遭遇するかもしれません)。 +一方で、同じイベント内で複数回の更新を行う場合、更新関数が役に立ちます。また、state 変数自身を参照することが難しいケースにも有用です(再レンダーの発生を最適化する際に、このケースに遭遇することがあります)。 -文法のわずかな冗長性よりも一貫性を優先するのであれば、state が直前の state から導出される場合には常に更新関数を書くようにすることも合理的です。もし、state が、他の state 変数の直前の値から導出される場合は、それらを 1 つのオブジェクトにまとめて [reducer を利用する](/learn/extracting-state-logic-into-a-reducer)ことを検討してください。 +わずかな文法の冗長性よりも一貫性を優先するのであれば、state が直前の state から導出される場合には、常に更新関数を書くようにすることは合理的です。もし、state が、他の state 変数の直前の値から導出される場合は、それらを 1 つのオブジェクトにまとめて [reducer を利用する](/learn/extracting-state-logic-into-a-reducer)ことを検討してください。 - + #### 更新関数を渡す {/*passing-the-updater-function*/} -この例では更新関数を渡しているため、"+3"ボタンはうまく動きます。 +この例では更新関数を渡しているため、"+3"ボタンは想定通りに動きます。 @@ -418,7 +418,7 @@ h1 { display: block; margin: 10px; } ### オブジェクトや配列の state を更新する {/*updating-objects-and-arrays-in-state*/} -state にオブジェクトや配列をセットすることができます。ただし、React では、state は読み取り専用 (read-only) として扱う必要があります。そのため、state を更新する場合は、**既存のオブジェクトを直接*変更する (mutate)* のではなく、*置き換える (replace)* 必要があります**。例えば、state として `form` オブジェクトを保持している場合、以下のように書き換えてはいけません。 +state にオブジェクトや配列をセットすることができます。ただし React では、state は読み取り専用 (read-only) として扱う必要があります。そのため、state を更新する場合は、**既存のオブジェクトを直接*変更する (mutate)* のではなく、*置き換える (replace)* 必要があります**。例えば、state として `form` オブジェクトを保持している場合、以下のように書き換えを行ってはいけません。 ```js // 🚩 Don't mutate an object in state like this: @@ -437,7 +437,7 @@ setForm({ 詳しくは、[オブジェクトの state を更新する](/learn/updating-objects-in-state)や、[配列の state を更新する](/learn/updating-arrays-in-state)を参照してください。 - + #### フォーム (オブジェクト) {/*form-object*/} @@ -884,7 +884,7 @@ function ItemList({ artworks, onToggle }) { ### 初期 state が再生成されることを防ぐ {/*avoiding-recreating-the-initial-state*/} -React は一度だけ初期 state を保存し、以降のレンダーではそれを無視します。 +React は一度だけ初期 state を保存し、2 回目以降のレンダーではそれを無視します。 ```js function TodoList() { @@ -892,9 +892,9 @@ function TodoList() { // ... ``` -`createInitialTodos()` は全てのレンダーで呼び出されるものの、その結果は初回レンダーでのみ利用されます。これは、`createInitialTodos()`が巨大な配列の生成やコストの高い計算を行っている場合に、無駄が多くなります。 +`createInitialTodos()` は毎レンダーで呼び出されるものの、その結果は初回レンダーでのみ利用されます。これは、`createInitialTodos()`が巨大な配列の生成やコストの高い計算を行っている場合に、無駄が多くなります。 -これを解決するため、以下のように**_初期化関数_****を渡す**ことができます。 +これを解決するため、以下のように***初期化関数*を渡す**ことができます。 ```js function TodoList() { @@ -906,11 +906,11 @@ function TodoList() { 初期化関数が[純粋](/learn/keeping-components-pure)であることを確認するため、開発時に[初期化関数が 2 回呼び出される](#my-initializer-or-updater-function-runs-twice)ことがあります。 - + #### 初期化関数を渡す {/*passing-the-initializer-function*/} -この例では、初期化関数を利用しています。そのため、`createInitialTodos` 関数は初期化時のみ実行されます。input に文字を入力した場合など、コンポーネントの再レンダー時には実行されません。 +この例では、初期化関数を利用しています。そのため、`createInitialTodos` 関数は初期化時のみ実行されます。input に文字を入力した場合などの、コンポーネントの再レンダー時には実行されません。 @@ -963,7 +963,7 @@ export default function TodoList() { #### 初期 state を直接渡す {/*passing-the-initial-state-directly*/} -この例では、初期化関数を利用して**いません**。そのため、`createInitialTodos` 関数は、input に文字を入力したときなどの、全てのレンダーで実行されます。挙動に目に見える違いはありませんが、少し効率が悪くなります。 +この例では、初期化関数を利用して**いません**。そのため、`createInitialTodos` 関数は、input に文字を入力したときなどの全てのレンダーで実行されます。挙動に目に見える違いはありませんが、少し効率が悪くなります。 @@ -1020,7 +1020,7 @@ export default function TodoList() { ### key を利用して state をリセットする {/*resetting-state-with-a-key*/} -`key` 属性は、[リストをレンダーする場合](/learn/rendering-lists)によく耳にします。しかし、もう 1 つの使い道があります。 +`key` 属性は、[リストをレンダーする場合](/learn/rendering-lists)によく利用します。しかし、もう 1 つの使い道があります。 **コンポーネントに異なる `key` を渡すことで、コンポーネントの state をリセットすることができます**。この例では、`version` state 変数を `Form` に `key` として渡しています。"Reset" ボタンをクリックすると、`version` state 変数が変化します。`key` が変化したとき、React は `Form` コンポーネント(と、その全ての子コンポーネント)を一から再生成するため、`Form` の state がリセットされます。 @@ -1071,11 +1071,11 @@ button { display: block; margin-bottom: 20px; } ### 直前のレンダーの情報を保存する {/*storing-information-from-previous-renders*/} -通常、state の更新はイベントハンドラの中で行われます。しかし、まレンダーに応じて state を設定したい場合があります。例えば、prop が変化したときに state 変数を変化させたい場合です。 +通常、state の更新はイベントハンドラの中で行われます。しかし、レンダーに応じて state を設定したい場合があります。例えば、prop が変化したときに state 変数を変化させたい場合です。 以下に示すように、ほとんどのケースでは不要です。 -* **もし必要な値が現在の props と他の state のみから導出される場合、[冗長な state を削除してください](/learn/choosing-the-state-structure#avoid-redundant-state)。**もし再計算されることが気になる場合は、[`useMemo` フック](/reference/react/useMemo)が役に立ちます。 +* **もし必要な値が現在の props と他の state のみから導出される場合、[冗長な state を削除してください](/learn/choosing-the-state-structure#avoid-redundant-state)**。もし再計算されることが気になる場合は、[`useMemo` フック](/reference/react/useMemo)が役に立ちます。 * もしコンポーネントツリーの state 全体をリセットしたい場合、[コンポーネントに異なる `key` を渡してください](#resetting-state-with-a-key)。 * 可能であれば、関連するすべての state をイベントハンドラの中で更新してください。 @@ -1089,7 +1089,7 @@ export default function CountLabel({ count }) { } ``` -直近の変更で、counter の値が*増えたのか減ったのか*を表示したいとします。`count` プロパティだけでは知ることができないため、前回の値を追跡する必要があります。前回の値を保持するために、`prevCount` state 変数を追加します。さらに、`trend` state 変数を追加し、count が増えたのか減ったのかを保持します。`prevCount` と `count` を比較し、もしこれらが一致しない場合に、`prevCount` と `trend` を更新します。これで、現在の count プロパティと、*前回のレンダーからどのように変化したのか*の両方を表示することができます。 +直近の変更で、counter の値が*増えたのか減ったのか*を表示したいとします。`count` プロパティだけでは知ることができないため、前回の値を保持し続ける必要があります。前回の値を保持するために、`prevCount` state 変数を追加します。さらに、`trend` state 変数を追加し、count が増えたのか減ったのかを保持します。`prevCount` と `count` を比較し、もしこれらが一致しない場合に、`prevCount` と `trend` を更新します。これで、現在の count プロパティと、*前回のレンダーからどのように変化したのか*の両方を表示することができます。 @@ -1138,15 +1138,15 @@ button { margin-bottom: 10px; } -レンダー中に `set` 関数を呼び出す場合、`prevCount !== count` のような条件節の中で、`setPrevCount(count)` のような呼び出しが必要なことに注意してください。さもないと、再レンダーのループに陥り、コンポーネントがクラッシュします。また、例のように、*現在レンダーしている*コンポーネントの state のみ更新することができます。レンダー中に*別の*コンポーネントの `set` 関数を呼び出すこと、エラーになります。最後に、`set` 関数の呼び出しは、[書き換えなしで state を更新](#updating-objects-and-arrays-in-state)する必要があります。これは、[純関数](/learn/keeping-components-pure)の他のルールを破ることができないことを意味します。 +レンダー中に `set` 関数を呼び出す場合は、`prevCount !== count` のような条件節の中で、`setPrevCount(count)` のような呼び出しが必要なことに注意してください。さもないと、再レンダーのループに陥り、コンポーネントがクラッシュします。また、例のように、*現在レンダーしている*コンポーネントの state のみ更新することができます。レンダー中に*別の*コンポーネントの `set` 関数を呼び出すとエラーになります。最後に、`set` 関数の呼び出しは、[書き換えなしで state を更新](#updating-objects-and-arrays-in-state)する必要があります。これは、[純関数](/learn/keeping-components-pure)の他のルールを破ることができないことを意味します。 -このパターンは理解するのが難しいため、通常は避けられます。しかし、これは、エフェクト内で state を更新するよりは良い方法です。レンダー中に `set` 関数を呼び出すと、React は、コンポーネントが `return` 文で終了した直後に、そのコンポーネントを再レンダーします。これは、子コンポーネントをレンダーする前に行われます。この方法では、子コンポーネントが 2 回レンダーされることはありません。コンポーネント関数の残りの部分は引き続き実行されます(その結果は破棄されます)。もし、`set` 関数の呼び出すを含む条件節が、全てのフックの呼び出しより下にある場合は、早期に `return;` を追加して、再レンダーを早めることができます。 +このパターンは理解するのが難しいため、通常は避けられます。しかし、エフェクト内で state を更新するよりは良い方法です。レンダー中に `set` 関数を呼び出すと、コンポーネントが `return` 文で終了した直後に再レンダーが行われます。これは、子コンポーネントをレンダーする前に行われ、子コンポーネントが 2 回レンダーされることはありません。コンポーネント関数の残りの部分は引き続き実行されます(その結果は破棄されます)。もし、`set` 関数の呼び出しを含む条件節が、全てのフックの呼び出しより下にある場合、早期に `return;` を追加して、再レンダーを早めることができます。 --- ## トラブルシューティング {/*troubleshooting*/} -### state を更新したのに、古い値がログに表示される {/*ive-updated-the-state-but-logging-gives-me-the-old-value*/} +### state を更新したのに古い値がログに表示される {/*ive-updated-the-state-but-logging-gives-me-the-old-value*/} `set` 関数の呼び出しは、実行中のコードの state を変化**させません**。 @@ -1165,7 +1165,7 @@ function handleClick() { これは、[state がスナップショットのように振る舞う](/learn/state-as-a-snapshot)ためです。state の更新は、新しい state の値での再レンダーをリクエストします。すでに実行中のイベントハンドラ内の `count` という JavaScript 変数には影響を与えません。 -次の state が必要な場合は、`set` 関数に渡す前に変数に保存することができます。 +次の state が必要な場合は、`set` 関数に渡す前に一度変数に保存することができます。 ```js const nextCount = count + 1; @@ -1177,9 +1177,9 @@ console.log(nextCount); // 1 --- -### state を更新したのに、画面が更新されない {/*ive-updated-the-state-but-the-screen-doesnt-update*/} +### state を更新したのに画面が更新されない {/*ive-updated-the-state-but-the-screen-doesnt-update*/} -React では、**更新の前後で state の値が変化しない場合、変更は無視されます**。state の値の変化は、[`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) によって判断されます。これは、state のオブジェクトや配列を直接変更した場合によく起こります。 +React では、**更新の前後で state の値が変化しない場合、その変更は無視されます**。state の値の変化は、[`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) によって判断されます。これは、state のオブジェクトや配列を直接書き換えた場合によく起こります。 ```js obj.x = 10; // 🚩 Wrong: mutating existing object @@ -1200,7 +1200,7 @@ setObj({ ### "Too many re-renders" というエラーが出る {/*im-getting-an-error-too-many-re-renders*/} -`Too many re-renders. React limits the number of renders to prevent an infinite loop.` というエラーが出ることがあります。これは、通常、*レンダー中に*無条件に `set` 関数を呼び出しているため、コンポーネントがループに入っていることを意味します。レンダー、`set` 関数の呼び出し(レンダーを引き起こす)、レンダー、`set` 関数の呼び出し(レンダーを引き起こす)、というように続きます。これは、イベントハンドラの指定に間違いがあることが多いです。 +`Too many re-renders. React limits the number of renders to prevent an infinite loop.` というエラーが出ることがあります。これは通常、*レンダー中に*無条件に `set` 関数を呼び出しているため、コンポーネントがループに入っていることを意味します。レンダー、`set` 関数の呼び出し(レンダーを引き起こす)、レンダー、`set` 関数の呼び出し(レンダーを引き起こす)、というように続きます。これは、イベントハンドラの指定に間違いがあることが多いです。 ```js {1-2} // 🚩 Wrong: calls the handler during render @@ -1213,13 +1213,13 @@ return return ``` -このエラーの原因がわからない場合は、コンソールのエラーの横にある矢印をクリックして、JavaScript スタックを調べ、エラーの原因となる `set` 関数の呼び出しを特定します。 +このエラーの原因がわからない場合は、コンソールのエラーの横にある矢印をクリックして、JavaScript スタックを調べ、エラーの原因となる `set` 関数の呼び出しを特定してください。 --- ### 初期化関数や更新関数が2度呼ばれる {/*my-initializer-or-updater-function-runs-twice*/} -[Strict Mode](/reference/react/StrictMode) では、React はいくつかの関数を、本来 1 回のところを 2 回呼び出すことがあります。 +[Strict Mode](/reference/react/StrictMode) では、いくつかの関数が、本来 1 回のところを 2 回呼び出されることがあります。 ```js {2,5-6,11-12} function TodoList() { @@ -1239,11 +1239,11 @@ function TodoList() { // ... ``` -これは予想される動作であり、コードを壊すことはありません。 +これは予想される動作であり、あなたのコードを壊すものではありません。 -この **開発時のみ** の挙動は、[コンポーネントを純粋に保つ](/learn/keeping-components-pure)ために役立ちます。React は、2 つの呼び出しのうちの 1 つの結果を利用し、もう 1 つの呼び出しの結果を無視します。コンポーネント、初期化関数、更新関数が純粋であれば、これはロジックに影響しません。ただし、誤って純粋でない関数を指定した場合は、これにより間違いに気付くことができます。 +これは**開発時のみ**の挙動で、[コンポーネントを純粋に保つ](/learn/keeping-components-pure)ために役立ちます。React は、呼び出し結果の 1 つを利用し、もう 1 つを無視します。コンポーネント、初期化関数、更新関数が純粋であれば、この挙動があなたのロジックに影響を与えることはありません。ただし、誤って純粋でない関数を指定した場合は、これにより間違いに気付くことができるでしょう。 -例えば、この純粋でない更新関数は、state の配列を変更します。 +例えば以下の更新関数は、state の配列を書き換えるため純粋ではありません。 ```js {2,3} setTodos(prevTodos => { @@ -1252,7 +1252,7 @@ setTodos(prevTodos => { }); ``` -React は更新関数を 2 回呼び出すため、todo が 2 回追加されたことがわかり、間違いに気付くことができます。この例では、[配列を書き換えるのではなく、配列を置き換える](#updating-objects-and-arrays-in-state)ことで間違いを修正できます。 +React は更新関数を 2 回呼び出すため、todo が 2 つ追加されてしまい、間違いに気付くことができます。この例では、配列を[書き換えるのではなく、置き換える](#updating-objects-and-arrays-in-state)ことで間違いを修正できます。 ```js {2,3} setTodos(prevTodos => { @@ -1261,13 +1261,13 @@ setTodos(prevTodos => { }); ``` -この更新関数が純粋になったので、複数回呼び出しても動作に影響しません。これが、React が 2 回呼び出すことで間違いに気付くことができる理由です。**コンポーネント、初期化関数、更新関数のみが純粋である必要があります。**イベントハンドラは純粋である必要はないため、React がイベントハンドラを 2 回呼び出すことはありません。 +更新関数が純粋になったため、複数回呼び出されても動作に影響しません。これが、2 回呼び出されることで間違いに気付くことができる理由です。**コンポーネント、初期化関数、更新関数のみが純粋である必要があります**。イベントハンドラは、純粋である必要がないため、2 回呼び出されることはありません。 詳しくは、[コンポーネントを純粋に保つ](/learn/keeping-components-pure)を参照してください。 --- -### 関数を state にセットしようとすると、関数が呼び出されてしまう {/*im-trying-to-set-state-to-a-function-but-it-gets-called-instead*/} +### 関数を state にセットしようとすると、その関数が呼び出されてしまう {/*im-trying-to-set-state-to-a-function-but-it-gets-called-instead*/} このような形で関数を state に設定することはできません。 @@ -1279,7 +1279,7 @@ function handleClick() { } ``` -関数を渡すと、React は `someFunction` を [初期化関数](#avoiding-recreating-the-initial-state) 、`someOtherFunction` を [更新関数](#updating-state-based-on-the-previous-state) として扱います。そのため、それらを呼び出し、その結果を保存しようとします。関数自体を *保存* するには、どちらの場合も `() =>` を前に付ける必要があります。こうすると、React は関数自体を保存します。 +関数を渡すと、React は `someFunction` を [初期化関数](#avoiding-recreating-the-initial-state) 、`someOtherFunction` を [更新関数](#updating-state-based-on-the-previous-state) として扱います。そのため、それらを呼び出し、その結果を保存しようとします。関数自体を*保存*するには、どちらの場合も `() =>` を前に付ける必要があります。こうすると、React は関数自体を保存します。 ```js {1,4} const [fn, setFn] = useState(() => someFunction); From 73edcb4b75ebd528e4e2fb71c1dba6845ea5e7c9 Mon Sep 17 00:00:00 2001 From: yuta-ike <38308823+yuta-ike@users.noreply.github.com> Date: Wed, 31 May 2023 15:01:31 +0900 Subject: [PATCH 3/5] Fix "useState" translation --- src/content/reference/react/useState.md | 88 ++++++++++++------------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/src/content/reference/react/useState.md b/src/content/reference/react/useState.md index 0360711bc..27f93d9e9 100644 --- a/src/content/reference/react/useState.md +++ b/src/content/reference/react/useState.md @@ -20,7 +20,7 @@ const [state, setState] = useState(initialState); ### `useState(initialState)` {/*usestate*/} -コンポーネントのトップレベルで `useState` を呼び出して、[state 変数](/learn/state-a-components-memory) を宣言します。 +コンポーネントのトップレベルで `useState` を呼び出して、[state 変数](/learn/state-a-components-memory)を宣言します。 ```js import { useState } from 'react'; @@ -71,7 +71,7 @@ function handleClick() { #### 引数 {/*setstate-parameters*/} * `nextState`: 次に state にセットしたい値です。どんな型の値でも渡すことができますが、関数を渡した場合は特別な振る舞いをします。 - * `nextState` に関数を渡した場合、その関数は*更新関数*として扱われます。更新関数は、純粋で、未確定の state (pending state) を唯一の引数として受け取り、次の state を返す必要があります。React は更新関数をキューに入れ、コンポーネントを再レンダーします。次のレンダーで、React はキューに入れられたすべての更新関数を前の state に対して適用し、次の state を導出します。[例を見る](#updating-state-based-on-the-previous-state) + * `nextState` に関数を渡した場合、その関数は*更新用関数*として扱われます。更新用関数は、純粋で、処理中の state の値を唯一の引数として受け取り、次の state を返す必要があります。React は更新用関数をキューに入れ、コンポーネントを再レンダーします。次のレンダーで、React はキューに入れられたすべての更新用関数を前の state に対して適用し、次の state を導出します。[例を見る](#updating-state-based-on-the-previous-state) #### 返り値 {/*setstate-returns*/} @@ -85,9 +85,9 @@ function handleClick() { * React は [state の更新をまとめて行います(バッチ処理)](/learn/queueing-a-series-of-state-updates)。**すべてのイベントハンドラを実行し終え**、`set` 関数が呼び出された後に、画面を更新します。これにより、1 つのイベント中に複数回の再レンダーが発生することはありません。まれに、早期に画面を更新する必要がある場合(例えば DOM にアクセスする場合など)がありますが、その場合は [`flushSync`](/reference/react-dom/flushSync) を利用できます。 -* レンダリング中に `set` 関数を呼び出すことは、*現在レンダリング中の*コンポーネント内からのみ許されています。その場合、React はその出力を破棄し、新しい state で再レンダーを試みます。このパターンが必要になることはほとんどありませんが、**前回のレンダーからの情報を保存**するために使用できます。[例を見る](#storing-information-from-previous-renders) +* レンダー中に `set` 関数を呼び出すことは、*現在レンダー中の*コンポーネント内からのみ許されています。その場合、React はその出力を破棄し、新しい state で再レンダーを試みます。このパターンが必要になることはほとんどありませんが、**前回のレンダーからの情報を保存**するために使用できます。[例を見る](#storing-information-from-previous-renders) -* Strict Mode では、[純粋でない関数を見つけやすくするために](#my-initializer-or-updater-function-runs-twice)**更新関数が 2 回呼び出されます**。これは開発時のみの振る舞いであり、本番には影響しません。更新関数が純粋であれば(そうであるべきです)、2 回呼び出されてもコードに影響はありません。2 回の呼び出しのうち 1 回の呼び出し結果は無視されます。 +* Strict Mode では、[純粋でない関数を見つけやすくするために](#my-initializer-or-updater-function-runs-twice)**更新用関数が 2 回呼び出されます**。これは開発時のみの振る舞いであり、本番には影響しません。更新用関数が純粋であれば(そうであるべきです)、2 回呼び出されてもコードに影響はありません。2 回の呼び出しのうち 1 回の呼び出し結果は無視されます。 --- @@ -111,7 +111,7 @@ state 変数は慣習として、[分割代入](https://javascript.info/destruct `useState` は、以下の 2 つの値を持つ配列を返します。 1. この state 変数の現在の値。最初は、初期 state に設定されます。 -1. インタラクションに応じて、state を他の値に変更するための`set` 関数。 +2. インタラクションに応じて、state を他の値に変更するための`set` 関数。 スクリーン上の表示を更新するには、次の state を引数として `set` 関数を呼び出します。 @@ -125,7 +125,7 @@ React は次の state を保存したあと、新しい値でコンポーネン -`set` 関数の呼び出しは、[既に実行されているコードの現在の state を変更するわけでは**ありません**](#ive-updated-the-state-but-logging-gives-me-the-old-value)。 +`set` 関数の呼び出しは、[既に実行中のコードの現在の state を変更するわけでは**ありません**](#ive-updated-the-state-but-logging-gives-me-the-old-value)。 ```js {3} function handleClick() { @@ -138,7 +138,7 @@ function handleClick() { - + #### カウンタ (number) {/*counter-number*/} @@ -290,7 +290,7 @@ function handleClick() { しかし、1 回クリックしたあと、`age` は `45` ではなく `43` になります! これは、`set` 関数を呼び出しても、既に実行されているコードの `age` state 変数を[更新するわけではない](/learn/state-as-a-snapshot)ためです。そのため、`setAge(age + 1)` の呼び出しは全て `setAge(43)` になります。 -この問題を解消するため、次の state の代わりに、***更新関数*を `setAge` に渡す**ことができます。 +この問題を解消するため、次の state の代わりに、***更新用関数*を `setAge` に渡す**ことができます。 ```js [[1, 2, "a", 0], [2, 2, "a + 1"], [1, 3, "a", 0], [2, 3, "a + 1"], [1, 4, "a", 0], [2, 4, "a + 1"]] function handleClick() { @@ -300,39 +300,39 @@ function handleClick() { } ``` -ここで、`a => a + 1` は更新関数です。更新関数は、未確定の state (pending state) を受け取り、そこから次の state を導出します。 +ここで、`a => a + 1` は更新用関数です。更新用関数は、処理中の state の値を受け取り、そこから次の state を導出します。 -React は更新関数を[キュー](/learn/queueing-a-series-of-state-updates)に入れます。そして、次のレンダー中に、同じ順番で更新関数を呼び出します。 +React は更新用関数を[キュー](/learn/queueing-a-series-of-state-updates)に入れます。そして、次のレンダー中に、同じ順番で更新用関数を呼び出します。 -1. `a => a + 1` は未確定の state として `42` を受け取り、次の state として `43` を返します。 -1. `a => a + 1` は未確定の state として `43` を受け取り、次の state として `44` を返します。 -1. `a => a + 1` は未確定の state として `44` を受け取り、次の state として `45` を返します。 +1. `a => a + 1` は処理中の state の値として `42` を受け取り、次の state として `43` を返します。 +1. `a => a + 1` は処理中の state の値として `43` を受け取り、次の state として `44` を返します。 +1. `a => a + 1` は処理中の state の値として `44` を受け取り、次の state として `45` を返します。 -キューにはこれ以上の更新関数はないので、React は最終的に `45` を現在の state として保存します。 +キューにはこれ以上の更新用関数はないので、React は最終的に `45` を現在の state として保存します。 -慣習として、未確定の state の引数名には、state 変数名の頭文字 1 文字を利用することが一般的です(例えば、`age` という state 変数に対して、`a` という引数名)。しかし、`prevAge` など、他の分かりやすい名前を使うこともできます。 +慣習として、処理中の state の引数名には、state 変数名の頭文字 1 文字を利用することが一般的です(例えば、`age` という state 変数に対して、`a` という引数名)。しかし、`prevAge` など、他の分かりやすい名前を使うこともできます。 -開発時に[更新関数が 2 回呼び出される](#my-initializer-or-updater-function-runs-twice)ことがあります。これは、更新関数が[純粋](/learn/keeping-components-pure)であることを確認するためです。 +開発時に[更新用関数が 2 回呼び出される](#my-initializer-or-updater-function-runs-twice)ことがあります。これは、更新用関数が[純粋](/learn/keeping-components-pure)であることを確認するためです。 -#### 常に更新関数を利用すべきか {/*is-using-an-updater-always-preferred*/} +#### 常に更新用関数を利用すべきか {/*is-using-an-updater-always-preferred*/} 新しくセットする値が直前の state から導出される場合、常に `setAge(a => a + 1)` という書き方をすべきだという意見があります。悪いことではありませんが、必ずしも必要なわけではありません。 -ほとんどのケースでは、どちらのアプローチでも違いはありません。React は、クリックなどのユーザの意図的なアクションに対して、`age` state 変数の更新が次のクリックの前に発生することを保証しています。すなわち、イベントハンドラの開始時に、クリックハンドラが"古い (stale)" `age` を参照してしまうことはありません。 +ほとんどのケースでは、どちらのアプローチでも違いはありません。React は、クリックなどのユーザの意図的なアクションに対して、`age` state 変数の更新が次のクリックの前に発生することを保証しています。すなわち、イベントハンドラの開始時に、クリックハンドラが "古い (stale)" `age` を参照してしまうことはありません。 -一方で、同じイベント内で複数回の更新を行う場合、更新関数が役に立ちます。また、state 変数自身を参照することが難しいケースにも有用です(再レンダーの発生を最適化する際に、このケースに遭遇することがあります)。 +一方で、同じイベント内で複数回の更新を行う場合、更新用関数が役に立ちます。また、state 変数自身を参照することが難しいケースにも有用です(再レンダーの発生を最適化する際に、このケースに遭遇することがあります)。 -わずかな文法の冗長性よりも一貫性を優先するのであれば、state が直前の state から導出される場合には、常に更新関数を書くようにすることは合理的です。もし、state が、他の state 変数の直前の値から導出される場合は、それらを 1 つのオブジェクトにまとめて [reducer を利用する](/learn/extracting-state-logic-into-a-reducer)ことを検討してください。 +わずかな文法の冗長性よりも一貫性を優先するのであれば、state が直前の state から導出される場合には、常に更新関数を書くようにすることは合理的です。もし、state が、他の state 変数の直前の値から導出される場合は、それらを 1 つのオブジェクトにまとめて[リデューサ (reducer) を利用する](/learn/extracting-state-logic-into-a-reducer)ことを検討してください。 - + -#### 更新関数を渡す {/*passing-the-updater-function*/} +#### 更新用関数を渡す {/*passing-the-updater-function*/} -この例では更新関数を渡しているため、"+3"ボタンは想定通りに動きます。 +この例では更新関数を渡しているため、"+3" ボタンは想定通りに動きます。 @@ -373,7 +373,7 @@ h1 { display: block; margin: 10px; } #### 次の state を直接渡す {/*passing-the-next-state-directly*/} -この例では更新関数を渡して**いません**。そのため"+3"ボタンは**意図した通りには動きません**。 +この例では更新関数を渡して**いません**。そのため "+3" ボタンは**意図した通りには動きません**。 @@ -418,7 +418,7 @@ h1 { display: block; margin: 10px; } ### オブジェクトや配列の state を更新する {/*updating-objects-and-arrays-in-state*/} -state にオブジェクトや配列をセットすることができます。ただし React では、state は読み取り専用 (read-only) として扱う必要があります。そのため、state を更新する場合は、**既存のオブジェクトを直接*変更する (mutate)* のではなく、*置き換える (replace)* 必要があります**。例えば、state として `form` オブジェクトを保持している場合、以下のように書き換えを行ってはいけません。 +state にオブジェクトや配列をセットすることができます。ただし React では、state は読み取り専用 (read-only) として扱う必要があります。そのため、state を更新する場合は、**既存のオブジェクトを直接*書き換える (mutate)* のではなく、*置き換える (replace)* 必要があります**。例えば、state として `form` オブジェクトを保持している場合、以下のように書き換えを行ってはいけません。 ```js // 🚩 Don't mutate an object in state like this: @@ -439,9 +439,9 @@ setForm({ -#### フォーム (オブジェクト) {/*form-object*/} +#### フォーム(オブジェクト) {/*form-object*/} -この例では、`form` state 変数はオブジェクトを保持しています。それぞれの input 要素は change ハンドラを持っており、新しい `form` オブジェクトを引数として `setForm` を呼び出します。`{...form}` のようにスプレッド構文を用いることで、state オブジェクトを(書き換えではなく)確実に置換することができます。 +この例では、`form` state 変数はオブジェクトを保持しています。それぞれの input 要素は change ハンドラを持っており、新しい `form` オブジェクトを引数として `setForm` を呼び出します。`{ ...form }` のようにスプレッド構文を用いることで、state オブジェクトを(書き換えではなく)確実に置き換えることができます。 @@ -512,7 +512,7 @@ input { margin-left: 5px; } -#### フォーム (ネストされたオブジェクト) {/*form-nested-object*/} +#### フォーム(ネストされたオブジェクト) {/*form-nested-object*/} この例では、state がネストされたオブジェクトになっています。ネストされたオブジェクトの state を更新する場合、更新するオブジェクトのコピーを作成する必要があります。さらに、そのオブジェクトを内包する上位のオブジェクトも同様に、コピーを作成する必要があります。詳しくは、[ネストされたオブジェクトの更新](/learn/updating-objects-in-state#updating-a-nested-object)を参照してください。 @@ -624,9 +624,9 @@ img { width: 200px; height: 200px; } -#### リスト (配列) {/*list-array*/} +#### リスト(配列) {/*list-array*/} -この例では、`todos` state 変数が配列を保持しています。各ボタンのハンドラは、新しい `todos` state の配列を引数として `setTodos` を呼び出します。スプレッド構文(`[...todos]`)や、`todos.map()`、`todos.filter()` などを利用すると、state の配列を(書き換えではなく)確実に置換することができます。 +この例では、`todos` state 変数が配列を保持しています。各ボタンのハンドラは、`todos` 配列の新しい値を引数として `setTodos` を呼び出します。スプレッド構文 (`[...todos]`) や、`todos.map()`、`todos.filter()` などを利用すると、state の配列を(書き換えではなく)確実に置き換えることができます。 @@ -793,7 +793,7 @@ ul, li { margin: 0; padding: 0; } #### Immer で簡潔な更新ロジックを書く {/*writing-concise-update-logic-with-immer*/} -配列やオブジェクトの state の更新を、書き換えではなく置換で行うことが煩雑に感じる場合、[Immer](https://github.com/immerjs/use-immer) のようなライブラリを用いて繰り返しのコードを減らすことができます。Immer を利用することで、オブジェクトを直接書き換えるようなコードを書くことができます。しかし内部では、イミュータブル(不変, immutable)な更新、すなわち配列やオブジェクトの置換として実行されます。 +配列やオブジェクトの書き換えを行わずに state を更新することが煩雑に感じる場合、[Immer](https://github.com/immerjs/use-immer) のようなライブラリを用いて繰り返しのコードを減らすことができます。Immer を利用することで、オブジェクトを書き換えているかのような簡潔なコードを書くことができます。しかし内部では、イミュータブル(不変, immutable)な更新が実行されます。 @@ -910,7 +910,7 @@ function TodoList() { #### 初期化関数を渡す {/*passing-the-initializer-function*/} -この例では、初期化関数を利用しています。そのため、`createInitialTodos` 関数は初期化時のみ実行されます。input に文字を入力した場合などの、コンポーネントの再レンダー時には実行されません。 +この例では、初期化関数を利用しています。そのため、`createInitialTodos` 関数は初期化時のみ実行されます。入力フィールドに文字を入力した場合などの、コンポーネントの再レンダー時には実行されません。 @@ -963,7 +963,7 @@ export default function TodoList() { #### 初期 state を直接渡す {/*passing-the-initial-state-directly*/} -この例では、初期化関数を利用して**いません**。そのため、`createInitialTodos` 関数は、input に文字を入力したときなどの全てのレンダーで実行されます。挙動に目に見える違いはありませんが、少し効率が悪くなります。 +この例では、初期化関数を利用して**いません**。そのため、`createInitialTodos` 関数は、入力フィールドに文字を入力したときなどの全てのレンダーで実行されます。挙動に目に見える違いはありませんが、少し効率が悪くなります。 @@ -1024,7 +1024,7 @@ export default function TodoList() { **コンポーネントに異なる `key` を渡すことで、コンポーネントの state をリセットすることができます**。この例では、`version` state 変数を `Form` に `key` として渡しています。"Reset" ボタンをクリックすると、`version` state 変数が変化します。`key` が変化したとき、React は `Form` コンポーネント(と、その全ての子コンポーネント)を一から再生成するため、`Form` の state がリセットされます。 -詳しくは、[state の保存とリセット](/learn/preserving-and-resetting-state)を参照してください。 +詳しくは、[state の保持とリセット](/learn/preserving-and-resetting-state)を参照してください。 @@ -1075,7 +1075,7 @@ button { display: block; margin-bottom: 20px; } 以下に示すように、ほとんどのケースでは不要です。 -* **もし必要な値が現在の props と他の state のみから導出される場合、[冗長な state を削除してください](/learn/choosing-the-state-structure#avoid-redundant-state)**。もし再計算されることが気になる場合は、[`useMemo` フック](/reference/react/useMemo)が役に立ちます。 +* **もし必要な値が現在の props と他の state のみから導出される場合、[冗長な state を削除してください](/learn/choosing-the-state-structure#avoid-redundant-state)**。もし何度も再計算されることが気になる場合は、[`useMemo` フック](/reference/react/useMemo)が役に立ちます。 * もしコンポーネントツリーの state 全体をリセットしたい場合、[コンポーネントに異なる `key` を渡してください](#resetting-state-with-a-key)。 * 可能であれば、関連するすべての state をイベントハンドラの中で更新してください。 @@ -1140,7 +1140,7 @@ button { margin-bottom: 10px; } レンダー中に `set` 関数を呼び出す場合は、`prevCount !== count` のような条件節の中で、`setPrevCount(count)` のような呼び出しが必要なことに注意してください。さもないと、再レンダーのループに陥り、コンポーネントがクラッシュします。また、例のように、*現在レンダーしている*コンポーネントの state のみ更新することができます。レンダー中に*別の*コンポーネントの `set` 関数を呼び出すとエラーになります。最後に、`set` 関数の呼び出しは、[書き換えなしで state を更新](#updating-objects-and-arrays-in-state)する必要があります。これは、[純関数](/learn/keeping-components-pure)の他のルールを破ることができないことを意味します。 -このパターンは理解するのが難しいため、通常は避けられます。しかし、エフェクト内で state を更新するよりは良い方法です。レンダー中に `set` 関数を呼び出すと、コンポーネントが `return` 文で終了した直後に再レンダーが行われます。これは、子コンポーネントをレンダーする前に行われ、子コンポーネントが 2 回レンダーされることはありません。コンポーネント関数の残りの部分は引き続き実行されます(その結果は破棄されます)。もし、`set` 関数の呼び出しを含む条件節が、全てのフックの呼び出しより下にある場合、早期に `return;` を追加して、再レンダーを早めることができます。 +このパターンは理解するのが難しいため、通常は避けるべきです。しかし、エフェクト内で state を更新するよりは良い方法です。レンダー中に `set` 関数を呼び出すと、コンポーネントが `return` 文で終了した直後、子コンポーネントをレンダーする前に再レンダーが行われます。このため、子コンポーネントが 2 回レンダーされずに済みます。コンポーネント関数の残りの部分は引き続き実行されます(結果は破棄されますが)。もし、`set` 関数の呼び出しを含む条件分岐が、全てのフックの呼び出しより下にある場合、早期 `return;` を追加して、再レンダーを早めることができます。 --- @@ -1179,7 +1179,7 @@ console.log(nextCount); // 1 ### state を更新したのに画面が更新されない {/*ive-updated-the-state-but-the-screen-doesnt-update*/} -React では、**更新の前後で state の値が変化しない場合、その変更は無視されます**。state の値の変化は、[`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) によって判断されます。これは、state のオブジェクトや配列を直接書き換えた場合によく起こります。 +React では、**更新の前後で state の値が変化しない場合、その変更は無視されます**。state の値の変化は、[`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) によって判断されます。この現象は、state のオブジェクトや配列を直接書き換えた場合によく起こります。 ```js obj.x = 10; // 🚩 Wrong: mutating existing object @@ -1200,7 +1200,7 @@ setObj({ ### "Too many re-renders" というエラーが出る {/*im-getting-an-error-too-many-re-renders*/} -`Too many re-renders. React limits the number of renders to prevent an infinite loop.` というエラーが出ることがあります。これは通常、*レンダー中に*無条件に `set` 関数を呼び出しているため、コンポーネントがループに入っていることを意味します。レンダー、`set` 関数の呼び出し(レンダーを引き起こす)、レンダー、`set` 関数の呼び出し(レンダーを引き起こす)、というように続きます。これは、イベントハンドラの指定に間違いがあることが多いです。 +`Too many re-renders. React limits the number of renders to prevent an infinite loop.` というエラーが出ることがあります。これは通常、*レンダー中に*無条件に `set` 関数を呼び出しているため、コンポーネントがループに入っていることを意味します。レンダー、`set` 関数の呼び出し(レンダーを引き起こす)、レンダー、`set` 関数の呼び出し(レンダーを引き起こす)、というように続きます。大抵の場合、これはイベントハンドラの指定を間違ったことによるものです。 ```js {1-2} // 🚩 Wrong: calls the handler during render @@ -1217,7 +1217,7 @@ return --- -### 初期化関数や更新関数が2度呼ばれる {/*my-initializer-or-updater-function-runs-twice*/} +### 初期化関数や更新関数が 2 度呼ばれる {/*my-initializer-or-updater-function-runs-twice*/} [Strict Mode](/reference/react/StrictMode) では、いくつかの関数が、本来 1 回のところを 2 回呼び出されることがあります。 @@ -1241,9 +1241,9 @@ function TodoList() { これは予想される動作であり、あなたのコードを壊すものではありません。 -これは**開発時のみ**の挙動で、[コンポーネントを純粋に保つ](/learn/keeping-components-pure)ために役立ちます。React は、呼び出し結果の 1 つを利用し、もう 1 つを無視します。コンポーネント、初期化関数、更新関数が純粋であれば、この挙動があなたのロジックに影響を与えることはありません。ただし、誤って純粋でない関数を指定した場合は、これにより間違いに気付くことができるでしょう。 +これは**開発時のみ**の挙動で、[コンポーネントを純粋に保つ](/learn/keeping-components-pure)ために役立ちます。React は、呼び出し結果の 1 つを利用し、もう 1 つを無視します。コンポーネント、初期化関数、更新用関数が純粋であれば、この挙動があなたのロジックに影響を与えることはありません。ただし、誤って純粋でない関数を指定した場合は、これにより間違いに気付くことができるでしょう。 -例えば以下の更新関数は、state の配列を書き換えるため純粋ではありません。 +例えば以下の更新用関数は、state の配列を書き換えるため純粋ではありません。 ```js {2,3} setTodos(prevTodos => { @@ -1252,7 +1252,7 @@ setTodos(prevTodos => { }); ``` -React は更新関数を 2 回呼び出すため、todo が 2 つ追加されてしまい、間違いに気付くことができます。この例では、配列を[書き換えるのではなく、置き換える](#updating-objects-and-arrays-in-state)ことで間違いを修正できます。 +React は更新用関数を 2 回呼び出すため、todo が 2 つ追加されてしまい、間違いに気付くことができます。この例では、配列を[書き換えるのではなく、置き換える](#updating-objects-and-arrays-in-state)ことで間違いを修正できます。 ```js {2,3} setTodos(prevTodos => { @@ -1261,7 +1261,7 @@ setTodos(prevTodos => { }); ``` -更新関数が純粋になったため、複数回呼び出されても動作に影響しません。これが、2 回呼び出されることで間違いに気付くことができる理由です。**コンポーネント、初期化関数、更新関数のみが純粋である必要があります**。イベントハンドラは、純粋である必要がないため、2 回呼び出されることはありません。 +更新用関数が純粋になったため、複数回呼び出されても動作に影響しません。これが、2 回呼び出されることで間違いに気付くことができる理由です。**コンポーネント、初期化関数、更新用関数のみが純粋である必要があります**。イベントハンドラは、純粋である必要がないため、2 回呼び出されることはありません。 詳しくは、[コンポーネントを純粋に保つ](/learn/keeping-components-pure)を参照してください。 @@ -1279,7 +1279,7 @@ function handleClick() { } ``` -関数を渡すと、React は `someFunction` を [初期化関数](#avoiding-recreating-the-initial-state) 、`someOtherFunction` を [更新関数](#updating-state-based-on-the-previous-state) として扱います。そのため、それらを呼び出し、その結果を保存しようとします。関数自体を*保存*するには、どちらの場合も `() =>` を前に付ける必要があります。こうすると、React は関数自体を保存します。 +関数を渡すと、React は `someFunction` を[初期化関数](#avoiding-recreating-the-initial-state)、`someOtherFunction` を[更新関数](#updating-state-based-on-the-previous-state)として扱います。そのため、それらを呼び出し、その結果を保存しようとします。関数を実行するのではなく*保存*するには、どちらの場合も `() =>` を前に付ける必要があります。こうすると、React は関数自体を保存します。 ```js {1,4} const [fn, setFn] = useState(() => someFunction); From b6b239ca877f2cb6106630c79eb2b7fefd1a0eea Mon Sep 17 00:00:00 2001 From: yuta-ike <38308823+yuta-ike@users.noreply.github.com> Date: Wed, 31 May 2023 15:10:04 +0900 Subject: [PATCH 4/5] Fix "useState" translation --- src/content/reference/react/useState.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/content/reference/react/useState.md b/src/content/reference/react/useState.md index 27f93d9e9..067435110 100644 --- a/src/content/reference/react/useState.md +++ b/src/content/reference/react/useState.md @@ -324,7 +324,7 @@ React は更新用関数を[キュー](/learn/queueing-a-series-of-state-updates 一方で、同じイベント内で複数回の更新を行う場合、更新用関数が役に立ちます。また、state 変数自身を参照することが難しいケースにも有用です(再レンダーの発生を最適化する際に、このケースに遭遇することがあります)。 -わずかな文法の冗長性よりも一貫性を優先するのであれば、state が直前の state から導出される場合には、常に更新関数を書くようにすることは合理的です。もし、state が、他の state 変数の直前の値から導出される場合は、それらを 1 つのオブジェクトにまとめて[リデューサ (reducer) を利用する](/learn/extracting-state-logic-into-a-reducer)ことを検討してください。 +わずかな文法の冗長性よりも一貫性を優先するのであれば、state が直前の state から導出される場合には、常に更新用関数を書くようにすることは合理的です。もし、state が、他の state 変数の直前の値から導出される場合は、それらを 1 つのオブジェクトにまとめて[リデューサ (reducer) を利用する](/learn/extracting-state-logic-into-a-reducer)ことを検討してください。 @@ -332,7 +332,7 @@ React は更新用関数を[キュー](/learn/queueing-a-series-of-state-updates #### 更新用関数を渡す {/*passing-the-updater-function*/} -この例では更新関数を渡しているため、"+3" ボタンは想定通りに動きます。 +この例では更新用関数を渡しているため、"+3" ボタンは想定通りに動きます。 @@ -373,7 +373,7 @@ h1 { display: block; margin: 10px; } #### 次の state を直接渡す {/*passing-the-next-state-directly*/} -この例では更新関数を渡して**いません**。そのため "+3" ボタンは**意図した通りには動きません**。 +この例では更新用関数を渡して**いません**。そのため "+3" ボタンは**意図した通りには動きません**。 @@ -1079,7 +1079,7 @@ button { display: block; margin-bottom: 20px; } * もしコンポーネントツリーの state 全体をリセットしたい場合、[コンポーネントに異なる `key` を渡してください](#resetting-state-with-a-key)。 * 可能であれば、関連するすべての state をイベントハンドラの中で更新してください。 -これらがどれも適用できない稀なケースで、コンポーネントのレンダー中に `set` 関数を呼び出し、それまでにレンダーされた値に基づいて state を更新するパターンが利用できます。 +これらがどれも適用できない稀なケースでは、コンポーネントのレンダー中に `set` 関数を呼び出し、それまでにレンダーされた値に基づいて state を更新するパターンが利用できます。 以下の例では、`CountLabel` コンポーネントは、渡された `count` プロパティを表示しています。 @@ -1217,7 +1217,7 @@ return --- -### 初期化関数や更新関数が 2 度呼ばれる {/*my-initializer-or-updater-function-runs-twice*/} +### 初期化関数や更新用関数が 2 度呼ばれる {/*my-initializer-or-updater-function-runs-twice*/} [Strict Mode](/reference/react/StrictMode) では、いくつかの関数が、本来 1 回のところを 2 回呼び出されることがあります。 @@ -1279,7 +1279,7 @@ function handleClick() { } ``` -関数を渡すと、React は `someFunction` を[初期化関数](#avoiding-recreating-the-initial-state)、`someOtherFunction` を[更新関数](#updating-state-based-on-the-previous-state)として扱います。そのため、それらを呼び出し、その結果を保存しようとします。関数を実行するのではなく*保存*するには、どちらの場合も `() =>` を前に付ける必要があります。こうすると、React は関数自体を保存します。 +関数を渡すと、React は `someFunction` を[初期化関数](#avoiding-recreating-the-initial-state)、`someOtherFunction` を[更新用関数](#updating-state-based-on-the-previous-state)として扱います。そのため、それらを呼び出し、その結果を保存しようとします。関数を実行するのではなく*保存*するには、どちらの場合も `() =>` を前に付ける必要があります。こうすると、React は関数自体を保存します。 ```js {1,4} const [fn, setFn] = useState(() => someFunction); From e7ca33c97cf62e0fffd7b07989280c7b9e6adba7 Mon Sep 17 00:00:00 2001 From: yuta-ike <38308823+yuta-ike@users.noreply.github.com> Date: Wed, 31 May 2023 21:30:43 +0900 Subject: [PATCH 5/5] Fix "useState" translation --- src/content/reference/react/useState.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/content/reference/react/useState.md b/src/content/reference/react/useState.md index 067435110..67cd605a6 100644 --- a/src/content/reference/react/useState.md +++ b/src/content/reference/react/useState.md @@ -39,7 +39,7 @@ state 変数は慣習として、[分割代入](https://javascript.info/destruct #### 引数 {/*parameters*/} * `initialState`: state の初期値です。どんな型の値でも渡すことができますが、関数を渡した場合は特別な振る舞いをします。この引数は初回レンダー後は無視されます。 - * `initialState` に関数を渡した場合、その関数は*初期化関数*として扱われます。初期化関数は、純粋で、引数を取らず、何らかの型の値を返す必要があります。React はコンポーネントを初期化するときに初期化関数を呼び出し、その返り値を初期 state として保存します。[例を見る](#avoiding-recreating-the-initial-state) + * `initialState` に関数を渡した場合、その関数は*初期化関数 (initializer function)* として扱われます。初期化関数は、純粋で、引数を取らず、何らかの型の値を返す必要があります。React はコンポーネントを初期化するときに初期化関数を呼び出し、その返り値を初期 state として保存します。[例を見る](#avoiding-recreating-the-initial-state) #### 返り値 {/*returns*/} @@ -71,7 +71,7 @@ function handleClick() { #### 引数 {/*setstate-parameters*/} * `nextState`: 次に state にセットしたい値です。どんな型の値でも渡すことができますが、関数を渡した場合は特別な振る舞いをします。 - * `nextState` に関数を渡した場合、その関数は*更新用関数*として扱われます。更新用関数は、純粋で、処理中の state の値を唯一の引数として受け取り、次の state を返す必要があります。React は更新用関数をキューに入れ、コンポーネントを再レンダーします。次のレンダーで、React はキューに入れられたすべての更新用関数を前の state に対して適用し、次の state を導出します。[例を見る](#updating-state-based-on-the-previous-state) + * `nextState` に関数を渡した場合、その関数は*更新用関数 (updater function)* として扱われます。更新用関数は、純粋で、処理中の state の値を唯一の引数として受け取り、次の state を返す必要があります。React は更新用関数をキューに入れ、コンポーネントを再レンダーします。次のレンダーで、React はキューに入れられたすべての更新用関数を前の state に対して適用し、次の state を導出します。[例を見る](#updating-state-based-on-the-previous-state) #### 返り値 {/*setstate-returns*/} @@ -236,7 +236,7 @@ export default function MyCheckbox() { -#### フォーム (2 つの変数) {/*form-two-variables*/} +#### フォーム(2 つの変数) {/*form-two-variables*/} 同じコンポーネントで、複数の state 変数を宣言することができます。それぞれの state 変数は、完全に独立しています。 @@ -320,7 +320,7 @@ React は更新用関数を[キュー](/learn/queueing-a-series-of-state-updates 新しくセットする値が直前の state から導出される場合、常に `setAge(a => a + 1)` という書き方をすべきだという意見があります。悪いことではありませんが、必ずしも必要なわけではありません。 -ほとんどのケースでは、どちらのアプローチでも違いはありません。React は、クリックなどのユーザの意図的なアクションに対して、`age` state 変数の更新が次のクリックの前に発生することを保証しています。すなわち、イベントハンドラの開始時に、クリックハンドラが "古い (stale)" `age` を参照してしまうことはありません。 +ほとんどのケースでは、どちらのアプローチでも違いはありません。React は、クリックなどのユーザの意図的なアクションに対して、`age` state 変数の更新が次のクリックの前に発生することを保証しています。すなわち、イベントハンドラの開始時に、クリックハンドラが「古い」`age` を参照してしまうことはありません。 一方で、同じイベント内で複数回の更新を行う場合、更新用関数が役に立ちます。また、state 変数自身を参照することが難しいケースにも有用です(再レンダーの発生を最適化する際に、このケースに遭遇することがあります)。 @@ -418,7 +418,7 @@ h1 { display: block; margin: 10px; } ### オブジェクトや配列の state を更新する {/*updating-objects-and-arrays-in-state*/} -state にオブジェクトや配列をセットすることができます。ただし React では、state は読み取り専用 (read-only) として扱う必要があります。そのため、state を更新する場合は、**既存のオブジェクトを直接*書き換える (mutate)* のではなく、*置き換える (replace)* 必要があります**。例えば、state として `form` オブジェクトを保持している場合、以下のように書き換えを行ってはいけません。 +state にオブジェクトや配列をセットすることができます。ただし React では、state は読み取り専用として扱う必要があります。そのため、state を更新する場合は、**既存のオブジェクトを直接*書き換える (mutate)* のではなく、*置き換える (replace)* 必要があります**。例えば、state として `form` オブジェクトを保持している場合、以下のように書き換えを行ってはいけません。 ```js // 🚩 Don't mutate an object in state like this: @@ -435,7 +435,7 @@ setForm({ }); ``` -詳しくは、[オブジェクトの state を更新する](/learn/updating-objects-in-state)や、[配列の state を更新する](/learn/updating-arrays-in-state)を参照してください。 +詳しくは、[state 内のオブジェクトの更新](/learn/updating-objects-in-state)や、[state 内の配列の更新](/learn/updating-arrays-in-state)を参照してください。