Skip to content

Translating "forms" page, and a typo fixed #17

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

Merged
merged 8 commits into from
Feb 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ This repo contains the source code and documentation powering [reactjs.org](http

### Installation

1. `cd reactjs.org` to go into the project root
1. `cd ar.reactjs.org` to go into the project root
1. `yarn` to install the website's npm dependencies

### Running locally
Expand Down
88 changes: 47 additions & 41 deletions content/docs/forms.md
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
Expand All @@ -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:
تعمل عناصر النماذج بشكلٍ مختلفٍ قليلًا عن بقيّة عناصر DOM الأخرى في React بسبب احتفاظ عناصر النماذج بشكل طبيعي بحالة داخلية خاصّة بها. فمثلًا يقبل هذا النموذج في HTML اسمًا واحدًا:

```html
<form>
Expand All @@ -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".

## Controlled Components {#controlled-components}
يمتلك هذا النموذج نفس السّلوك الافتراضي لنماذج HTML من حيث الانتقال إلى صفحة جديدة عندما يضغط المستخدم على زر تقديم البيانات (Submit)، وإن أردت فقط هذا السّلوك في React فسيعمل بشكل جيّد معك، ولكن في معظم الأحيان من الملائم أكثر أن نمتلك دالة في JavaScript تتعامل مع تقديم البيانات ولديها الوصول إلى البيانات التي أدخلها المستخدم في النموذج. الطريقة القياسيّة لتحقيق هذا الأمر هي باستخدام تقنيّة تدعى المُكوِّنات المضبوطة (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).
## المكونات المضبوطة {#controlled-components}

تُحافِظ عناصر النموذج في HTML مثل `<input>`، و `<textarea>`، و `<select>` على حالتها الخاصّة وتُحدِثها وفقًا لمُدخلات المستخدم. أمّا في React فيُحتفَظ بحالة قابلة للتعديل ضمن خاصيّة الحالة للمُكوِّنات وتُحدَّث فقط عن طريق التابع [`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 المصدر الوحيد للحقيقة، فبذلك يُصبِح مُكوِّن React الذي يُصيِّر النموذج مُتحكِّمًا أيضًا بما يحدث في ذلك النموذج مع تتالي مُدخلات المستخدم. يُدعى عنصر الإدخال والذي تتحكّم React بقيمته بالمُكوِّن المضبوط.

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:
على سبيل المثال إن أردنا في المثال السّابق أن نعرض الاسم بعد تقديمه فبإمكاننا كتابة النموذج كمُكوِّن مضبوط:

```javascript{4,10-12,24}
class NameForm extends React.Component {
Expand Down Expand Up @@ -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` مُعيَّنة عن طريق عنصر النموذج فستكون قيمتها المعروضة دومًا هي `this.state.value`، وبذلك نجعل حالة React المصدر الوحيد للحقيقة. وبما أنّ التابع `handleChange` يُنفَّذ عند كل ضغطة زر من المستخدم ليُحدِّث حالة React، فستتحدّث القيمة المعروضة بينما يكتب المستخدم.

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:
في المكونات المضبوطة يكون لكل تغيير للحالة دالة للتعامل مع ذلك مُوافِقة له. يجعل ذلك من تعديل دخل المستخدم والتحقّق منه أمرًا سهلًا، فمثلًا لو أردنا إجبار المستخدم على كتابة الأحرف بحالة كبيرة سنكتب الدالة `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>` بشكلٍ مباشر كما يلي:

```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` بدلًا من ذلك، وبهذه الطريقة يُمكِن كتابة النموذج الذي يستخدم `<textarea>` بشكلٍ مُشابِه للحقل الذي يستخدم عنصر الإدخال `<input>`:

```javascript{4-6,12-14,26}
class EssayForm extends React.Component {
Expand Down Expand Up @@ -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)، وبذلك نضمن وجود نص ضمن العنصر `<textarea>` منذ البداية.

## 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
<select>
Expand All @@ -138,7 +138,7 @@ 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` بجانبه، ولكن في React بدلًا من استخدام الخاصيّة `selected` نستخدم الخاصيّة `value` ضمن العنصر `<select>` وهذا أسهل في المُكوِّنات المضبوطة لأنّك ستحتاج لتعديلها فقط في مكانٍ واحد. على سبيل المثال:

```javascript{4,10-12,24}
class FlavorForm extends React.Component {
Expand Down Expand Up @@ -178,33 +178,35 @@ 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>` تعمل بشكلٍ مماثل، فجميعها تقبل الخاصيّة value والتي نستخدمها لتنفيذ المُكوِّن المضبوط.

> Note
ملاحظة: بإمكانك تمرير مصفوفة إلى الخاصيّة `value` حيث يُتيح لك ذلك انتقاء عدّة خيارات في العنصر `<select>` :

> ملاحظة
>
> You can pass an array into the `value` attribute, allowing you to select multiple options in a `select` tag:
> بإمكانك تمرير مصفوفة إلى الخاصيّة `value` حيث يُتيح لك ذلك انتقاء عدّة خيارات في العنصر `<select>` :
>
>```js
><select multiple={true} value={['B', 'C']}>
>```

## The file input Tag {#the-file-input-tag}
## عنصر إدخال الملفات {#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">`‎ للمستخدم أن يختار ملفًّا واحدًا أو أكثر من جهازه لتحميلها إلى الخادم أو التعامل معها عن طريق JavaScript وذلك عبر [واجهة برمجة التطبيق الخاصّة بالملف](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications).

```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).

## Handling Multiple Inputs {#handling-multiple-inputs}
وبما أنّ قيمته هي قابلة للقراءة-فقط فهو مُكوِّن غير مضبوط (uncontrolled component) في React، سنناقش هذا المُكوِّن مع المُكوِّنات غير المضبوطة الأخرى في
[قسمها الخاص](/docs/uncontrolled-components.html#the-file-input-tag).

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`.
## التعامل مع إدخالات متعددة {#handling-multiple-inputs}

For example:
عندما تحتاج إلى التعامل مع عناصر `input` مُتعدِّدة مضبوطة فبإمكانك إضافة الخاصيّة `name` إلى كل عنصر وتترك لدالة معالجة الأحداث أن تختار ما ستفعله بناءً على قيمة `event.target.name`.
فلنأخذ هذا المثال:

```javascript{15,18,28,37}
class Reservation extends React.Component {
Expand Down Expand Up @@ -254,31 +256,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 [اسم الخاصيّة المحسوب](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Object_initializer#Computed_property_names) لتحديث مفتاح الحالة بما يُوافِق الاسم المُدخَل:

```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()`‎ تدمج تلقائيًّا [حالة جزئيّة مع الحالة الحاليّة](/docs/state-and-lifecycle.html#state-updates-are-merged) سنحتاج فقط إلى استدعائها مع الأجزاء المتغيّرة.

## Controlled Input Null Value {#controlled-input-null-value}
## الإدخالات المضبوطة ذات القيمة 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`.
يمنع تحديد الخاصيّة `value` في [المُكوِّنات المضبوطة](/docs/forms.html#controlled-components) المستخدم من تغيير المُدخلات ما لم ترغب بذلك. إن حدَّدت القيمة `value` وبقي العنصر `input` قابلًا للتعديل فربّما قد عيّنت `value` إلى القيمة `undefined` أو `null` من غير قصد.

The following code demonstrates this. (The input is locked at first but becomes editable after a short delay.)
تُوضِّح الشيفرة التالية هذا (يكون العنصر input مقفولًا في البداية ثم يُصبِح قابلًا للتعديل بعد فترة زمنيّة قصيرة):

```javascript
ReactDOM.render(<input value="hi" />, mountNode);
Expand All @@ -289,10 +291,14 @@ setTimeout(function() {

```

## Alternatives to Controlled Components {#alternatives-to-controlled-components}
## بدائل المكونات المضبوطة {#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.
قد يُصبِح استخدام المكونات المضبوطة مُمِلًّا أحيانًا لأنّك تحتاج إلى كتابة مُعالِج أحداث لكل طريقة قد تتغيّر بها بياناتك وإلى توجيه جميع حالات الإدخال عبر مُكوِّن React. يُصبِح هذا مُزعجًا بشكلٍ خاص عند تحويل الشيفرة الموجودة سابقًا إلى React أو عند دمج تطبيق React مع مكتبة أخرى. في هذه الحالات قد ترغب باستخدام المُكوِّنات غير المضبوطة
([uncontrolled components](/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.
إذا كنت تبحث عن حل كامل بما في ذلك التحقق من صحة الحقول، وتتبع الحقول التي قمت بزيارتها، والتعامل مع إرسال النموذج، فإن
[Formik](https://jaredpalmer.com/formik)
هو أحد الخيارات الشائعة. ومع ذلك، فهو مبني على نفس المبادئ للمكونات المضبوطة وإدارة الحالة(state) - لذا لا تهمل تعلمها.
28 changes: 14 additions & 14 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -10220,15 +10220,15 @@ react-dev-utils@^4.2.1:
strip-ansi "3.0.1"
text-table "0.2.0"

react-dom@16.7.0-alpha.0:
version "16.7.0-alpha.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.7.0-alpha.0.tgz#8379158d4c76d63c989f325f45dfa5762582584f"
integrity sha512-/XUn1ldxmoV2B7ov0rWT5LMZaaHMlF9GGLkUsmPRxmWTJwRDOuAPXidSaSlmR/VOhDSI1s+v3+KzFqhhDFJxYA==
react-dom@16.8.2:
version "16.8.2"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.8.2.tgz#7c8a69545dd554d45d66442230ba04a6a0a3c3d3"
integrity sha512-cPGfgFfwi+VCZjk73buu14pYkYBR1b/SRMSYqkLDdhSEHnSwcuYTPu6/Bh6ZphJFIk80XLvbSe2azfcRzNF+Xg==
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"
prop-types "^15.6.2"
scheduler "^0.11.0-alpha.0"
scheduler "^0.13.2"

react-error-overlay@^3.0.0:
version "3.0.0"
Expand Down Expand Up @@ -10282,15 +10282,15 @@ react-side-effect@^1.1.0:
exenv "^1.2.1"
shallowequal "^1.0.1"

react@16.7.0-alpha.0:
version "16.7.0-alpha.0"
resolved "https://registry.yarnpkg.com/react/-/react-16.7.0-alpha.0.tgz#e2ed4abe6f268c9b092a1d1e572953684d1783a9"
integrity sha512-V0za4H01aoAF0SdzahHepvfvzTQ1xxkgMX4z8uKzn+wzZAlVk0IVpleqyxZWluqmdftNedj6fIIZRO/rVYVFvQ==
react@16.8.2:
version "16.8.2"
resolved "https://registry.yarnpkg.com/react/-/react-16.8.2.tgz#83064596feaa98d9c2857c4deae1848b542c9c0c"
integrity sha512-aB2ctx9uQ9vo09HVknqv3DGRpI7OIGJhCx3Bt0QqoRluEjHSaObJl+nG12GDdYH6sTgE7YiPJ6ZUyMx9kICdXw==
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"
prop-types "^15.6.2"
scheduler "^0.11.0-alpha.0"
scheduler "^0.13.2"

read-all-stream@^3.0.0:
version "3.1.0"
Expand Down Expand Up @@ -10964,10 +10964,10 @@ sax@>=0.6.0, sax@^1.2.4, sax@~1.2.1, sax@~1.2.4:
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==

scheduler@^0.11.0-alpha.0:
version "0.11.0-alpha.0"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.11.0-alpha.0.tgz#7b132c726608993471db07866f2d59a52b9e190b"
integrity sha512-0tUDHYSyni/EHkMMBysVXVwfanCWWbLsulnDB1tGrQiWWrVuRVoclWCPHCYC/1iR5Rj34EQhxh3/F36V+F+ZpA==
scheduler@^0.13.2:
version "0.13.2"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.2.tgz#969eaee2764a51d2e97b20a60963b2546beff8fa"
integrity sha512-qK5P8tHS7vdEMCW5IPyt8v9MJOHqTrOUgPXib7tqm9vh834ibBX5BNhwkplX/0iOzHW5sXyluehYfS9yrkz9+w==
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"
Expand Down