-
Notifications
You must be signed in to change notification settings - Fork 88
doc: translate forms #23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
4c648c5
Begin thinking-in-react
chloewlin c77a49f
Work in thinking-in-react
chloewlin 9f9e8db
Complete thinking-in-react
chloewlin 03f8485
Fix typos and mistakes
chloewlin 386d450
Start working on forms
chloewlin 590d648
Complete until file input tag
chloewlin 90992ce
Complete form
chloewlin f168fbb
Remove an extra ]
chloewlin a2da1ea
Fix link to uncontrolled component
chloewlin ba30348
Update 'single source of truth' translation
chloewlin c66c7d0
Apply changes
chloewlin f06a0fa
Update third-personal references
chloewlin bc63609
Merge branch 'master' into form
chloewlin File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,6 +1,6 @@ | ||||||
--- | ||||||
id: forms | ||||||
title: Forms | ||||||
title: 表格 | ||||||
permalink: docs/forms.html | ||||||
prev: lists-and-keys.html | ||||||
next: lifting-state-up.html | ||||||
|
@@ -9,7 +9,7 @@ redirect_from: | |||||
- "docs/forms-zh-CN.html" | ||||||
--- | ||||||
|
||||||
HTML form elements work a little bit differently from other DOM elements in React, because form elements naturally keep some internal state. For example, this form in plain HTML accepts a single name: | ||||||
HTML 表格的 element 和 React 中其他的 DOM element 不太一樣,因為表格的 element 很自然地有一些內部的 state。例如,下面的這個表格在純粹的 HTML 中接收單一的名稱: | ||||||
|
||||||
```html | ||||||
<form> | ||||||
|
@@ -21,15 +21,15 @@ HTML form elements work a little bit differently from other DOM elements in Reac | |||||
</form> | ||||||
``` | ||||||
|
||||||
This form has the default HTML form behavior of browsing to a new page when the user submits the form. If you want this behavior in React, it just works. But in most cases, it's convenient to have a JavaScript function that handles the submission of the form and has access to the data that the user entered into the form. The standard way to achieve this is with a technique called "controlled components". | ||||||
這個表格有 HTML 表格的預設行為,也就是在使用者遞交一個表格的時候去瀏覽一個新頁面。如果你想要在 React 中也有這樣的行為的話,直接用 HTML 是可行的。但是在大多數的情況中,有一個 JavaScript function 來處理遞交表格的功能並讀取使用者在表格中填入的資料是很方便的。要做到這樣,標準的方法是使用「controlled component」: | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The term
Suggested change
|
||||||
|
||||||
## Controlled Components {#controlled-components} | ||||||
## Controlled Component {#controlled-components} | ||||||
|
||||||
In HTML, form elements such as `<input>`, `<textarea>`, and `<select>` typically maintain their own state and update it based on user input. In React, mutable state is typically kept in the state property of components, and only updated with [`setState()`](/docs/react-component.html#setstate). | ||||||
在 HTML 中,表格的 element,像是 `<input>`、`<textarea>` 和 `<select>` 通常會維持它們自身的 state,並根據使用者的輸入來更新 state。在 React 中,可變的 state 通常是被維持在 component 中的 state property,並只能以 [`setState()`](/docs/react-component.html#setstate) 來更新。 | ||||||
|
||||||
We can combine the two by making the React state be the "single source of truth". Then the React component that renders a form also controls what happens in that form on subsequent user input. An input form element whose value is controlled by React in this way is called a "controlled component". | ||||||
我們可以透過將 React 的 state 變成「唯一真相來源」來將這兩者結合。如此,render 表格的 React component 同時也掌握了後續使用者的輸入對表格帶來的改變。像這樣一個輸入表單的 element,被 React 用這樣的方式來控制它的值,就被稱為「controlled component」。 | ||||||
|
||||||
For example, if we want to make the previous example log the name when it is submitted, we can write the form as a controlled component: | ||||||
例如,如果我們想要讓上一個例子在一個名字被輸入表格時印出,我們可以把這個表格寫成一個 controlled component: | ||||||
|
||||||
```javascript{4,10-12,24} | ||||||
class NameForm extends React.Component { | ||||||
|
@@ -64,29 +64,29 @@ class NameForm extends React.Component { | |||||
} | ||||||
``` | ||||||
|
||||||
[**Try it on CodePen**](https://codepen.io/gaearon/pen/VmmPgp?editors=0010) | ||||||
[**在 CodePen 上試試看吧!**](https://codepen.io/gaearon/pen/VmmPgp?editors=0010) | ||||||
|
||||||
Since the `value` attribute is set on our form element, the displayed value will always be `this.state.value`, making the React state the source of truth. Since `handleChange` runs on every keystroke to update the React state, the displayed value will update as the user types. | ||||||
既然 `value` attribute 被放在我們的 form element 裡面,被展示的 value 便永遠會是 `this.state.value`,這使得 React 的 state 成為了資料來源(the source of truth)。由於 `handleChange` 在每一次鍵盤被敲擊時都會被執行,並更新 React 的 state,因此被展示的 value 將會在使用者打字的同時被更新。 | ||||||
|
||||||
With a controlled component, every state mutation will have an associated handler function. This makes it straightforward to modify or validate user input. For example, if we wanted to enforce that names are written with all uppercase letters, we could write `handleChange` as: | ||||||
在這樣的 controlled component 中,每一個 state 的 mutation 都會有一個相對應的 handler function。這使得修改或驗證使用者輸入變得很容易。例如,如果我們想要確認名字全部都是用大寫字母寫成的話,我們可以把 `handleChange` 寫成: | ||||||
|
||||||
```javascript{2} | ||||||
handleChange(event) { | ||||||
this.setState({value: event.target.value.toUpperCase()}); | ||||||
} | ||||||
``` | ||||||
|
||||||
## The textarea Tag {#the-textarea-tag} | ||||||
## Textarea 標籤 {#the-textarea-tag} | ||||||
|
||||||
In HTML, a `<textarea>` element defines its text by its children: | ||||||
在 HTML 中,一個 `<textarea>` 的 element 是經由它的 children 來定義它的文字: | ||||||
|
||||||
```html | ||||||
<textarea> | ||||||
Hello there, this is some text in a text area | ||||||
</textarea> | ||||||
``` | ||||||
|
||||||
In React, a `<textarea>` uses a `value` attribute instead. This way, a form using a `<textarea>` can be written very similarly to a form that uses a single-line input: | ||||||
在 React 中,一個 `<textarea>` 則是使用一個 `value` 的 attribute。如此一來,一個使用 `<textarea>` 的表格和一個只寫一行 input 的表格可以用非常類似的方法來寫成: | ||||||
|
||||||
```javascript{4-6,12-14,26} | ||||||
class EssayForm extends React.Component { | ||||||
|
@@ -123,11 +123,11 @@ class EssayForm extends React.Component { | |||||
} | ||||||
``` | ||||||
|
||||||
Notice that `this.state.value` is initialized in the constructor, so that the text area starts off with some text in it. | ||||||
請注意 `this.state.value` 是在 constructor 內被初始化的,所以上述的 text area 一開始會有一些文字。 | ||||||
|
||||||
## The select Tag {#the-select-tag} | ||||||
## Select 標籤 {#the-select-tag} | ||||||
|
||||||
In HTML, `<select>` creates a drop-down list. For example, this HTML creates a drop-down list of flavors: | ||||||
在 HTML 中,`<select>` 會建立一個下拉式選單。例如,這個 HTML 會建立一個有各種水果的下拉式選單: | ||||||
|
||||||
```html | ||||||
<select> | ||||||
|
@@ -138,7 +138,8 @@ In HTML, `<select>` creates a drop-down list. For example, this HTML creates a d | |||||
</select> | ||||||
``` | ||||||
|
||||||
Note that the Coconut option is initially selected, because of the `selected` attribute. React, instead of using this `selected` attribute, uses a `value` attribute on the root `select` tag. This is more convenient in a controlled component because you only need to update it in one place. For example: | ||||||
請注意在這裡,椰子的選項是一開始就被選定的,因為它有一個 `selected` attribute。但是在 React 中並不是用 `selected` attribute,而是在 `select` 的標籤上用一個 `value` attribute。對一個 controlled component 來說這是比較方便的,因為你只需要在一個地方更新它。例如: | ||||||
|
||||||
|
||||||
```javascript{4,10-12,24} | ||||||
class FlavorForm extends React.Component { | ||||||
|
@@ -178,33 +179,33 @@ class FlavorForm extends React.Component { | |||||
} | ||||||
``` | ||||||
|
||||||
[**Try it on CodePen**](https://codepen.io/gaearon/pen/JbbEzX?editors=0010) | ||||||
[**在 CodePen 上試試看吧!**](https://codepen.io/gaearon/pen/JbbEzX?editors=0010) | ||||||
|
||||||
Overall, this makes it so that `<input type="text">`, `<textarea>`, and `<select>` all work very similarly - they all accept a `value` attribute that you can use to implement a controlled component. | ||||||
整體來說,這使得 `<input type="text">`,`<textarea>` 和 `<select>` 使用起來都很類似。它們全都會接收一個你在實作一個 controlled component 時會使用到的 `value` attribute。 | ||||||
|
||||||
> Note | ||||||
> 注意 | ||||||
> | ||||||
> You can pass an array into the `value` attribute, allowing you to select multiple options in a `select` tag: | ||||||
> 你可以將一個 array 傳給 `value` 這個 attribute,這使得你可以在一個 `select` 中選取多個選項: | ||||||
> | ||||||
>```js | ||||||
><select multiple={true} value={['B', 'C']}> | ||||||
>``` | ||||||
|
||||||
## The file input Tag {#the-file-input-tag} | ||||||
## 檔案 input 標籤 {#the-file-input-tag} | ||||||
|
||||||
In HTML, an `<input type="file">` lets the user choose one or more files from their device storage to be uploaded to a server or manipulated by JavaScript via the [File API](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications). | ||||||
在 HTML 中,`<input type="file">` 讓使用者從它們的儲存裝置中選擇一個至多個檔案,並把它們上傳到伺服器或透過 [File API](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications) 被 JavaScript 處理。 | ||||||
|
||||||
```html | ||||||
<input type="file" /> | ||||||
``` | ||||||
|
||||||
Because its value is read-only, it is an **uncontrolled** component in React. It is discussed together with other uncontrolled components [later in the documentation](/docs/uncontrolled-components.html#the-file-input-tag). | ||||||
由於它的值是唯讀,它在 React 中是一個 **uncontrolled** component。[在稍後的文件中](/docs/uncontrolled-components.html#the-file-input-tag)有其他關於它和其他 uncontrolled component 的討論。 | ||||||
|
||||||
## Handling Multiple Inputs {#handling-multiple-inputs} | ||||||
## 處理多個輸入 {#handling-multiple-inputs} | ||||||
|
||||||
When you need to handle multiple controlled `input` elements, you can add a `name` attribute to each element and let the handler function choose what to do based on the value of `event.target.name`. | ||||||
當你需要處理多個 controlled `input` element,你可以在每個 element 中加入一個 `name` attribute,並讓 handler function 選擇基於 `event.target.name` 的值該怎麼做: | ||||||
|
||||||
For example: | ||||||
例如: | ||||||
|
||||||
```javascript{15,18,28,37} | ||||||
class Reservation extends React.Component { | ||||||
|
@@ -254,31 +255,31 @@ class Reservation extends React.Component { | |||||
} | ||||||
``` | ||||||
|
||||||
[**Try it on CodePen**](https://codepen.io/gaearon/pen/wgedvV?editors=0010) | ||||||
[**在 CodePen 上試試看吧!**](https://codepen.io/gaearon/pen/wgedvV?editors=0010) | ||||||
|
||||||
Note how we used the ES6 [computed property name](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Object_initializer#Computed_property_names) syntax to update the state key corresponding to the given input name: | ||||||
注意我們使用了 ES6 的 [computed property name](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Object_initializer#Computed_property_names) 語法來更新與輸入中的 name 相對應的 state key: | ||||||
|
||||||
```js{2} | ||||||
this.setState({ | ||||||
[name]: value | ||||||
}); | ||||||
``` | ||||||
|
||||||
It is equivalent to this ES5 code: | ||||||
這和下面的 ES5 程式碼是ㄧ樣的: | ||||||
|
||||||
```js{2} | ||||||
var partialState = {}; | ||||||
partialState[name] = value; | ||||||
this.setState(partialState); | ||||||
``` | ||||||
|
||||||
Also, since `setState()` automatically [merges a partial state into the current state](/docs/state-and-lifecycle.html#state-updates-are-merged), we only needed to call it with the changed parts. | ||||||
此外,由於 `setState()` 自動 [merge 一部分的 state 和現在的 state](/docs/state-and-lifecycle.html#state-updates-are-merged),我們只需要在有改變的地方呼叫它即可。 | ||||||
|
||||||
## Controlled Input Null Value {#controlled-input-null-value} | ||||||
## Controlled 輸入值為 Null {#controlled-input-null-value} | ||||||
|
||||||
Specifying the value prop on a [controlled component](/docs/forms.html#controlled-components) prevents the user from changing the input unless you desire so. If you've specified a `value` but the input is still editable, you may have accidentally set `value` to `undefined` or `null`. | ||||||
在一個 [controlled component](/docs/forms.html#controlled-components) 上指明 value prop 可避免使用者改變輸入,除非你希望使用者這樣做。如果你已經指明了 `value` 但輸入仍然是可以被修改的,你很可能是不小心將 `value` 的值設定為 `undefined` 或 `null`。 | ||||||
|
||||||
The following code demonstrates this. (The input is locked at first but becomes editable after a short delay.) | ||||||
下面的程式碼就是一個範例。(輸入原先是被鎖住的,但在短暫的延遲後,變得可以被修改了。) | ||||||
|
||||||
```javascript | ||||||
ReactDOM.render(<input value="hi" />, mountNode); | ||||||
|
@@ -289,10 +290,10 @@ setTimeout(function() { | |||||
|
||||||
``` | ||||||
|
||||||
## Alternatives to Controlled Components {#alternatives-to-controlled-components} | ||||||
## Controlled component 的替代方案 {#alternatives-to-controlled-components} | ||||||
|
||||||
It can sometimes be tedious to use controlled components, because you need to write an event handler for every way your data can change and pipe all of the input state through a React component. This can become particularly annoying when you are converting a preexisting codebase to React, or integrating a React application with a non-React library. In these situations, you might want to check out [uncontrolled components](/docs/uncontrolled-components.html), an alternative technique for implementing input forms. | ||||||
有時候使用 controlled component 是很乏味的,因為你需要為每一個資訊可以改變的方式寫一個 event handler,並將所有的輸入 state 透過一個 React component 來傳遞。這在你將一個舊的程式庫改寫成 React 時或將一個 React 的應用程式與一個非 React 的函式庫整合時會變得特別麻煩。在這種情況中,你也許會想參考 [uncontrolled component](/docs/uncontrolled-components.html),也就是另一種取代輸入表格的方式。 | ||||||
|
||||||
## Fully-Fledged Solutions {#fully-fledged-solutions} | ||||||
## 成熟的解決方案 {#fully-fledged-solutions} | ||||||
|
||||||
If you're looking for a complete solution including validation, keeping track of the visited fields, and handling form submission, [Formik](https://jaredpalmer.com/formik) is one of the popular choices. However, it is built on the same principles of controlled components and managing state — so don't neglect to learn them. | ||||||
如果你想找出一個完整的、包含驗證、可追蹤 visited field 並能處理遞交表格等功能的解決方案,[Formik](https://jaredpalmer.com/formik) 是一個很熱門的選擇。然而,它是在與 controlled component 和維持 state 相同的原則上所建立的,所以別忘了學習它。 | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think
簡單
more intuitive.