Skip to content

Commit 914e669

Browse files
authored
From L201 to L450
1 parent ba35b86 commit 914e669

1 file changed

Lines changed: 25 additions & 26 deletions

File tree

src/content/learn/thinking-in-react.md

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -206,18 +206,18 @@ td {
206206

207207
## الخطوة 3: حدد أبسط وأكمل تمثيل لحالات واجهة المستخدم {/*step-3-find-the-minimal-but-complete-representation-of-ui-state*/}
208208

209-
لجعل الواجهة تفاعلية؛ يجب أن تسمح للمستخدم بتعديل أنموذج بياناتك. لإنجاز ذلك، سيتعين عليك توظيف *الحالات*.
209+
لجعل الواجهة تفاعلية؛ يجب أن تسمح للمستخدم بتعديل نموذج بياناتك. لإنجاز ذلك، سيتعين عليك استخدام *الحالات*.
210210

211-
اعتبر الحالات كما لو أنها عدّتك من البيانات المتغيرة التي يجب أن يتذكرها تطبيقك. أهم مبدأ يجب أخذه في الاعتبار عند تحديد حالاتك هي أن تكون [فريدة](https://ar.wikipedia.org/wiki/%D9%84%D8%A7_%D8%AA%D9%83%D8%B1%D8%B1_%D9%86%D9%81%D8%B3%D9%83). حاول استنباط القدر الأدنى لتمثيل حالات تطبيقك المختلفة التي سيحتاجها، وقم باحتساب أي حالة أخرى تزيد على ذلك عند الحاجة. مثلا، إذا كنت تقوم ببناء قائمة مشتريات، يمكنك حفظ الأصناف كمصفوفة في حالة التطبيق. أما إذا احتجت لعرض عدد الأصناف في القائمة، فلا تقم بحفظ عدد الأصناف كحالة أخرى. عوضا عن ذلك؛ يمكنك دائما قراءة طول المصفوفة.
211+
اعتبر الحالات كما لو أنها عدّتك من البيانات المتغيرة التي يجب أن يتذكرها تطبيقك. أهم مبدأ يجب أخذه في الاعتبار عند تحديد حالاتك هو [عدم التكرار DRY](https://ar.wikipedia.org/wiki/%D9%84%D8%A7_%D8%AA%D9%83%D8%B1%D8%B1_%D9%86%D9%81%D8%B3%D9%83). حاول استنباط القدر الأدنى لتمثيل حالات تطبيقك المختلفة التي سيحتاجها، وقم باحتساب أي حالة أخرى تزيد على ذلك عند الحاجة. مثلا، إذا كنت تقوم ببناء قائمة مشتريات، يمكنك حفظ الأصناف كمصفوفة في حالة التطبيق. أما إذا احتجت لعرض عدد الأصناف في القائمة، فلا تقم بحفظ عدد الأصناف كحالة أخرى. عوضا عن ذلك؛ يمكنك دائما قراءة طول المصفوفة `Array.length`.
212212

213-
الآن فكر في كل ما قد تحتاجه من بيانات في تطبيقنا المفترض:
213+
الآن فكر في كل ما قد تحتاجه من بيانات في تطبيقنا:
214214

215215
1. القائمة الأصلية للمنتجات.
216216
2. كلمات البحث التي قام المستخدم بكتابتها.
217217
3. حالة مربع الاختيار (الخاص بإظهار المنتجات التي لها رصيد فقط).
218218
4. قائمة المنتجات بعد التصفية بكلمات البحث.
219219

220-
أيا مما سبق يعتبر حالة؟ يمكنك تمييزها بأنها لا تنطبق عليها المواصفات التالية:
220+
أي مما سبق يعتبر حالة؟ يمكنك تمييزها بأنها لا تنطبق عليها المواصفات التالية:
221221

222222
* هل تبقى دائما **ثابتة** لا تتغير؟ إذا ليست حالة..
223223
* هل **تم تمريرها من المكون الأب** عن طريق الخصائص؟ إذا ليست حالة.
@@ -227,7 +227,7 @@ td {
227227

228228
لنقم بمراجعتهم واحد تلو الآخر مرة أخرى:
229229

230-
1. القائمة الأصلية للمنتجات **يتم تمريرها ضمن الخصائص،فهي ليست حالة.**
230+
1. القائمة الأصلية للمنتجات **يتم تمريرها ضمن الخصائص، فهي ليست حالة.**
231231
2. كلمات البحث تبدو كحالة بما أنها تتغير مع مرور الوقت ولا يمكن اشتقاقها من أي شيء آخر.
232232
3. حالة مربع الاختيار تبدو كحالة بما أنها تتغير مع مرور الوقت ولا يمكن اشتقاقها من أي شيء آخر.
233233
4. قائمة المنتجات بعد التصفية **ليست حالة إذ يمكن اشتقاقها** عبر تصفية قائمة المنتجات الأصلية وفقا لكلمات البحث وحالة مربع الاختيار.
@@ -238,36 +238,35 @@ td {
238238

239239
#### الخصائص والحالات {/*props-vs-state*/}
240240

241-
يعتبر كل منهما من أحد أنواع البيانات "النموذجية" في React: الخصائص والحالة. يختلف كلاهما عن الآخر بفارق كبير:
241+
هناك نوعان من البيانات "الافتراضية" في React: الخصائص والحالة. يختلف كلاهما عن الآخر بفارق كبير:
242242

243-
* [**الخصائص (Props)** تشبه المعطيات](/learn/passing-props-to-a-component) التي تقوم بتمريرها لإحدى الدوال. تتيح لمكون أعلى أن تمرر بيانات لمكون تابع له وتنسيق مظهره أيضا. فمثلا، مكون `Form` يمكن أن يمرر خاصية `color` إلى `Button` لتغيير لونه.
244-
* [**الحالة (State)** تشبه ذاكرة المكون.](/learn/state-a-components-memory) تتيح للمكون إمكانية أن يحاقظ على اطلاعه على بعض البيانات وأن يغيرها تجاوبا مع تفاعل المستخدم. فمثلا, يمكن للزر `Button` أن يبقى على اطلاع لحالة `isHovered`.
243+
* [**الخصائص (Props)** تشبه المعطيات](/learn/passing-props-to-a-component) التي تقوم بتمريرها لإحدى الدوال. تتيح لمكون أعلى أن تمرر بيانات لمكون فرعي عنه وتنسيق مظهره أيضا. فمثلا، مكون `Form` يمكن أن يمرر خاصية `color` إلى `Button` لتغيير لونه.
244+
* [**الحالة (State)** تشبه ذاكرة المكون.](/learn/state-a-components-memory) تتيح للمكون إمكانية أن يبقى مطلعًا على بعض البيانات وأن يغيرها تجاوبا مع تفاعل المستخدم. فمثلا, يمكن للزر `Button` أن يبقى على اطلاع لحالة `isHovered`.
245245

246-
الخصائص والحالات أمران مختلفان، لكن يكملان بعضهما. قد يحتوي مكون ما على بعض البيانات في حالات (كي يتمكن من تغييرها) و *يمررها* لمكون تابع كخصائص لها. لا بأس إن كنت تشعر أن الفارق بينهما لا يزال غامضا. قد يستلزم الأمر بعض الممارسة لتتمكن من الإلمام به!
246+
الخصائص والحالات أمران مختلفان، لكن يكملان بعضهما. قد يحتوي مكون ما على بعض البيانات في حالات (كي يتمكن من تغييرها) و *يمررها* لمكون تابع كخصائص لها. لا بأس إن كنت تشعر أن الفارق بينهما لا يزال غامضا. قد يستلزم الأمر بعض الممارسة لتلمّ به!
247247

248248
</DeepDive>
249249

250250
## الخطوة 4: حدد أين تضع الحالات {/*step-4-identify-where-your-state-should-live*/}
251251

252-
بعد أن حدد القدر الأدنى من بيانات الحالات اللازمة، عليك الأن أن تحدد أي المكونات مسءول عن تغيير كلٌّ من هذه الحالات، أو *يملك* تلك الحالة. تذكر أن React يستخدم سيل البيانات في اتجاه واحد، وهو تمرير البيانات من المكون الأب لمكون تابع له في التسلسل الشجري. قد لا يبدو واضحا من الوهلة الأولى أي مكون يجب أن يملك تلك "الحالة" ويكون مسؤولا عنها. ربما يكون هذا تحديا لك إن كان هذا المفهوم جديدا عليك،لكن ستتمكن من إيجاد الإجابة باتباع الخطوات التالية!
252+
بعد تحديد القدر الأدنى من بيانات الحالات اللازمة، عليك الآن أن تحدد أي المكونات مسئول عن تغيير كلٌّ من هذه الحالات، أو *يملك* تلك الحالة. تذكر أن React يستخدم سيل البيانات في اتجاه واحد، وهو تمرير البيانات من المكون الأب لمكون تابع له في التسلسل الشجري. قد لا يبدو واضحا من الوهلة الأولى أي مكون يجب أن يملك تلك "الحالة" ويكون مسؤولا عنها. ربما يكون هذا تحديا لك إن كان هذا المفهوم جديدا عليك، لكن ستتمكن من إيجاد الإجابة باتباع الخطوات التالية!
253253

254254
لكل حالة على حدة في تطبيقك:
255255

256256
1. حدد *جميع* المكونات التي تعرض أي شيء له علاقة بهذه الحالة.
257-
2. حدد السلف الأقرب المشترك بينهم؛ مكون يكون أعلى منهم جميعا في التسلسل الشجري.
257+
2. حدد السلف المشترك الأقرب بينهم؛ مكون يكون أعلى منهم جميعا في التسلسل الشجري.
258258
3. حدد أين يجب أن تتمركز الحالة:
259259
1. عادة، يمكنك وضع الحالة مباشرة في سلفهم المشترك.
260260
2. يمكنك أيضا أن تضع الحالة في مكون أعلى من السلف المشترك.
261261
3. إن لم يكن بإمكانك تحديد مكون حيث يبدو من المنطقي وضع الحالة فيه، قم بعمل مكون جديد خصيصا لحفظ تلك الحالة، وقم بوضعه في مكان ما في التسلسل الشجري يسبق سلفهم المشترك.
262262

263263
في الخطوة السابقة، وجدت حالتين في هذا التطبيق: نص البحث المكتوب، وحالة مربع الاختيار. في هذا المثال، يظهران دائما معا، فمن المنطقي وضعهم معا في نفس المكان.
264264

265-
Now let's run through our strategy for them:
266-
حسنا، لنقوم باختبار طريقتنا عليهم:
265+
حسنا، لنختبر طريقتنا عليهم:
267266

268267
1. **حدد المكونات التي تستخدم الحالة:**
269-
* مكون (جدول المنتجات) `ProductTable` يحتاج الحالة ليقوم بتصفية قائمة المنتجات (نص البحث وحالة مربع الاختيار).
270-
* مكون (خانة البحث) `SearchBar` يقوم بعرض الحالة نفسها (نص البحث).
268+
* مكون `ProductTable` (جدول المنتجات) يحتاج الحالة ليقوم بتصفية قائمة المنتجات (نص البحث وحالة مربع الاختيار).
269+
* مكون `SearchBar` (خانة البحث) يقوم بعرض الحالة نفسها (نص البحث).
271270
1. **حدد لهم سلفا مشتركا:** السلف المشترك للمكونين هو `FilterableProductTable`.
272271
2. **حدد أين تضع الحالة**: سنضع نص البحث وحالة مربع الاختيار في المكون `FilterableProductTable`.
273272

@@ -281,7 +280,7 @@ function FilterableProductTable({ products }) {
281280
const [inStockOnly, setInStockOnly] = useState(false);
282281
```
283282
284-
ثم مرر المتغير `filterText` و `inStockOnly` للمكونين `ProductTable` و `SearchBar` كخاصية ضمن خصائص كلا منهما:
283+
ثم مرر المتغير `filterText` و`inStockOnly` للمكونين `ProductTable` و`SearchBar` كخاصية ضمن خصائص كل منهما:
285284
286285
```js
287286
<div>
@@ -291,12 +290,10 @@ function FilterableProductTable({ products }) {
291290
<ProductTable
292291
products={products}
293292
filterText={filterText}
294-
inStockOnly={inStockOnly} />
295-
</div>
293+
inStockOnly={inStockOnly} /></div>
296294
```
297295
298-
You can start seeing how your application will behave. Edit the `filterText` initial value from `useState('')` to `useState('fruit')` in the sandbox code below. You'll see both the search input text and the table update:
299-
قد يبدو واضحا لك من الآن كيف سيبدو سلوك تطبيقك. قم بتعديل قيمة `filterText` الأولية من `useState('')` إلى `useState('fruit')` في الكود التالي داخل الـsandbox المدرج. سترى نتيجة التعديل على كلا من محتوى خانة البحث وجدول المنتجات:
296+
قد يبدو واضحا لك من الآن كيف سيبدو سلوك تطبيقك. قم بتعديل قيمة `filterText` الأولية من `useState('')` إلى `useState('fruit')` في الكود التالي داخل الـsandbox المدرج. سترى نتيجة التعديل على كل من محتوى خانة البحث وجدول المنتجات:
300297
301298
<Sandpack>
302299
@@ -393,13 +390,13 @@ function SearchBar({ filterText, inStockOnly }) {
393390
<input
394391
type="text"
395392
value={filterText}
396-
placeholder="Search..."/>
393+
placeholder="بحث..."/>
397394
<label>
398395
<input
399396
type="checkbox"
400397
checked={inStockOnly} />
401398
{' '}
402-
Only show products in stock
399+
عرض المنتجات المتوفرة فقط
403400
</label>
404401
</form>
405402
);
@@ -438,15 +435,17 @@ td {
438435
439436
</Sandpack>
440437
441-
لاحظ أنك لو عدلت مباشرة على نموذج البحث فلن يحدث شيء. هناك رسالة خطأ في الـsandbox أعلاه تخبرك لماذا:
438+
لاحظ أنك لو عدّلت مباشرة على نموذج البحث فلن يحدث شيء. هناك رسالة خطأ في الـsandbox أعلاه تخبرك لماذا:
442439
443440
<ConsoleBlock level="error">
441+
442+
You provided a \`value\` prop to a form field without an \`onChange\` handler. This will render a read-only field.
444443
445444
لقد قمت بتمرير \`قيمة\` إحدى الخصائص لإحدى خانات نموذج دون تحديد معالج لحدث تغير القيمة \`onChange\`. سينتج عن هذا خانة قابلة للقراءة فقط.
446445
447446
</ConsoleBlock>
448447
449-
في الـsandbox أعلاه؛ المكونان `ProductTable` و `SearchBar` يقرآن الخصائص `filterText` و `inStockOnly` لعرض الجدول، مربع البحث، ومربع الاختيار. إليك مثلا كيف يقوم المكون `SearchBar` بكتابة محتوى مربع البحث:
448+
في الـsandbox أعلاه؛ المكونان `ProductTable` و`SearchBar` يقرآن الخصائص `filterText` و`inStockOnly` لعرض الجدول، ومربع البحث، ومربع الاختيار. إليك مثلا كيف يقوم المكون `SearchBar` بكتابة محتوى مربع البحث:
450449
451450
```js {1,6}
452451
function SearchBar({ filterText, inStockOnly }) {
@@ -455,10 +454,10 @@ function SearchBar({ filterText, inStockOnly }) {
455454
<input
456455
type="text"
457456
value={filterText}
458-
placeholder="Search..."/>
457+
placeholder="بحث..."/>
459458
```
460459
461-
برغم ذلك، فأنت لم تقم بعد بكتابة أي كود للتجاوب مع تفاعلات المستخدم (كالكتابة). هذه ستكون خطوتك الأخيرة.
460+
برغم ذلك، فأنت لم تكتب بعد أي كود للتجاوب مع تفاعلات المستخدم (كالكتابة). هذه ستكون خطوتك الأخيرة.
462461
463462
464463
## الخطوة 5: إضافة تدفق البيانات العكسي {/*step-5-add-inverse-data-flow*/}

0 commit comments

Comments
 (0)