You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<Illustrationcaption="Computer inputs"alt="Ones and zeroes."src="/images/docs/illustrations/i_inputs2.png" />
325
325
</IllustrationBlock>
326
326
327
-
In both cases,**you must set [state variables](/learn/state-a-components-memory#anatomy-of-usestate)to update the UI.**For the form you're developing, you will need to change state in response to a few different inputs:
327
+
في كلتا الحالتين،**يجب عليك تعيين [متغيرات الحالة (state variables)](/learn/state-a-components-memory#anatomy-of-usestate)لتُحدّث واجهة المستخدم (UI).**من أجل النموذج الذي تطوره، سوف تحتاج لتغيير الحالة كنتيجة لقليل من المدخلات المختلفة:
328
328
329
-
***Changing the text input** (human) should switch it from the *Empty* state to the *Typing* state or back, depending on whether the text box is empty or not.
330
-
***Clicking the Submit button** (human) should switch it to the *Submitting* state.
329
+
**تغيرت مدخل النص** (الإنسان) سوف يغيرها من الحالة *الفارغة* إلى حالة *الكتابة* أو العكس، يعتمد على ما إذا كان حقل النص فارغًا أم لا.
330
+
**الضغط على زر الإرسال** (الإنسان) سوف يغيرها إلى حالة *الإرسال*
331
331
***Successful network response** (computer) should switch it to the *Success* state.
332
332
***Failed network response** (computer) should switch it to the *Error* state with the matching error message.
333
333
334
334
<Note>
335
335
336
-
Notice that human inputs often require [event handlers](/learn/responding-to-events)!
336
+
لاحظ أن مدخلات الإنسان غالبًا تتطلب [معالجات أحداث (event handlers)](/learn/responding-to-events)!
337
337
338
338
</Note>
339
339
340
-
To help visualize this flow, try drawing each state on paper as a labeled circle, and each change between two states as an arrow. You can sketch out many flows this way and sort out bugs long before implementation.
340
+
للمساعدة على تصوّر هذا التدفق، جرّب رسم كل حالة على ورقة كدائرة مُعنّوَنة. وكل تغيّر بين حالتين كسهم. تستطيع رسم العديد من التدفقات بهذه الطريقة وحل الأخطاء مبكرًا قبل التنفيذ.
341
341
342
342
<DiagramGroup>
343
343
344
344
<Diagramname="responding_to_input_flow"height={350}width={688}alt="Flow chart moving left to right with 5 nodes. The first node labeled 'empty' has one edge labeled 'start typing' connected to a node labeled 'typing'. That node has one edge labeled 'press submit' connected to a node labeled 'submitting', which has two edges. The left edge is labeled 'network error' connecting to a node labeled 'error'. The right edge is labeled 'network success' connecting to a node labeled 'success'.">
345
345
346
-
Form states
346
+
حالات النموذج
347
347
348
348
</Diagram>
349
349
350
350
</DiagramGroup>
351
351
352
-
### Step 3: Represent the state in memory with`useState` {/*step-3-represent-the-state-in-memory-with-usestate*/}
352
+
### الخطوة 3: مثّل الحالة في الذاكرة باستخدام`useState` {/*step-3-represent-the-state-in-memory-with-usestate*/}
353
353
354
-
Next you'll need to represent the visual states of your component in memory with [`useState`.](/reference/react/useState)Simplicity is key: each piece of state is a "moving piece", and **you want as few "moving pieces" as possible.**More complexity leads to more bugs!
354
+
يلي ذلك ستحتاج لتمثّل الحالات المرئية لمكوّنك في الذاكرة باستخدام [`useState`.](/reference/react/useState)البساطة هي المفتاح: كل قطعة من الحالة هي "قطعة متحركة"، و**التقليل من "القطع المتحركة" قدر الإمكان هذا ما تريده.**;كثرة التعقيدات تؤدي إلى كثرة الأخطاء!
355
355
356
-
Start with the state that *absolutely must* be there. For example, you'll need to store the`answer`for the input, and the `error` (if it exists) to store the last error:
356
+
ابدأ بالحالة التي *لا بدّ* من وجودها. على سبيل المثال، سوف تحتاج لتخزين الإجابة`answer`للمدخل، والخطأ `error` (لو وُجد) لتخزين آخر خطأ:
357
357
358
358
```js
359
359
const [answer, setAnswer] =useState('');
360
360
const [error, setError] =useState(null);
361
361
```
362
362
363
-
Then, you'll need a state variable representing which one of the visual states that you want to display. There's usually more than a single way to represent that in memory, so you'll need to experiment with it.
363
+
بعد ذلك، سوف تحتاج لمتغير حالة يمثّل أي من الحالات المرئية التي تريد عرضها. يوجد غالبًا أكثر من طريقة واحدة لتمثيل ذلك في الذاكرة، لذلك سوف يتعين عليك تجريبها.
364
364
365
-
If you struggle to think of the best way immediately, start by adding enough state that you're *definitely* sure that all the possible visual states are covered:
365
+
إذا واجهت صعوبة في التفكير في أفضل طريقة على الفور، ابدا بإضافة حالة كافية حتى تكون متأكدًا *تمامًا* من تغطية جميع الحالات المرئية المحتملة:
Your first idea likely won't be the best, but that's ok--refactoring state is a part of the process!
375
+
خطوتك المبدأئية على الأرجح لن تكون هي الأفضل، ولكن هذا لا بأس به -- إعادة تصميم الحالة هو جزء من العملية!
376
376
377
-
### Step 4: Remove any non-essential state variables {/*step-4-remove-any-non-essential-state-variables*/}
377
+
### خطوة 4: احذف أيّ متغيرات حالة غير ضرورية {/*step-4-remove-any-non-essential-state-variables*/}
378
378
379
-
You want to avoid duplication in the state content so you're only tracking what is essential. Spending a little time on refactoring your state structure will make your components easier to understand, reduce duplication, and avoid unintended meanings. Your goal is to **prevent the cases where the state in memory doesn't represent any valid UI that you'd want a user to see.**(For example, you never want to show an error message and disable the input at the same time, or the user won't be able to correct the error!)
379
+
ما تريده هو تجنب تكرار محتوى الحالة لذلك أنت فقط تقوم بتعقب ما هو ضروري. قضاء قليل من الوقت في إعادة تصميم هيكل حالتك سوف يجعل مكوّنك أسهل للفهم، يقلل التكرار، ويتجنب المعاني غير المقصودة. هدفك هو **منع الأوضاع التي تكون بها الحالة في الذاكرة لا تمثل أي واجهة مستخدم صالحة تود للمستخدم أن يراها.**)u(على سبيل المثال، لن تريد أبدًا إظهار رسالة خطأ مع تعطيل الإدخال في نفس الوقت، أو أن المستخدم لن يكون قادرًا على تصحيح الخطأ!)
380
380
381
-
Here are some questions you can ask about your state variables:
381
+
هنا بعض الاسئلة التي يمكن أن تسألها عن متغيرات الحالة:
382
382
383
-
***Does this state cause a paradox?**For example, `isTyping`and`isSubmitting`can't both be `true`. A paradox usually means that the state is not constrained enough. There are four possible combinations of two booleans, but only three correspond to valid states. To remove the "impossible" state, you can combine these into a `status`that must be one of three values: `'typing'`, `'submitting'`, or`'success'`.
384
-
***Is the same information available in another state variable already?**Another paradox: `isEmpty`and`isTyping`can't be `true`at the same time. By making them separate state variables, you risk them going out of sync and causing bugs. Fortunately, you can remove`isEmpty`and instead check `answer.length === 0`.
385
-
***Can you get the same information from the inverse of another state variable?**`isError`is not needed because you can check `error !== null`instead.
383
+
***هل هذه الحالة تسبب معضلة؟**على سبيل المثال، `isTyping`و`isSubmitting`لا يمكن لكليهما أن يكونا بقيمة `true`. المعضلة غالبا تعني أن الحالة ليست مقيدة بالشكل الكافي. هناك أربع احتمالات ممكنة لاثنين من نوع boolean، لكن ثلاث منها فقط يوافقن حالات صالحة. لحذف الحالة "المستحيلة"، يمكنك جمع تلك الحالات داخل `status`التي يجب يجب أن تكون واحدة من ثلاث قيم: `'typing'`, `'submitting'`, أو`'success'`.
384
+
***هل نفس المعلومات متاحة بالفعل لمتغير حالة آخر؟**معضلة أخرى: `isEmpty`و`isTyping`لا يمكنها أن يكونا `true`في نفس الوقت. بجعلهما متغيرين حالة منفصلين، تخاطر بفقدان الترابط بينهما وإحداث الأخطاء. لحسن الحظ، يمكن حذف`isEmpty`والتحقق من `answer.length === 0` بدلًا عن ذلك.
385
+
***هل يمكنك الحصول على نفس المعلومات من من عكس متغير حالة آخر؟**`isError`غير ضروري لأنه يمكنك التحقق من `error !== null`بدلًا عن ذلك.
386
386
387
-
After this clean-up, you're left with 3 (down from 7!) *essential* state variables:
387
+
بعد هذا التبسيط، تبقى لديك 3 (من أصل 7!) متغيرات حالة *ضرورية*:
388
388
389
389
```js
390
390
const [answer, setAnswer] =useState('');
391
391
const [error, setError] =useState(null);
392
392
const [status, setStatus] =useState('typing'); // 'typing', 'submitting', or 'success'
393
393
```
394
394
395
-
You know they are essential, because you can't remove any of them without breaking the functionality.
395
+
أنت تعلم أنها ضرورية، لأنك لا تستطيع إزالة أيّ منها بدون تخريب آلية العمل
396
396
397
397
<DeepDive>
398
398
399
-
#### Eliminating “impossible” states with a reducer {/*eliminating-impossible-states-with-a-reducer*/}
399
+
#### إزالة الحالات "المستحيلة" باستخدام مخفض (reducer) {/*eliminating-impossible-states-with-a-reducer*/}
400
400
401
-
These three variables are a good enough representation of this form's state. However, there are still some intermediate states that don't fully make sense. For example, a non-null `error`doesn't make sense when `status`is `'success'`. To model the state more precisely, you can [extract it into a reducer.](/learn/extracting-state-logic-into-a-reducer)Reducers let you unify multiple state variables into a single object and consolidate all the related logic!
401
+
هذه الثلاث متغيرات تمثيل جيد كفاية لحالة النموذج. مع ذلك، لا تزال هناك بعض الحالات المتوسطة التي لا تشكّل معنى بصورة تامة. على سبيل المثال، `error`التي لا تحمل القيمة null ليس لها معنى عندما تكون `status`تحمل قيمة `success`. لتمثيل الحالة بطريقة أكثر دقة، يمكنك [استخلاصها إلى مخفض.](/learn/extracting-state-logic-into-a-reducer)المخفضات تتيح ليك توحيد العديد من متغيرات الحالة داخل كائن (object) واحد وتجميع كل المنطق المتعلق بها.
402
402
403
403
</DeepDive>
404
404
405
-
### Step 5: Connect the event handlers to set state {/*step-5-connect-the-event-handlers-to-set-state*/}
405
+
### الخطوة 5: اربط معالجات الأحداث لتعيين الحالة {/*step-5-connect-the-event-handlers-to-set-state*/}
406
406
407
+
أخيرًا، إنشاء معالجات الأحداث التي تحدّث الحالة. أدناه هو النموذج النهائي، مع كل معالجات الأحداث متصلة ببعضها:
407
408
Lastly, create event handlers that update the state. Below is the final form, with all event handlers wired up:
408
409
409
410
<Sandpack>
@@ -438,9 +439,9 @@ export default function Form() {
438
439
439
440
return (
440
441
<>
441
-
<h2>City quiz</h2>
442
+
<h2>اختبار المدينة</h2>
442
443
<p>
443
-
In which city is there a billboard that turns air into drinkable water?
444
+
في أي مدينة يوجد لوحة إعلانية تقوم بتحويل الهواء إلى مياه صالحة للشرب؟
444
445
</p>
445
446
<form onSubmit={handleSubmit}>
446
447
<textarea
@@ -466,7 +467,7 @@ export default function Form() {
466
467
}
467
468
468
469
function submitForm(answer) {
469
-
// Pretend it's hitting the network.
470
+
// محاكاة للتواصل باستخدام الشبكة.
470
471
return new Promise((resolve, reject) => {
471
472
setTimeout(() => {
472
473
let shouldError = answer.toLowerCase() !== 'lima'
@@ -486,17 +487,17 @@ function submitForm(answer) {
486
487
487
488
</Sandpack>
488
489
489
-
Although this code is longer than the original imperative example, it is much less fragile. Expressing all interactions as state changes lets you later introduce new visual states without breaking existing ones. It also lets you change what should be displayed in each state without changing the logic of the interaction itself.
490
+
بالرغم من أن هذا الكود أطول من المثال الأمريّ الأصلي، إلا أنه أقل هشاشة بكثير. التعبير عن جميع الأوامر على أنها تغيّرات في الحالة يتيح لك لاحقًا إضافة حالات مرئية جديدة دون تعطيل الحالات القائمة بالفعل. كما يتيح لك أيضًا تغيير ما يجب عرضه في كل حالة دون تغيير منطق الأمر نفسه.
490
491
491
492
<Recap>
492
493
493
-
* Declarative programming means describing the UI for each visual state rather than micromanaging the UI (imperative).
494
-
* When developing a component:
495
-
1. Identify all its visual states.
496
-
2. Determine the human and computer triggers for state changes.
497
-
3. Model the state with`useState`.
498
-
4. Remove non-essential state to avoid bugs and paradoxes.
499
-
5. Connect the event handlers to set state.
494
+
* البرمجة التصريحية تعني وصف واجهة المستخدم لكل حالة مرئية عوضًا عن الإدارة التفصيلية لواجهة المستخدم (الأمريّة).
495
+
* عند تطوير مكوّن:
496
+
1. حدد كل حالاته المرئية.
497
+
2. عيّن منشطات الإنسان والكمبيوتر لتغيّرات الحالة.
498
+
3. مثل الحالة عن طريق `useState`.
499
+
4. احذف الحالة غير الضرورية لتجنب الأخطاء والمعضلات.
0 commit comments