From ab075c5c5427dae2cdac1310f9d9e36dca6d6cbb Mon Sep 17 00:00:00 2001 From: Hosam Hamdy Date: Thu, 27 Apr 2023 15:59:49 +0200 Subject: [PATCH 01/11] finished from intro to Step1 --- src/content/learn/thinking-in-react.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/content/learn/thinking-in-react.md b/src/content/learn/thinking-in-react.md index 23d4beb3f..db05bcdc8 100644 --- a/src/content/learn/thinking-in-react.md +++ b/src/content/learn/thinking-in-react.md @@ -1,18 +1,18 @@ --- -title: Thinking in React +title: على طريقة React --- -React can change how you think about the designs you look at and the apps you build. When you build a user interface with React, you will first break it apart into pieces called *components*. Then, you will describe the different visual states for each of your components. Finally, you will connect your components together so that the data flows through them. In this tutorial, we’ll guide you through the thought process of building a searchable product data table with React. +قد يغير React من الطريقة التي ترى بها التصاميم أو تبني بها التطبيقات. عندما تقوم ببناء واجهة للمستخدم بـ React سيتوجب عليك أولا أن تفصلها لأجزاء تدعى *مكونات*. بعد ذلك، تقوم بوصف الحالات الظاهرية المختلفة لكل مكون على حدته. وأخيرا، تقوم بربط مكوناتك معا كي تسري البيانات خلالها بانسيابية. في هذا الدرس، سنخوض معك في عملية التفكير في بناء جدول بيانات لمنتجات، مع إمكانية البحث فيه. -## Start with the mockup {/*start-with-the-mockup*/} +## ابدأ بالنموذج التقريبي {/*start-with-the-mockup*/} -Imagine that you already have a JSON API and a mockup from a designer. +لنفرض أن لديك واجهة برمجة لـ JSON ونموذج تقريبي من أحد المصممين. -The JSON API returns some data that looks like this: +واجهة JSON البرمجية تعطيك بيانات كالتالي: ```json [ @@ -25,13 +25,13 @@ The JSON API returns some data that looks like this: ] ``` -The mockup looks like this: +والنموذج التقريبي يبدو هكذا: -To implement a UI in React, you will usually follow the same five steps. +لتنفيذ واجهة مستخدم في React, ستسير عادة على نفس الخطوات الخمسة الآتية. -## Step 1: Break the UI into a component hierarchy {/*step-1-break-the-ui-into-a-component-hierarchy*/} +## الخطوة 1: قسم الواجهة إلى شجرة من المكونات {/*step-1-break-the-ui-into-a-component-hierarchy*/} Start by drawing boxes around every component and subcomponent in the mockup and naming them. If you work with a designer, they may have already named these components in their design tool. Ask them! From b63b3f9e6d826cc34f2dd55279a0522c4e6dd4c7 Mon Sep 17 00:00:00 2001 From: Hosam Hamdy Date: Fri, 28 Apr 2023 18:22:29 +0200 Subject: [PATCH 02/11] finished through the first diagram --- src/content/learn/thinking-in-react.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/content/learn/thinking-in-react.md b/src/content/learn/thinking-in-react.md index db05bcdc8..b176db1d8 100644 --- a/src/content/learn/thinking-in-react.md +++ b/src/content/learn/thinking-in-react.md @@ -33,29 +33,29 @@ title: على طريقة React ## الخطوة 1: قسم الواجهة إلى شجرة من المكونات {/*step-1-break-the-ui-into-a-component-hierarchy*/} -Start by drawing boxes around every component and subcomponent in the mockup and naming them. If you work with a designer, they may have already named these components in their design tool. Ask them! +ابدأ برسم مربعات حول كل من المكونات ومكوناتها الفرعية في النموذج التقريبي، وقم بتسمية كل منها. إذا كنت تعمل مع مصمم، فلربما تجده قد قام بتسميتها بالفعل في البرامج التي يستخدمها، اسأله أولا! -Depending on your background, you can think about splitting up a design into components in different ways: +قد تختلف طريفة التفكير في تقسيم التصميم لمكونات بناء على خلفيتك المهنية إلى عدة طرق من حيث: -* **Programming**--use the same techniques for deciding if you should create a new function or object. One such technique is the [single responsibility principle](https://en.wikipedia.org/wiki/Single_responsibility_principle), that is, a component should ideally only do one thing. If it ends up growing, it should be decomposed into smaller subcomponents. -* **CSS**--consider what you would make class selectors for. (However, components are a bit less granular.) -* **Design**--consider how you would organize the design's layers. +* **البرمجة**--استخدم نفس الطرائق لتقرر إذا ما كان عليك إنشاء دالة (function) أو كائن. إحدى الطرائق المقصودة هي [مبدأ المهمة الواحدة](https://ar.wikipedia.org/wiki/%D9%85%D8%A8%D8%AF%D8%A3_%D8%A7%D9%84%D9%85%D9%87%D9%85%D8%A9_%D8%A7%D9%84%D9%88%D8%A7%D8%AD%D8%AF%D8%A9)، والتي تشير إلى أنه في أحسن الأحوال، يكون للمكون الواحد وظيفة واحدة فقط. وكلما زادت مهمات المكون، يجب تقسيمها لمكونات فرعية أصغر. +* **التنسيق (CSS)**--فكر فيما ستقوم بتخصيص أسماء تصنيفات (classes) له. (مع أن المكونات أصلا يفترض أنها صغيرة الحجم). +* **التصميم**--فكر كيف ستقوم بترتيب تراص طبقات التصميم. -If your JSON is well-structured, you'll often find that it naturally maps to the component structure of your UI. That's because UI and data models often have the same information architecture--that is, the same shape. Separate your UI into components, where each component matches one piece of your data model. - -There are five components on this screen: +إذا كان الـJSON الذي تستخدمه مهيأ بشكل جيد، فكثيرا ما ستجده يطابق وصفك وتقسيمك لمكونات واجهنك بكل سلاسة. ذلك أن واجهة المستخدم ونماذج البيانات عادة ما يكون لهما نفس بنية المعلومات. بمعنى آخر، لهما نفس الشكل. فقسم واجهتك إلى مكونات، حيث يتماشى كل مكون مع إحدى +أجزاء نموذج البيانات. +يوجد في هذه الصورة خمس مكونات: -1. `FilterableProductTable` (grey) contains the entire app. -2. `SearchBar` (blue) receives the user input. -3. `ProductTable` (lavender) displays and filters the list according to the user input. -4. `ProductCategoryRow` (green) displays a heading for each category. -5. `ProductRow` (yellow) displays a row for each product. +1. `FilterableProductTable` (باللون الرمادي - جدول منتجات قابل للبحث) يحوي البرنامج بالكامل. +2. `SearchBar` (بالأزرق - مربع بحث) حيث يكتب فيه المستخدم. +3. `ProductTable` (بالبنفسجي - جدول منتجات) يعرض المنتجات ونتائج البحث فيها بحسب مدخلات المستخدم. +4. `ProductCategoryRow` (بالأخضر - سطر خاص بنوع المنتج) يعرض عنوان لكل نوع من المنتجات. +5. `ProductRow` (بالأصفر - سطر المنتج) يعرض سطرا لكل منتج. From 2aaaa9098d2d8f7da9faf63b4428603a9cc178b5 Mon Sep 17 00:00:00 2001 From: Hosam Date: Fri, 28 Apr 2023 23:00:41 +0300 Subject: [PATCH 03/11] finshed through Step3 --- src/content/learn/thinking-in-react.md | 28 +++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/content/learn/thinking-in-react.md b/src/content/learn/thinking-in-react.md index b176db1d8..41f07cd73 100644 --- a/src/content/learn/thinking-in-react.md +++ b/src/content/learn/thinking-in-react.md @@ -12,7 +12,7 @@ title: على طريقة React لنفرض أن لديك واجهة برمجة لـ JSON ونموذج تقريبي من أحد المصممين. -واجهة JSON البرمجية تعطيك بيانات كالتالي: +واجهة JSON البرمجية أعطتك البيانات التالية: ```json [ @@ -29,19 +29,19 @@ title: على طريقة React -لتنفيذ واجهة مستخدم في React, ستسير عادة على نفس الخطوات الخمسة الآتية. +لتنفيذ واجهة مستخدم في React، ستسير عادة على نفس الخطوات الخمس التالية: ## الخطوة 1: قسم الواجهة إلى شجرة من المكونات {/*step-1-break-the-ui-into-a-component-hierarchy*/} ابدأ برسم مربعات حول كل من المكونات ومكوناتها الفرعية في النموذج التقريبي، وقم بتسمية كل منها. إذا كنت تعمل مع مصمم، فلربما تجده قد قام بتسميتها بالفعل في البرامج التي يستخدمها، اسأله أولا! -قد تختلف طريفة التفكير في تقسيم التصميم لمكونات بناء على خلفيتك المهنية إلى عدة طرق من حيث: +قد تختلف طريقة التفكير في تقسيم التصميم لمكونات بناء على خلفيتك المهنية إلى عدة طرق؛ من حيث: * **البرمجة**--استخدم نفس الطرائق لتقرر إذا ما كان عليك إنشاء دالة (function) أو كائن. إحدى الطرائق المقصودة هي [مبدأ المهمة الواحدة](https://ar.wikipedia.org/wiki/%D9%85%D8%A8%D8%AF%D8%A3_%D8%A7%D9%84%D9%85%D9%87%D9%85%D8%A9_%D8%A7%D9%84%D9%88%D8%A7%D8%AD%D8%AF%D8%A9)، والتي تشير إلى أنه في أحسن الأحوال، يكون للمكون الواحد وظيفة واحدة فقط. وكلما زادت مهمات المكون، يجب تقسيمها لمكونات فرعية أصغر. * **التنسيق (CSS)**--فكر فيما ستقوم بتخصيص أسماء تصنيفات (classes) له. (مع أن المكونات أصلا يفترض أنها صغيرة الحجم). * **التصميم**--فكر كيف ستقوم بترتيب تراص طبقات التصميم. -إذا كان الـJSON الذي تستخدمه مهيأ بشكل جيد، فكثيرا ما ستجده يطابق وصفك وتقسيمك لمكونات واجهنك بكل سلاسة. ذلك أن واجهة المستخدم ونماذج البيانات عادة ما يكون لهما نفس بنية المعلومات. بمعنى آخر، لهما نفس الشكل. فقسم واجهتك إلى مكونات، حيث يتماشى كل مكون مع إحدى +إذا كان الـJSON الذي تستخدمه مهيأ بشكل جيد، فكثيرا ما ستجده يطابق وصفك وتقسيمك لمكونات واجهتك بكل سلاسة. ذلك أن واجهة المستخدم ونماذج البيانات عادة ما يكون لهما نفس بنية المعلومات. بمعنى آخر، لهما نفس الشكل. فقسم واجهتك إلى مكونات، حيث يتماشى كل مكون مع إحدى أجزاء نموذج البيانات. يوجد في هذه الصورة خمس مكونات: @@ -53,7 +53,7 @@ title: على طريقة React 1. `FilterableProductTable` (باللون الرمادي - جدول منتجات قابل للبحث) يحوي البرنامج بالكامل. 2. `SearchBar` (بالأزرق - مربع بحث) حيث يكتب فيه المستخدم. -3. `ProductTable` (بالبنفسجي - جدول منتجات) يعرض المنتجات ونتائج البحث فيها بحسب مدخلات المستخدم. +3. `ProductTable` (بالبنفسجي - جدول المنتجات) يعرض المنتجات ونتائج البحث فيها بحسب مدخلات المستخدم. 4. `ProductCategoryRow` (بالأخضر - سطر خاص بنوع المنتج) يعرض عنوان لكل نوع من المنتجات. 5. `ProductRow` (بالأصفر - سطر المنتج) يعرض سطرا لكل منتج. @@ -61,9 +61,9 @@ title: على طريقة React -If you look at `ProductTable` (lavender), you'll see that the table header (containing the "Name" and "Price" labels) isn't its own component. This is a matter of preference, and you could go either way. For this example, it is a part of `ProductTable` because it appears inside the `ProductTable`'s list. However, if this header grows to be complex (e.g., if you add sorting), you can move it into its own `ProductTableHeader` component. +إذا ألقيت نظرة على جدول المنتجات (`ProductTable` - بالبنفسجي) ستجد أن رأس الجدول (الذي يحوي خانات "الاسم - Name" و"السعر - Price") ليس كائنا مستقلا بذاته. هذه مسألة تفضيل شخصي، حيث بإمكانك اتخاذ أي مسلك بين الاثنين. في هذا المثال هي جزء من مكون `جدول المنتجات`، لإنه يظهر داخل قائمة `جدول المنتجات`. على كل حال،إذا زادت مهام رأس الجدول تعقيدا (كأن تضيف لها خيار الترتيب) يمكنك حينها أن تنشء له مكونا خاصا به، وليكن `ProductTableHeader` (`رأس جدول المنتجات`). -Now that you've identified the components in the mockup, arrange them into a hierarchy. Components that appear within another component in the mockup should appear as a child in the hierarchy: +والآن بعد أن حددت مكونات النموذج التقريبي، قم بترتيبهم في شجرة تسلسلية؛ المكونات التي تظهر داخل مكونات أخرى في النموذج التقريبي يجب أن تبدو كفروع في الشجرة: * `FilterableProductTable` * `SearchBar` @@ -71,13 +71,13 @@ Now that you've identified the components in the mockup, arrange them into a hie * `ProductCategoryRow` * `ProductRow` -## Step 2: Build a static version in React {/*step-2-build-a-static-version-in-react*/} +## الخطوة 2: قم ببناء نموذج مصمت بـ React {/*step-2-build-a-static-version-in-react*/} -Now that you have your component hierarchy, it's time to implement your app. The most straightforward approach is to build a version that renders the UI from your data model without adding any interactivity... yet! It's often easier to build the static version first and add interactivity later. Building a static version requires a lot of typing and no thinking, but adding interactivity requires a lot of thinking and not a lot of typing. +والآن بما أن لديك تقسيما متسلسلا للمكونات، حان الوقت لنبدأ التنفيذ. أكثر الطرق مباشرة؛ أن تبني نموذجا يعرض واجهة المستخدم من نموذج بياناتك، دون إضافة أي تفاعل... هذا بغض النظر أنه من الأيسر غالبا أن تبني النموذج المصمت أولا ثم تقوم لاحقا بإضافة إمكانية التفاعل عليه! بناء نموذج مصمت يتطلب الكثير من الكتابة دونما أي تفكير. بخلاف إضافة التفاعليات، التي تتطلب الكثير من التفكير وقدرًا أقل من الكتابة. -To build a static version of your app that renders your data model, you'll want to build [components](/learn/your-first-component) that reuse other components and pass data using [props.](/learn/passing-props-to-a-component) Props are a way of passing data from parent to child. (If you're familiar with the concept of [state](/learn/state-a-components-memory), don't use state at all to build this static version. State is reserved only for interactivity, that is, data that changes over time. Since this is a static version of the app, you don't need it.) +لبناء نموذج مصمت من تطبيقك يقوم بعرض البيانات المطلوبة، سيكون عليك بناء [مكونات](/learn/your-first-component) توظف مكونات أخرى، وتمرر البيانات إليها باستخدام [الخصائص](/learn/passing-props-to-a-component). الخصائص هي إحدى طرق تمرير البيانات من مكون لمكون فرعي داخله (إذا كان مبدأ [الحالات](/learn/state-a-components-memory) مألوفا لديك، فلا تستخدم الحالات مطلقا لبناء النسخة المصمتة. الحالات مخصصة أصلا للتفاعلات، ونعني بذلك البيانات التي تتغير بمرور الوقت. وبما أن هذا نموذج مصمت من التطبيق، فلا يفترض أننا نحتاجه). -You can either build "top down" by starting with building the components higher up in the hierarchy (like `FilterableProductTable`) or "bottom up" by working from components lower down (like `ProductRow`). In simpler examples, it’s usually easier to go top-down, and on larger projects, it’s easier to go bottom-up. +يمكنك إما بناء التطبيق "من أعلاه لأسفله"؛ بالبدء ببناء المكونات الأعلى في الشجرة التسلسلية (كأن تبدأ بـ`FilterableProductTable`)، أو "من أسفله لأعلاه"؛ بأن تبدأ بالمكونات الدنيا (مثل `ProductRow`). إذا كان لدينا مثال أبسط من ذلك، سيكون من الأيسرأن تبدأ من الأعلى لأسفل، أما في المشاريع الكبرى، عادة ما يكون من الأيسر أن نبدأ من الأدنى للأعلى. @@ -195,13 +195,13 @@ td { -(If this code looks intimidating, go through the [Quick Start](/learn/) first!) +(إذا شعرت بالقلق بسبب الكود السابق, قم بمراجعة قسم [البداية السريعة](/learn/) أولا!) -After building your components, you'll have a library of reusable components that render your data model. Because this is a static app, the components will only return JSX. The component at the top of the hierarchy (`FilterableProductTable`) will take your data model as a prop. This is called _one-way data flow_ because the data flows down from the top-level component to the ones at the bottom of the tree. +بعد بنائك لمكوناتك، أصبح لديك مكتبة من المكونات القابلة لإعادة الاستخدام التي تقوم بعرض أنموذج بياناتك. وبما أن هذا تطبيق مصمت، فمخرجات المكونات ستكون مجرد JSX. المكون الأعلى في التسلسل الشجري (`FilterableProductTable`) سيتلقى أنموذج البيانات كإحدى خصائصه. يدعى هذا بـ _سيل البيانات في اتجاه واحد_ لأن البيانات تسري لأسفل قادمة من مكون أعلى في التسلسل الشجري إلى مكونات دنيا في التسلسل. -At this point, you should not be using any state values. That’s for the next step! +إلى هذه المرحلة يجب ألا تكون قد استخدمت الحالات على الإطلاق. لأن هذا ما سنفعله في الخطوة التالية! From 14b808edc87b17eb2a333461da68b56dcd589077 Mon Sep 17 00:00:00 2001 From: Hosam Date: Fri, 28 Apr 2023 23:10:59 +0300 Subject: [PATCH 04/11] some typo and lingual corrections --- src/content/learn/thinking-in-react.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/content/learn/thinking-in-react.md b/src/content/learn/thinking-in-react.md index 41f07cd73..88cb1079b 100644 --- a/src/content/learn/thinking-in-react.md +++ b/src/content/learn/thinking-in-react.md @@ -61,9 +61,9 @@ title: على طريقة React -إذا ألقيت نظرة على جدول المنتجات (`ProductTable` - بالبنفسجي) ستجد أن رأس الجدول (الذي يحوي خانات "الاسم - Name" و"السعر - Price") ليس كائنا مستقلا بذاته. هذه مسألة تفضيل شخصي، حيث بإمكانك اتخاذ أي مسلك بين الاثنين. في هذا المثال هي جزء من مكون `جدول المنتجات`، لإنه يظهر داخل قائمة `جدول المنتجات`. على كل حال،إذا زادت مهام رأس الجدول تعقيدا (كأن تضيف لها خيار الترتيب) يمكنك حينها أن تنشء له مكونا خاصا به، وليكن `ProductTableHeader` (`رأس جدول المنتجات`). +إذا ألقيت نظرة على جدول المنتجات (`ProductTable` - بالبنفسجي) ستجد أن رأس الجدول (الذي يحوي خانات "الاسم - Name" و"السعر - Price") ليس كائنا مستقلا بذاته. هذه مسألة تفضيل شخصي، حيث بإمكانك اتخاذ أي مسلك بين الاثنين. في هذا المثال هي جزء من مكون `جدول المنتجات`، لإنه يظهر داخل قائمة `جدول المنتجات`. على كل حال، إذا زادت مهام رأس الجدول تعقيدا (كأن تضيف لها خيار الترتيب) يمكنك حينها أن تنشئ له مكونا خاصا به، وليكن `ProductTableHeader` (`رأس جدول المنتجات`). -والآن بعد أن حددت مكونات النموذج التقريبي، قم بترتيبهم في شجرة تسلسلية؛ المكونات التي تظهر داخل مكونات أخرى في النموذج التقريبي يجب أن تبدو كفروع في الشجرة: +والآن بعد أن حددت مكونات النموذج التقريبي، قم بترتيبهم في شجرة تسلسلية؛ بحيث أن المكونات التي تظهر داخل مكونات أخرى في النموذج التقريبي يجب أن تبدو كفروع في الشجرة: * `FilterableProductTable` * `SearchBar` @@ -73,11 +73,11 @@ title: على طريقة React ## الخطوة 2: قم ببناء نموذج مصمت بـ React {/*step-2-build-a-static-version-in-react*/} -والآن بما أن لديك تقسيما متسلسلا للمكونات، حان الوقت لنبدأ التنفيذ. أكثر الطرق مباشرة؛ أن تبني نموذجا يعرض واجهة المستخدم من نموذج بياناتك، دون إضافة أي تفاعل... هذا بغض النظر أنه من الأيسر غالبا أن تبني النموذج المصمت أولا ثم تقوم لاحقا بإضافة إمكانية التفاعل عليه! بناء نموذج مصمت يتطلب الكثير من الكتابة دونما أي تفكير. بخلاف إضافة التفاعليات، التي تتطلب الكثير من التفكير وقدرًا أقل من الكتابة. +والآن بما أن لديك تقسيما متسلسلا للمكونات، حان الوقت لنبدأ التنفيذ. أكثر الطرق مباشرة؛ أن تبني نموذجا يعرض واجهة المستخدم من نموذج بياناتك، دون إضافة أي تفاعل... هذا بغض النظر عن أنه من الأيسر غالبا أن تبني النموذج المصمت أولا ثم تقوم لاحقا بإضافة إمكانية التفاعل عليه! بناء نموذج مصمت يتطلب الكثير من الكتابة دون أن تستلزم أي تفكير. بخلاف إضافة التفاعليات، التي تتطلب الكثير من التفكير وقدرًا أقل من الكتابة. لبناء نموذج مصمت من تطبيقك يقوم بعرض البيانات المطلوبة، سيكون عليك بناء [مكونات](/learn/your-first-component) توظف مكونات أخرى، وتمرر البيانات إليها باستخدام [الخصائص](/learn/passing-props-to-a-component). الخصائص هي إحدى طرق تمرير البيانات من مكون لمكون فرعي داخله (إذا كان مبدأ [الحالات](/learn/state-a-components-memory) مألوفا لديك، فلا تستخدم الحالات مطلقا لبناء النسخة المصمتة. الحالات مخصصة أصلا للتفاعلات، ونعني بذلك البيانات التي تتغير بمرور الوقت. وبما أن هذا نموذج مصمت من التطبيق، فلا يفترض أننا نحتاجه). -يمكنك إما بناء التطبيق "من أعلاه لأسفله"؛ بالبدء ببناء المكونات الأعلى في الشجرة التسلسلية (كأن تبدأ بـ`FilterableProductTable`)، أو "من أسفله لأعلاه"؛ بأن تبدأ بالمكونات الدنيا (مثل `ProductRow`). إذا كان لدينا مثال أبسط من ذلك، سيكون من الأيسرأن تبدأ من الأعلى لأسفل، أما في المشاريع الكبرى، عادة ما يكون من الأيسر أن نبدأ من الأدنى للأعلى. +يمكنك إما بناء التطبيق "من أعلاه لأسفله"؛ بالبدء ببناء المكونات الأعلى في الشجرة التسلسلية (كأن تبدأ بـ`FilterableProductTable`)، أو "من أسفله لأعلاه"؛ بأن تبدأ بالمكونات الدنيا (مثل `ProductRow`). إذا كان لدينا مثال أبسط من هذا، سيكون من الأيسرأن تبدأ من الأعلى لأسفل، أما في المشاريع الكبرى، عادة ما يكون من الأيسر أن نبدأ من الأدنى للأعلى. From a2e2b837f24a957c67d86243e95920d00f82f504 Mon Sep 17 00:00:00 2001 From: Hosam Date: Sat, 29 Apr 2023 03:51:51 +0300 Subject: [PATCH 05/11] finished till Step4 --- src/content/learn/thinking-in-react.md | 46 ++++++++++++++------------ 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/src/content/learn/thinking-in-react.md b/src/content/learn/thinking-in-react.md index 88cb1079b..e5bd73d26 100644 --- a/src/content/learn/thinking-in-react.md +++ b/src/content/learn/thinking-in-react.md @@ -205,46 +205,48 @@ td { -## Step 3: Find the minimal but complete representation of UI state {/*step-3-find-the-minimal-but-complete-representation-of-ui-state*/} +## الخطوة 3: حدد أبسط وأكمل تمثيل لحالات واجهة المستخدم {/*step-3-find-the-minimal-but-complete-representation-of-ui-state*/} -To make the UI interactive, you need to let users change your underlying data model. You will use *state* for this. +لجعل الواجهة تفاعلية؛ يجب أن تسمح للمستخدم بتعديل أنموذج بياناتك. لإنجاز ذلك، سيتعين عليك توظيف *الحالات*. -Think of state as the minimal set of changing data that your app needs to remember. The most important principle for structuring state is to keep it [DRY (Don't Repeat Yourself).](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) Figure out the absolute minimal representation of the state your application needs and compute everything else on-demand. For example, if you're building a shopping list, you can store the items as an array in state. If you want to also display the number of items in the list, don't store the number of items as another state value--instead, read the length of your array. +اعتبر الحالات كما لو أنها عدّتك من البيانات المتغيرة التي يجب أن يتذكرها تطبيقك. أهم مبدأ يجب أخذه في الاعتبار عند تحديد حالاتك هي أن تكون [فريدة](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). حاول استنباط القدر الأدنى لتمثيل حالات تطبيقك المختلفة التي سيحتاجها، وقم باحتساب أي حالة أخرى تزيد على ذلك عند الحاجة. مثلا، إذا كنت تقوم ببناء قائمة مشتريات، يمكنك حفظ الأصناف كمصفوفة في حالة التطبيق. أما إذا احتجت لعرض عدد الأصناف في القائمة، فلا تقم بحفظ عدد الأصناف كحالة أخرى. عوضا عن ذلك؛ يمكنك دائما قراءة طول المصفوفة. -Now think of all of the pieces of data in this example application: +الآن فكر في كل ما قد تحتاجه من بيانات في تطبيقنا المفترض: -1. The original list of products -2. The search text the user has entered -3. The value of the checkbox -4. The filtered list of products +1. القائمة الأصلية للمنتجات. +2. كلمات البحث التي قام المستخدم بكتابتها. +3. حالة مربع الاختيار (الخاص بإظهار المنتجات التي لها رصيد فقط). +4. قائمة المنتجات بعد التصفية بكلمات البحث. -Which of these are state? Identify the ones that are not: +أيا مما سبق يعتبر حالة؟ يمكنك تمييزها بأنها لا تنطبق عليها المواصفات التالية: -* Does it **remain unchanged** over time? If so, it isn't state. -* Is it **passed in from a parent** via props? If so, it isn't state. -* **Can you compute it** based on existing state or props in your component? If so, it *definitely* isn't state! +* هل تبقى دائما **ثابتة** لا تتغير؟ إذا ليست حالة.. +* هل **تم تمريرها من المكون الأب** عن طريق الخصائص؟ إذا ليست حالة. +* **هل يمكن اشتقاقها** من حالة أخرى أو إحدى خصاص المكون؟ إذا ليست حالة! -What's left is probably state. +كل ما تبقى فهو غالبا يمكن وصفه بأنه حالة. -Let's go through them one by one again: +لنقم بمراجعتهم واحد تلو الآخر مرة أخرى: -1. The original list of products is **passed in as props, so it's not state.** -2. The search text seems to be state since it changes over time and can't be computed from anything. -3. The value of the checkbox seems to be state since it changes over time and can't be computed from anything. -4. The filtered list of products **isn't state because it can be computed** by taking the original list of products and filtering it according to the search text and value of the checkbox. +1. القائمة الأصلية للمنتجات **يتم تمريرها ضمن الخصائص،فهي ليست حالة.** +2. كلمات البحث تبدو كحالة بما أنها تتغير مع مرور الوقت ولا يمكن اشتقاقها من أي شيء آخر. +3. حالة مربع الاختيار تبدو كحالة بما أنها تتغير مع مرور الوقت ولا يمكن اشتقاقها من أي شيء آخر. +4. قائمة المنتجات بعد التصفية **ليست حالة إذ يمكن اشتقاقها** عبر تصفية قائمة المنتجات الأصلية وفقا لكلمات البحث وحالة مربع الاختيار. This means only the search text and the value of the checkbox are state! Nicely done! +هذا يعني أن كلمات البحث وحالة مربع الاختيار فقط هما ما يعتبران حالات محتملة للتطبيق! أحسنت عملا! -#### Props vs State {/*props-vs-state*/} +#### الخصائص والحالات {/*props-vs-state*/} There are two types of "model" data in React: props and state. The two are very different: +يعتبر كل منهما من أحد أنواع البيانات "النموذجية" في React: الخصائص والحالة. يختلف كلاهما عن الآخر بفارق كبير: -* [**Props** are like arguments you pass](/learn/passing-props-to-a-component) to a function. They let a parent component pass data to a child component and customize its appearance. For example, a `Form` can pass a `color` prop to a `Button`. -* [**State** is like a component’s memory.](/learn/state-a-components-memory) It lets a component keep track of some information and change it in response to interactions. For example, a `Button` might keep track of `isHovered` state. +* [**الخصائص (Props)** تشبه المعطيات](/learn/passing-props-to-a-component) التي تقوم بتمريرها لإحدى الدوال. تتيح لمكون أعلى أن تمرر بيانات لمكون تابع له وتنسيق مظهره أيضا. فمثلا، مكون `Form` يمكن أن يمرر خاصية `color` إلى `Button` لتغيير لونه. +* [**الحالة (State)** تشبه ذاكرة المكون.](/learn/state-a-components-memory) تتيح للمكون إمكانية أن يحاقظ على اطلاعه على بعض البيانات وأن يغيرها تجاوبا مع تفاعل المستخدم. فمثلا, يمكن للزر `Button` أن يبقى على اطلاع لحالة `isHovered`. -Props and state are different, but they work together. A parent component will often keep some information in state (so that it can change it), and *pass it down* to child components as their props. It's okay if the difference still feels fuzzy on the first read. It takes a bit of practice for it to really stick! +الخصائص والحالات أمران مختلفان، لكن يكملان بعضهما. قد يحتوي مكون ما على بعض البيانات في حالات (كي يتمكن من تغييرها) و *يمررها* لمكون تابع كخصائص لها. لا بأس إن كنت تشعر أن الفارق بينهما لا يزال غامضا. قد يستلزم الأمر بعض الممارسة لتتمكن من الإلمام به! From a66be9b19f3142857a435ec04bac9212931e89c2 Mon Sep 17 00:00:00 2001 From: Hosam Date: Sat, 29 Apr 2023 03:57:31 +0300 Subject: [PATCH 06/11] deleted the translated text --- src/content/learn/thinking-in-react.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/content/learn/thinking-in-react.md b/src/content/learn/thinking-in-react.md index e5bd73d26..adc297dfe 100644 --- a/src/content/learn/thinking-in-react.md +++ b/src/content/learn/thinking-in-react.md @@ -233,14 +233,12 @@ td { 3. حالة مربع الاختيار تبدو كحالة بما أنها تتغير مع مرور الوقت ولا يمكن اشتقاقها من أي شيء آخر. 4. قائمة المنتجات بعد التصفية **ليست حالة إذ يمكن اشتقاقها** عبر تصفية قائمة المنتجات الأصلية وفقا لكلمات البحث وحالة مربع الاختيار. -This means only the search text and the value of the checkbox are state! Nicely done! هذا يعني أن كلمات البحث وحالة مربع الاختيار فقط هما ما يعتبران حالات محتملة للتطبيق! أحسنت عملا! #### الخصائص والحالات {/*props-vs-state*/} -There are two types of "model" data in React: props and state. The two are very different: يعتبر كل منهما من أحد أنواع البيانات "النموذجية" في React: الخصائص والحالة. يختلف كلاهما عن الآخر بفارق كبير: * [**الخصائص (Props)** تشبه المعطيات](/learn/passing-props-to-a-component) التي تقوم بتمريرها لإحدى الدوال. تتيح لمكون أعلى أن تمرر بيانات لمكون تابع له وتنسيق مظهره أيضا. فمثلا، مكون `Form` يمكن أن يمرر خاصية `color` إلى `Button` لتغيير لونه. From eccade005ad080577cacd1d0142bfc21a7846b21 Mon Sep 17 00:00:00 2001 From: Hosam Date: Sat, 29 Apr 2023 04:46:23 +0300 Subject: [PATCH 07/11] finished through Step4 --- src/content/learn/thinking-in-react.md | 44 ++++++++++++++------------ 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/src/content/learn/thinking-in-react.md b/src/content/learn/thinking-in-react.md index adc297dfe..c03bfa26b 100644 --- a/src/content/learn/thinking-in-react.md +++ b/src/content/learn/thinking-in-react.md @@ -248,32 +248,33 @@ td { -## Step 4: Identify where your state should live {/*step-4-identify-where-your-state-should-live*/} +## الخطوة 4: حدد أين تضع الحالات {/*step-4-identify-where-your-state-should-live*/} -After identifying your app’s minimal state data, you need to identify which component is responsible for changing this state, or *owns* the state. Remember: React uses one-way data flow, passing data down the component hierarchy from parent to child component. It may not be immediately clear which component should own what state. This can be challenging if you’re new to this concept, but you can figure it out by following these steps! +بعد أن حدد القدر الأدنى من بيانات الحالات اللازمة، عليك الأن أن تحدد أي المكونات مسءول عن تغيير كلٌّ من هذه الحالات، أو *يملك* تلك الحالة. تذكر أن React يستخدم سيل البيانات في اتجاه واحد، وهو تمرير البيانات من المكون الأب لمكون تابع له في التسلسل الشجري. قد لا يبدو واضحا من الوهلة الأولى أي مكون يجب أن يملك تلك "الحالة" ويكون مسؤولا عنها. ربما يكون هذا تحديا لك إن كان هذا المفهوم جديدا عليك،لكن ستتمكن من إيجاد الإجابة باتباع الخطوات التالية! -For each piece of state in your application: +لكل حالة على حدة في تطبيقك: -1. Identify *every* component that renders something based on that state. -2. Find their closest common parent component--a component above them all in the hierarchy. -3. Decide where the state should live: - 1. Often, you can put the state directly into their common parent. - 2. You can also put the state into some component above their common parent. - 3. If you can't find a component where it makes sense to own the state, create a new component solely for holding the state and add it somewhere in the hierarchy above the common parent component. +1. حدد *جميع* المكونات التي تعرض أي شيء له علاقة بهذه الحالة. +2. حدد السلف الأقرب المشترك بينهم؛ مكون يكون أعلى منهم جميعا في التسلسل الشجري. +3. حدد أين يجب أن تتمركز الحالة: + 1. عادة، يمكنك وضع الحالة مباشرة في سلفهم المشترك. + 2. يمكنك أيضا أن تضع الحالة في مكون أعلى من السلف المشترك. + 3. إن لم يكن بإمكانك تحديد مكون حيث يبدو من المنطقي وضع الحالة فيه، قم بعمل مكون جديد خصيصا لحفظ تلك الحالة، وقم بوضعه في مكان ما في التسلسل الشجري يسبق سلفهم المشترك. -In the previous step, you found two pieces of state in this application: the search input text, and the value of the checkbox. In this example, they always appear together, so it makes sense to put them into the same place. +في الخطوة السابقة، وجدت حالتين في هذا التطبيق: نص البحث المكتوب، وحالة مربع الاختيار. في هذا المثال، يظهران دائما معا، فمن المنطقي وضعهم معا في نفس المكان. Now let's run through our strategy for them: +حسنا، لنقوم باختبار طريقتنا عليهم: -1. **Identify components that use state:** - * `ProductTable` needs to filter the product list based on that state (search text and checkbox value). - * `SearchBar` needs to display that state (search text and checkbox value). -1. **Find their common parent:** The first parent component both components share is `FilterableProductTable`. -2. **Decide where the state lives**: We'll keep the filter text and checked state values in `FilterableProductTable`. +1. **حدد المكونات التي تستخدم الحالة:** + * مكون (جدول المنتجات) `ProductTable` يحتاج الحالة ليقوم بتصفية قائمة المنتجات (نص البحث وحالة مربع الاختيار). + * مكون (خانة البحث) `SearchBar` يقوم بعرض الحالة نفسها (نص البحث). +1. **حدد لهم سلفا مشتركا:** السلف المشترك للمكونين هو `FilterableProductTable`. +2. **حدد أين تضع الحالة**: سنضع نص البحث وحالة مربع الاختيار في المكون `FilterableProductTable`. -So the state values will live in `FilterableProductTable`. +إذا، فقيم الحالات ستكون محفوظة لدى المكون `FilterableProductTable`. -Add state to the component with the [`useState()` Hook.](/reference/react/useState) Hooks are special functions that let you "hook into" React. Add two state variables at the top of `FilterableProductTable` and specify their initial state: +أضف الحالات للمكون باستخدام [خطاف `useState()`.](/reference/react/useState) الخطافات (Hooks) عبارة عن دوال خاصة تسمح لك أن "تربط" مكوناتك بنظام React. أضف متغيرا لكل حالة في بداية الكود الخاص بالمكون `FilterableProductTable` وحدد حالتهم الأولية: ```js function FilterableProductTable({ products }) { @@ -281,7 +282,7 @@ function FilterableProductTable({ products }) { const [inStockOnly, setInStockOnly] = useState(false); ``` -Then, pass `filterText` and `inStockOnly` to `ProductTable` and `SearchBar` as props: +ثم مرر المتغير `filterText` و `inStockOnly` للمكونين `ProductTable` و `SearchBar` كخاصية ضمن خصائص كلا منهما: ```js
@@ -296,6 +297,7 @@ Then, pass `filterText` and `inStockOnly` to `ProductTable` and `SearchBar` as p ``` 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: +قد يبدو واضحا لك من الآن كيف سيبدو سلوك تطبيقك. قم بتعديل قيمة `filterText` الأولية من `useState('')` إلى `useState('fruit')` في الكود التالي داخل الـsandbox المدرج. سترى نتيجة التعديل على كلا من محتوى خانة البحث وجدول المنتجات: @@ -437,7 +439,7 @@ td { -Notice that editing the form doesn't work yet. There is a console error in the sandbox above explaining why: +لاحظ أنك لو عدلت مباشرة على نموذج البحث فلن يحدث شيء. هناك رسالة خطأ في الـsandbox أعلاه تخبرك لماذا: @@ -445,7 +447,7 @@ You provided a \`value\` prop to a form field without an \`onChange\` handler. T -In the sandbox above, `ProductTable` and `SearchBar` read the `filterText` and `inStockOnly` props to render the table, the input, and the checkbox. For example, here is how `SearchBar` populates the input value: +في الـsandbox أعلاه؛ المكونان `ProductTable` و `SearchBar` يقرآن الخصائص `filterText` و `inStockOnly` لعرض الجدول، مربع البحث، ومربع الاختيار. إليك مثلا كيف يقوم المكون `SearchBar` بكتابة محتوى مربع البحث: ```js {1,6} function SearchBar({ filterText, inStockOnly }) { @@ -457,7 +459,7 @@ function SearchBar({ filterText, inStockOnly }) { placeholder="Search..."/> ``` -However, you haven't added any code to respond to the user actions like typing yet. This will be your final step. +برغم ذلك، فأنت لم تقم بعد بكتابة أي كود للتجاوب مع تفاعلات المستخدم (كالكتابة). هذه ستكون خطوتك الأخيرة. ## Step 5: Add inverse data flow {/*step-5-add-inverse-data-flow*/} From cdef411bbc73612200eb7e455f67d5342cefaf8a Mon Sep 17 00:00:00 2001 From: Hosam Date: Sat, 29 Apr 2023 05:23:07 +0300 Subject: [PATCH 08/11] ALL DONE! --- src/content/learn/thinking-in-react.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/content/learn/thinking-in-react.md b/src/content/learn/thinking-in-react.md index c03bfa26b..37eead48d 100644 --- a/src/content/learn/thinking-in-react.md +++ b/src/content/learn/thinking-in-react.md @@ -443,7 +443,7 @@ td { -You provided a \`value\` prop to a form field without an \`onChange\` handler. This will render a read-only field. +لقد قمت بتمرير \`قيمة\` إحدى الخصائص لإحدى خانات نموذج دون تحديد معالج لحدث تغير القيمة \`onChange\`. سينتج عن هذا خانة قابلة للقراءة فقط. @@ -462,13 +462,13 @@ function SearchBar({ filterText, inStockOnly }) { برغم ذلك، فأنت لم تقم بعد بكتابة أي كود للتجاوب مع تفاعلات المستخدم (كالكتابة). هذه ستكون خطوتك الأخيرة. -## Step 5: Add inverse data flow {/*step-5-add-inverse-data-flow*/} +## الخطوة 5: إضافة تدفق البيانات العكسي {/*step-5-add-inverse-data-flow*/} -Currently your app renders correctly with props and state flowing down the hierarchy. But to change the state according to user input, you will need to support data flowing the other way: the form components deep in the hierarchy need to update the state in `FilterableProductTable`. +يعمل تطبيقك الآن بشكل صحيح، حيث تنساب الخصائص والحالات خلال شجرة المكونات. لكن لتغير الحالة تبعا لمدخلات المستخدم، سيكون لزاما عليك أن تحسب حسابا لدفق البيانات من الاتجاه الآخر: مكونات النموذج في أسفل الشجرة، تريد تعديل الحالة المتمركزة في المكون `FilterableProductTable`. -React makes this data flow explicit, but it requires a little more typing than two-way data binding. If you try to type or check the box in the example above, you'll see that React ignores your input. This is intentional. By writing ``, you've set the `value` prop of the `input` to always be equal to the `filterText` state passed in from `FilterableProductTable`. Since `filterText` state is never set, the input never changes. +يجعل React هذا النوع من تدفق البيانات بسيطا واضحا، لكنه يسلتزم قدرا أكبر من الكتابة مقارنة بالربط المزدوج للبيانات (two-way data binding). إذا ما حاولت الكتابة في خانة البحث أو التحديد على مربع الاختيار، ستجد أن React يتجاهل محاولاتك. وهذا أمر مقصود. بكتابتك ``، فقد حددت خاصية القيمة (`value`) لخانة البحث `input` لأن تكون دوما مطابقة لقيمة الخاصية `filterText` الممررة من حالة المكون `FilterableProductTable`. وحيث أن الحالة `filterText` لم يسبق أن تم تعيينها، فالخانة لن تتغير أبدأ. -You want to make it so whenever the user changes the form inputs, the state updates to reflect those changes. The state is owned by `FilterableProductTable`, so only it can call `setFilterText` and `setInStockOnly`. To let `SearchBar` update the `FilterableProductTable`'s state, you need to pass these functions down to `SearchBar`: +عليك أن تجعل الأمر ليكون كلما قام المستخدم بتغيير مدخلات النموذج، يتم حينها تحديث الحالة لتعكس هذه التغييرات. المكون `FilterableProductTable` هو من يملك الحالة، فهو فقط من يمكنه استدعاء الدالتين `setFilterText` و `setInStockOnly`. للسماح للمكون `SearchBar` بأن يقوم بتحديث حالة المكون `FilterableProductTable`، سيكون عليك أيضا أن تمرر هذه الدوال للمكون `SearchBar`: ```js {2,3,10,11} function FilterableProductTable({ products }) { @@ -484,7 +484,7 @@ function FilterableProductTable({ products }) { onInStockOnlyChange={setInStockOnly} /> ``` -Inside the `SearchBar`, you will add the `onChange` event handlers and set the parent state from them: +داخل المكون `SearchBar`، ستضيف معالجات حدث التغير `onChange` وتعدل من حالة المكون الأب عبرهما: ```js {5} onFilterTextChange(e.target.value)} /> ``` -Now the application fully works! +الآن يمكننا القول أن تطبيقنا يعمل بشكل كامل! @@ -644,8 +644,8 @@ td { -You can learn all about handling events and updating state in the [Adding Interactivity](/learn/adding-interactivity) section. +يمكنك القراءة عن معالجة الأحداث وتعديل الحالات في قسم [إضافة التفاعلات](/learn/adding-interactivity). -## Where to go from here {/*where-to-go-from-here*/} +## ماذا بعد؟ {/*where-to-go-from-here*/} -This was a very brief introduction to how to think about building components and applications with React. You can [start a React project](/learn/installation) right now or [dive deeper on all the syntax](/learn/describing-the-ui) used in this tutorial. +كانت هذه مقدمة مختصرة جدا لكيف يمكنك أن تفكر في بناء المكونات والتطبيقات باستخدام React. يمكنك [البدء في كتابة مشروع بـ React](/learn/installation) فورا أو [أن تتعمق أكثر في الصيغ](/learn/describing-the-ui) المستخدمة في هذا الشرح. From ba35b862f440c2c36bc7f3c9253e7462ded27e54 Mon Sep 17 00:00:00 2001 From: Ahmed Abdelbaset Date: Fri, 2 Jun 2023 10:52:19 +0300 Subject: [PATCH 09/11] From L1 to L200 --- src/content/learn/thinking-in-react.md | 35 +++++++++++++------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/src/content/learn/thinking-in-react.md b/src/content/learn/thinking-in-react.md index 37eead48d..3a1dad9a1 100644 --- a/src/content/learn/thinking-in-react.md +++ b/src/content/learn/thinking-in-react.md @@ -1,18 +1,18 @@ --- -title: على طريقة React +title: التفكير على طريقة React --- -قد يغير React من الطريقة التي ترى بها التصاميم أو تبني بها التطبيقات. عندما تقوم ببناء واجهة للمستخدم بـ React سيتوجب عليك أولا أن تفصلها لأجزاء تدعى *مكونات*. بعد ذلك، تقوم بوصف الحالات الظاهرية المختلفة لكل مكون على حدته. وأخيرا، تقوم بربط مكوناتك معا كي تسري البيانات خلالها بانسيابية. في هذا الدرس، سنخوض معك في عملية التفكير في بناء جدول بيانات لمنتجات، مع إمكانية البحث فيه. +قد يغير React من الطريقة التي ترى بها التصاميم أو تبني بها التطبيقات. عندما تقوم ببناء واجهة للمستخدم بـ React سيتوجب عليك أولا أن تقسمها لأجزاء تدعى *مكونات*. بعد ذلك، تقوم بوصف الحالات الظاهرية المختلفة لكل مكون على حده. وأخيرا، تقوم بربط مكوناتك معا كي تسري البيانات خلالها بانسيابية. في هذا الدرس، سنخوض معك في طريقة التفكير في بناء جدول بيانات لمنتجات، مع إمكانية البحث فيه. ## ابدأ بالنموذج التقريبي {/*start-with-the-mockup*/} -لنفرض أن لديك واجهة برمجة لـ JSON ونموذج تقريبي من أحد المصممين. +لنفرض أن لديك واجهة برمجة API لـ JSON ونموذج تقريبي من أحد المصممين. -واجهة JSON البرمجية أعطتك البيانات التالية: +واجهة JSON البرمجية تعطتك البيانات التالية: ```json [ @@ -33,16 +33,15 @@ title: على طريقة React ## الخطوة 1: قسم الواجهة إلى شجرة من المكونات {/*step-1-break-the-ui-into-a-component-hierarchy*/} -ابدأ برسم مربعات حول كل من المكونات ومكوناتها الفرعية في النموذج التقريبي، وقم بتسمية كل منها. إذا كنت تعمل مع مصمم، فلربما تجده قد قام بتسميتها بالفعل في البرامج التي يستخدمها، اسأله أولا! +ابدأ برسم مربعات حول كلٍّ من المكونات ومكوناتها الفرعية في النموذج التقريبي، وقم بتسمية كل منها. إذا كنت تعمل مع مصمم، فلربما تجده قد قام بتسميتها بالفعل في البرامج التي يستخدمها، اسأله أولا! قد تختلف طريقة التفكير في تقسيم التصميم لمكونات بناء على خلفيتك المهنية إلى عدة طرق؛ من حيث: -* **البرمجة**--استخدم نفس الطرائق لتقرر إذا ما كان عليك إنشاء دالة (function) أو كائن. إحدى الطرائق المقصودة هي [مبدأ المهمة الواحدة](https://ar.wikipedia.org/wiki/%D9%85%D8%A8%D8%AF%D8%A3_%D8%A7%D9%84%D9%85%D9%87%D9%85%D8%A9_%D8%A7%D9%84%D9%88%D8%A7%D8%AD%D8%AF%D8%A9)، والتي تشير إلى أنه في أحسن الأحوال، يكون للمكون الواحد وظيفة واحدة فقط. وكلما زادت مهمات المكون، يجب تقسيمها لمكونات فرعية أصغر. +* **البرمجة**--استخدم نفس الأساليب لتقرر ما إذا كان عليك إنشاء دالة (function) أو كائن. أحد الأساليب هو [مبدأ المهمة الواحدة](https://ar.wikipedia.org/wiki/%D9%85%D8%A8%D8%AF%D8%A3_%D8%A7%D9%84%D9%85%D9%87%D9%85%D8%A9_%D8%A7%D9%84%D9%88%D8%A7%D8%AD%D8%AF%D8%A9)، والتي تشير إلى أنه في أحسن الأحوال، يكون للمكون الواحد وظيفة واحدة فقط. وكلما زادت مهمات المكون، يجب تقسيمها لمكونات فرعية أصغر. * **التنسيق (CSS)**--فكر فيما ستقوم بتخصيص أسماء تصنيفات (classes) له. (مع أن المكونات أصلا يفترض أنها صغيرة الحجم). -* **التصميم**--فكر كيف ستقوم بترتيب تراص طبقات التصميم. +* **التصميم**--فكر كيف ستقوم بتنظيم طبقات التصميم. -إذا كان الـJSON الذي تستخدمه مهيأ بشكل جيد، فكثيرا ما ستجده يطابق وصفك وتقسيمك لمكونات واجهتك بكل سلاسة. ذلك أن واجهة المستخدم ونماذج البيانات عادة ما يكون لهما نفس بنية المعلومات. بمعنى آخر، لهما نفس الشكل. فقسم واجهتك إلى مكونات، حيث يتماشى كل مكون مع إحدى -أجزاء نموذج البيانات. +إذا كان الـJSON الذي تستخدمه مهيأ بشكل جيد، فكثيرا ما ستجده يطابق وصفك وتقسيمك لمكونات واجهتك بكل سلاسة. ذلك أن واجهة المستخدم ونماذج البيانات عادة ما يكون لهما نفس بنية المعلومات. بمعنى آخر، لهما نفس الشكل. فقسم واجهتك إلى مكونات، حيث يتماشى كل مكون مع أحد أجزاء نموذج البيانات. يوجد في هذه الصورة خمس مكونات: @@ -61,7 +60,7 @@ title: على طريقة React -إذا ألقيت نظرة على جدول المنتجات (`ProductTable` - بالبنفسجي) ستجد أن رأس الجدول (الذي يحوي خانات "الاسم - Name" و"السعر - Price") ليس كائنا مستقلا بذاته. هذه مسألة تفضيل شخصي، حيث بإمكانك اتخاذ أي مسلك بين الاثنين. في هذا المثال هي جزء من مكون `جدول المنتجات`، لإنه يظهر داخل قائمة `جدول المنتجات`. على كل حال، إذا زادت مهام رأس الجدول تعقيدا (كأن تضيف لها خيار الترتيب) يمكنك حينها أن تنشئ له مكونا خاصا به، وليكن `ProductTableHeader` (`رأس جدول المنتجات`). +إذا ألقيت نظرة على جدول المنتجات (`ProductTable` - بالبنفسجي) ستجد أن رأس الجدول (الذي يحوي خانات "الاسم - Name" و"السعر - Price") ليس كائنا مستقلا بذاته. هذه مسألة تفضيل شخصي، حيث بإمكانك اتخاذ أي مسلك بين الاثنين. في هذا المثال هي جزء من مكون `ProductTable`، لأنه يظهر داخل قائمة `ProductTable`. على كل حال، إذا زادت مهام رأس الجدول تعقيدا (كأن تضيف لها خيار الترتيب) يمكنك حينها أن تنشئ له مكونا خاصًا به، وليكن `ProductTableHeader` (`رأس جدول المنتجات`). والآن بعد أن حددت مكونات النموذج التقريبي، قم بترتيبهم في شجرة تسلسلية؛ بحيث أن المكونات التي تظهر داخل مكونات أخرى في النموذج التقريبي يجب أن تبدو كفروع في الشجرة: @@ -71,13 +70,13 @@ title: على طريقة React * `ProductCategoryRow` * `ProductRow` -## الخطوة 2: قم ببناء نموذج مصمت بـ React {/*step-2-build-a-static-version-in-react*/} +## الخطوة 2: قم ببناء نموذج ثابت بـ React {/*step-2-build-a-static-version-in-react*/} -والآن بما أن لديك تقسيما متسلسلا للمكونات، حان الوقت لنبدأ التنفيذ. أكثر الطرق مباشرة؛ أن تبني نموذجا يعرض واجهة المستخدم من نموذج بياناتك، دون إضافة أي تفاعل... هذا بغض النظر عن أنه من الأيسر غالبا أن تبني النموذج المصمت أولا ثم تقوم لاحقا بإضافة إمكانية التفاعل عليه! بناء نموذج مصمت يتطلب الكثير من الكتابة دون أن تستلزم أي تفكير. بخلاف إضافة التفاعليات، التي تتطلب الكثير من التفكير وقدرًا أقل من الكتابة. +والآن بما أن لديك تقسيما متسلسلا للمكونات، حان الوقت لنبدأ التنفيذ. أكثر الطرق مباشرة؛ أن تبني نموذجا يعرض واجهة المستخدم من نموذج بياناتك، دون إضافة أي تفاعل... هذا بغض النظر عن أنه من الأيسر غالبا أن تبني النموذج الثابت أولا ثم تقوم لاحقا بإضافة إمكانية التفاعل عليه! بناء نموذج ثابت يتطلب الكثير من الكتابة دون أن تستلزم أي تفكير. بخلاف إضافة التفاعليات، التي تتطلب الكثير من التفكير وقدرًا أقل من الكتابة. -لبناء نموذج مصمت من تطبيقك يقوم بعرض البيانات المطلوبة، سيكون عليك بناء [مكونات](/learn/your-first-component) توظف مكونات أخرى، وتمرر البيانات إليها باستخدام [الخصائص](/learn/passing-props-to-a-component). الخصائص هي إحدى طرق تمرير البيانات من مكون لمكون فرعي داخله (إذا كان مبدأ [الحالات](/learn/state-a-components-memory) مألوفا لديك، فلا تستخدم الحالات مطلقا لبناء النسخة المصمتة. الحالات مخصصة أصلا للتفاعلات، ونعني بذلك البيانات التي تتغير بمرور الوقت. وبما أن هذا نموذج مصمت من التطبيق، فلا يفترض أننا نحتاجه). +لبناء نموذج ثابت من تطبيقك يعرض البيانات المطلوبة، سيكون عليك بناء [مكونات](/learn/your-first-component) تحتوي مكونات أخرى، وتمرر البيانات إليها باستخدام [الخصائص](/learn/passing-props-to-a-component). الخصائص هي إحدى طرق تمرير البيانات من مكون لمكون فرعي داخله (إذا كان مبدأ [الحالة (state)](/learn/state-a-components-memory) مألوفا لديك، فلا تستخدم الحالات مطلقا لبناء النسخة الثابتة. الحالات مخصصة أصلا للتفاعلات، ونعني بذلك البيانات التي تتغير بمرور الوقت. وبما أن هذا نموذج ثابت من التطبيق، فلا يفترض أننا نحتاجه). -يمكنك إما بناء التطبيق "من أعلاه لأسفله"؛ بالبدء ببناء المكونات الأعلى في الشجرة التسلسلية (كأن تبدأ بـ`FilterableProductTable`)، أو "من أسفله لأعلاه"؛ بأن تبدأ بالمكونات الدنيا (مثل `ProductRow`). إذا كان لدينا مثال أبسط من هذا، سيكون من الأيسرأن تبدأ من الأعلى لأسفل، أما في المشاريع الكبرى، عادة ما يكون من الأيسر أن نبدأ من الأدنى للأعلى. +يمكنك إما بناء التطبيق "من أعلاه لأسفله"؛ بالبدء ببناء المكونات الأعلى في الشجرة التسلسلية (كأن تبدأ بـ`FilterableProductTable`)، أو "من أسفله لأعلاه"؛ بأن تبدأ بالمكونات الدنيا (مثل `ProductRow`). في الأمثلة الأبسط، سيكون من الأيسر أن تبدأ من الأعلى لأسفل، أما في المشاريع الكبرى، عادة ما يكون من الأيسر أن نبدأ من الأدنى للأعلى. @@ -142,11 +141,11 @@ function ProductTable({ products }) { function SearchBar() { return (
- +
); @@ -195,9 +194,9 @@ td {
-(إذا شعرت بالقلق بسبب الكود السابق, قم بمراجعة قسم [البداية السريعة](/learn/) أولا!) +(إذا كان هذا الكود غريبا عليك، قم بمراجعة قسم [البداية السريعة](/learn/) أولا!) -بعد بنائك لمكوناتك، أصبح لديك مكتبة من المكونات القابلة لإعادة الاستخدام التي تقوم بعرض أنموذج بياناتك. وبما أن هذا تطبيق مصمت، فمخرجات المكونات ستكون مجرد JSX. المكون الأعلى في التسلسل الشجري (`FilterableProductTable`) سيتلقى أنموذج البيانات كإحدى خصائصه. يدعى هذا بـ _سيل البيانات في اتجاه واحد_ لأن البيانات تسري لأسفل قادمة من مكون أعلى في التسلسل الشجري إلى مكونات دنيا في التسلسل. +بعد بنائك لمكوناتك، أصبح لديك مكتبة من المكونات القابلة لإعادة الاستخدام التي تقوم بعرض نموذج بياناتك. وبما أن هذا تطبيق ثابت، فمخرجات المكونات ستكون مجرد JSX. المكون الأعلى في التسلسل الشجري (`FilterableProductTable`) سيتلقى نموذج البيانات كإحدى خصائصه. يدعى هذا بـ _سيل البيانات في اتجاه واحد_ لأن البيانات تسري لأسفل قادمة من مكون أعلى في التسلسل الشجري إلى مكونات دنيا في التسلسل. From 914e6696702dc5ee5decd624550c8fe7bafd7313 Mon Sep 17 00:00:00 2001 From: Ahmed Abdelbaset Date: Fri, 2 Jun 2023 11:17:31 +0300 Subject: [PATCH 10/11] From L201 to L450 --- src/content/learn/thinking-in-react.md | 51 +++++++++++++------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/src/content/learn/thinking-in-react.md b/src/content/learn/thinking-in-react.md index 3a1dad9a1..b2a4bb745 100644 --- a/src/content/learn/thinking-in-react.md +++ b/src/content/learn/thinking-in-react.md @@ -206,18 +206,18 @@ td { ## الخطوة 3: حدد أبسط وأكمل تمثيل لحالات واجهة المستخدم {/*step-3-find-the-minimal-but-complete-representation-of-ui-state*/} -لجعل الواجهة تفاعلية؛ يجب أن تسمح للمستخدم بتعديل أنموذج بياناتك. لإنجاز ذلك، سيتعين عليك توظيف *الحالات*. +لجعل الواجهة تفاعلية؛ يجب أن تسمح للمستخدم بتعديل نموذج بياناتك. لإنجاز ذلك، سيتعين عليك استخدام *الحالات*. -اعتبر الحالات كما لو أنها عدّتك من البيانات المتغيرة التي يجب أن يتذكرها تطبيقك. أهم مبدأ يجب أخذه في الاعتبار عند تحديد حالاتك هي أن تكون [فريدة](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). حاول استنباط القدر الأدنى لتمثيل حالات تطبيقك المختلفة التي سيحتاجها، وقم باحتساب أي حالة أخرى تزيد على ذلك عند الحاجة. مثلا، إذا كنت تقوم ببناء قائمة مشتريات، يمكنك حفظ الأصناف كمصفوفة في حالة التطبيق. أما إذا احتجت لعرض عدد الأصناف في القائمة، فلا تقم بحفظ عدد الأصناف كحالة أخرى. عوضا عن ذلك؛ يمكنك دائما قراءة طول المصفوفة. +اعتبر الحالات كما لو أنها عدّتك من البيانات المتغيرة التي يجب أن يتذكرها تطبيقك. أهم مبدأ يجب أخذه في الاعتبار عند تحديد حالاتك هو [عدم التكرار 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`. -الآن فكر في كل ما قد تحتاجه من بيانات في تطبيقنا المفترض: +الآن فكر في كل ما قد تحتاجه من بيانات في تطبيقنا: 1. القائمة الأصلية للمنتجات. 2. كلمات البحث التي قام المستخدم بكتابتها. 3. حالة مربع الاختيار (الخاص بإظهار المنتجات التي لها رصيد فقط). 4. قائمة المنتجات بعد التصفية بكلمات البحث. -أيا مما سبق يعتبر حالة؟ يمكنك تمييزها بأنها لا تنطبق عليها المواصفات التالية: +أي مما سبق يعتبر حالة؟ يمكنك تمييزها بأنها لا تنطبق عليها المواصفات التالية: * هل تبقى دائما **ثابتة** لا تتغير؟ إذا ليست حالة.. * هل **تم تمريرها من المكون الأب** عن طريق الخصائص؟ إذا ليست حالة. @@ -227,7 +227,7 @@ td { لنقم بمراجعتهم واحد تلو الآخر مرة أخرى: -1. القائمة الأصلية للمنتجات **يتم تمريرها ضمن الخصائص،فهي ليست حالة.** +1. القائمة الأصلية للمنتجات **يتم تمريرها ضمن الخصائص، فهي ليست حالة.** 2. كلمات البحث تبدو كحالة بما أنها تتغير مع مرور الوقت ولا يمكن اشتقاقها من أي شيء آخر. 3. حالة مربع الاختيار تبدو كحالة بما أنها تتغير مع مرور الوقت ولا يمكن اشتقاقها من أي شيء آخر. 4. قائمة المنتجات بعد التصفية **ليست حالة إذ يمكن اشتقاقها** عبر تصفية قائمة المنتجات الأصلية وفقا لكلمات البحث وحالة مربع الاختيار. @@ -238,23 +238,23 @@ td { #### الخصائص والحالات {/*props-vs-state*/} -يعتبر كل منهما من أحد أنواع البيانات "النموذجية" في React: الخصائص والحالة. يختلف كلاهما عن الآخر بفارق كبير: +هناك نوعان من البيانات "الافتراضية" في React: الخصائص والحالة. يختلف كلاهما عن الآخر بفارق كبير: -* [**الخصائص (Props)** تشبه المعطيات](/learn/passing-props-to-a-component) التي تقوم بتمريرها لإحدى الدوال. تتيح لمكون أعلى أن تمرر بيانات لمكون تابع له وتنسيق مظهره أيضا. فمثلا، مكون `Form` يمكن أن يمرر خاصية `color` إلى `Button` لتغيير لونه. -* [**الحالة (State)** تشبه ذاكرة المكون.](/learn/state-a-components-memory) تتيح للمكون إمكانية أن يحاقظ على اطلاعه على بعض البيانات وأن يغيرها تجاوبا مع تفاعل المستخدم. فمثلا, يمكن للزر `Button` أن يبقى على اطلاع لحالة `isHovered`. +* [**الخصائص (Props)** تشبه المعطيات](/learn/passing-props-to-a-component) التي تقوم بتمريرها لإحدى الدوال. تتيح لمكون أعلى أن تمرر بيانات لمكون فرعي عنه وتنسيق مظهره أيضا. فمثلا، مكون `Form` يمكن أن يمرر خاصية `color` إلى `Button` لتغيير لونه. +* [**الحالة (State)** تشبه ذاكرة المكون.](/learn/state-a-components-memory) تتيح للمكون إمكانية أن يبقى مطلعًا على بعض البيانات وأن يغيرها تجاوبا مع تفاعل المستخدم. فمثلا, يمكن للزر `Button` أن يبقى على اطلاع لحالة `isHovered`. -الخصائص والحالات أمران مختلفان، لكن يكملان بعضهما. قد يحتوي مكون ما على بعض البيانات في حالات (كي يتمكن من تغييرها) و *يمررها* لمكون تابع كخصائص لها. لا بأس إن كنت تشعر أن الفارق بينهما لا يزال غامضا. قد يستلزم الأمر بعض الممارسة لتتمكن من الإلمام به! +الخصائص والحالات أمران مختلفان، لكن يكملان بعضهما. قد يحتوي مكون ما على بعض البيانات في حالات (كي يتمكن من تغييرها) و *يمررها* لمكون تابع كخصائص لها. لا بأس إن كنت تشعر أن الفارق بينهما لا يزال غامضا. قد يستلزم الأمر بعض الممارسة لتلمّ به! ## الخطوة 4: حدد أين تضع الحالات {/*step-4-identify-where-your-state-should-live*/} -بعد أن حدد القدر الأدنى من بيانات الحالات اللازمة، عليك الأن أن تحدد أي المكونات مسءول عن تغيير كلٌّ من هذه الحالات، أو *يملك* تلك الحالة. تذكر أن React يستخدم سيل البيانات في اتجاه واحد، وهو تمرير البيانات من المكون الأب لمكون تابع له في التسلسل الشجري. قد لا يبدو واضحا من الوهلة الأولى أي مكون يجب أن يملك تلك "الحالة" ويكون مسؤولا عنها. ربما يكون هذا تحديا لك إن كان هذا المفهوم جديدا عليك،لكن ستتمكن من إيجاد الإجابة باتباع الخطوات التالية! +بعد تحديد القدر الأدنى من بيانات الحالات اللازمة، عليك الآن أن تحدد أي المكونات مسئول عن تغيير كلٌّ من هذه الحالات، أو *يملك* تلك الحالة. تذكر أن React يستخدم سيل البيانات في اتجاه واحد، وهو تمرير البيانات من المكون الأب لمكون تابع له في التسلسل الشجري. قد لا يبدو واضحا من الوهلة الأولى أي مكون يجب أن يملك تلك "الحالة" ويكون مسؤولا عنها. ربما يكون هذا تحديا لك إن كان هذا المفهوم جديدا عليك، لكن ستتمكن من إيجاد الإجابة باتباع الخطوات التالية! لكل حالة على حدة في تطبيقك: 1. حدد *جميع* المكونات التي تعرض أي شيء له علاقة بهذه الحالة. -2. حدد السلف الأقرب المشترك بينهم؛ مكون يكون أعلى منهم جميعا في التسلسل الشجري. +2. حدد السلف المشترك الأقرب بينهم؛ مكون يكون أعلى منهم جميعا في التسلسل الشجري. 3. حدد أين يجب أن تتمركز الحالة: 1. عادة، يمكنك وضع الحالة مباشرة في سلفهم المشترك. 2. يمكنك أيضا أن تضع الحالة في مكون أعلى من السلف المشترك. @@ -262,12 +262,11 @@ td { في الخطوة السابقة، وجدت حالتين في هذا التطبيق: نص البحث المكتوب، وحالة مربع الاختيار. في هذا المثال، يظهران دائما معا، فمن المنطقي وضعهم معا في نفس المكان. -Now let's run through our strategy for them: -حسنا، لنقوم باختبار طريقتنا عليهم: +حسنا، لنختبر طريقتنا عليهم: 1. **حدد المكونات التي تستخدم الحالة:** - * مكون (جدول المنتجات) `ProductTable` يحتاج الحالة ليقوم بتصفية قائمة المنتجات (نص البحث وحالة مربع الاختيار). - * مكون (خانة البحث) `SearchBar` يقوم بعرض الحالة نفسها (نص البحث). + * مكون `ProductTable` (جدول المنتجات) يحتاج الحالة ليقوم بتصفية قائمة المنتجات (نص البحث وحالة مربع الاختيار). + * مكون `SearchBar` (خانة البحث) يقوم بعرض الحالة نفسها (نص البحث). 1. **حدد لهم سلفا مشتركا:** السلف المشترك للمكونين هو `FilterableProductTable`. 2. **حدد أين تضع الحالة**: سنضع نص البحث وحالة مربع الاختيار في المكون `FilterableProductTable`. @@ -281,7 +280,7 @@ function FilterableProductTable({ products }) { const [inStockOnly, setInStockOnly] = useState(false); ``` -ثم مرر المتغير `filterText` و `inStockOnly` للمكونين `ProductTable` و `SearchBar` كخاصية ضمن خصائص كلا منهما: +ثم مرر المتغير `filterText` و`inStockOnly` للمكونين `ProductTable` و`SearchBar` كخاصية ضمن خصائص كل منهما: ```js
@@ -291,12 +290,10 @@ function FilterableProductTable({ products }) { -
+ inStockOnly={inStockOnly} />
``` -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: -قد يبدو واضحا لك من الآن كيف سيبدو سلوك تطبيقك. قم بتعديل قيمة `filterText` الأولية من `useState('')` إلى `useState('fruit')` في الكود التالي داخل الـsandbox المدرج. سترى نتيجة التعديل على كلا من محتوى خانة البحث وجدول المنتجات: +قد يبدو واضحا لك من الآن كيف سيبدو سلوك تطبيقك. قم بتعديل قيمة `filterText` الأولية من `useState('')` إلى `useState('fruit')` في الكود التالي داخل الـsandbox المدرج. سترى نتيجة التعديل على كل من محتوى خانة البحث وجدول المنتجات: @@ -393,13 +390,13 @@ function SearchBar({ filterText, inStockOnly }) { + placeholder="بحث..."/> ); @@ -438,15 +435,17 @@ td { -لاحظ أنك لو عدلت مباشرة على نموذج البحث فلن يحدث شيء. هناك رسالة خطأ في الـsandbox أعلاه تخبرك لماذا: +لاحظ أنك لو عدّلت مباشرة على نموذج البحث فلن يحدث شيء. هناك رسالة خطأ في الـsandbox أعلاه تخبرك لماذا: + +You provided a \`value\` prop to a form field without an \`onChange\` handler. This will render a read-only field. لقد قمت بتمرير \`قيمة\` إحدى الخصائص لإحدى خانات نموذج دون تحديد معالج لحدث تغير القيمة \`onChange\`. سينتج عن هذا خانة قابلة للقراءة فقط. -في الـsandbox أعلاه؛ المكونان `ProductTable` و `SearchBar` يقرآن الخصائص `filterText` و `inStockOnly` لعرض الجدول، مربع البحث، ومربع الاختيار. إليك مثلا كيف يقوم المكون `SearchBar` بكتابة محتوى مربع البحث: +في الـsandbox أعلاه؛ المكونان `ProductTable` و`SearchBar` يقرآن الخصائص `filterText` و`inStockOnly` لعرض الجدول، ومربع البحث، ومربع الاختيار. إليك مثلا كيف يقوم المكون `SearchBar` بكتابة محتوى مربع البحث: ```js {1,6} function SearchBar({ filterText, inStockOnly }) { @@ -455,10 +454,10 @@ function SearchBar({ filterText, inStockOnly }) { + placeholder="بحث..."/> ``` -برغم ذلك، فأنت لم تقم بعد بكتابة أي كود للتجاوب مع تفاعلات المستخدم (كالكتابة). هذه ستكون خطوتك الأخيرة. +برغم ذلك، فأنت لم تكتب بعد أي كود للتجاوب مع تفاعلات المستخدم (كالكتابة). هذه ستكون خطوتك الأخيرة. ## الخطوة 5: إضافة تدفق البيانات العكسي {/*step-5-add-inverse-data-flow*/} From 9d8ab50812617997bee6659c50858f8c647bbc1c Mon Sep 17 00:00:00 2001 From: Ahmed Abdelbaset Date: Fri, 2 Jun 2023 11:26:13 +0300 Subject: [PATCH 11/11] From L450 to L650 --- src/content/learn/thinking-in-react.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/content/learn/thinking-in-react.md b/src/content/learn/thinking-in-react.md index b2a4bb745..465dee39d 100644 --- a/src/content/learn/thinking-in-react.md +++ b/src/content/learn/thinking-in-react.md @@ -457,16 +457,16 @@ function SearchBar({ filterText, inStockOnly }) { placeholder="بحث..."/> ``` -برغم ذلك، فأنت لم تكتب بعد أي كود للتجاوب مع تفاعلات المستخدم (كالكتابة). هذه ستكون خطوتك الأخيرة. +ومع ذلك، فأنت لم تكتب بعد أي كود للتجاوب مع تفاعلات المستخدم (كالكتابة). هذه ستكون خطوتك الأخيرة. -## الخطوة 5: إضافة تدفق البيانات العكسي {/*step-5-add-inverse-data-flow*/} +## الخطوة 5: إضافة تدفق البيانات العكسي {/*step-5-add-inverse-data-flow* -يعمل تطبيقك الآن بشكل صحيح، حيث تنساب الخصائص والحالات خلال شجرة المكونات. لكن لتغير الحالة تبعا لمدخلات المستخدم، سيكون لزاما عليك أن تحسب حسابا لدفق البيانات من الاتجاه الآخر: مكونات النموذج في أسفل الشجرة، تريد تعديل الحالة المتمركزة في المكون `FilterableProductTable`. +يعمل تطبيقك الآن بشكل صحيح، حيث تنساب الخصائص والحالات خلال شجرة المكونات. لكن لتغيير الحالة وفقًا لمدخلات المستخدم، سيكون لزامًا عليك أن تحسب حسابًا لدفق البيانات من الاتجاه الآخر: مكونات النموذج في أسفل الشجرة، تريد تعديل الحالة المتمركزة في المكون `FilterableProductTable`. -يجعل React هذا النوع من تدفق البيانات بسيطا واضحا، لكنه يسلتزم قدرا أكبر من الكتابة مقارنة بالربط المزدوج للبيانات (two-way data binding). إذا ما حاولت الكتابة في خانة البحث أو التحديد على مربع الاختيار، ستجد أن React يتجاهل محاولاتك. وهذا أمر مقصود. بكتابتك ``، فقد حددت خاصية القيمة (`value`) لخانة البحث `input` لأن تكون دوما مطابقة لقيمة الخاصية `filterText` الممررة من حالة المكون `FilterableProductTable`. وحيث أن الحالة `filterText` لم يسبق أن تم تعيينها، فالخانة لن تتغير أبدأ. +يجعل React هذا النوع من تدفق البيانات بسيطا واضحا، لكنه يسلتزم قدرا أكبر من الكتابة مقارنة بالربط المزدوج للبيانات (two-way data binding). إذا ما حاولت الكتابة في خانة البحث أو التحديد على مربع الاختيار، ستجد أن React يتجاهل محاولاتك. وهذا أمر مقصود. بكتابتك ``، فقد حددت خاصية القيمة (`value`) لخانة البحث `input` لأن تكون دوما مطابقة لقيمة الخاصية `filterText` الممررة من حالة المكون `FilterableProductTable`. وحيث أن الحالة `filterText` لم يتم تعديلها، فالخانة لن تتغير أبدأ. -عليك أن تجعل الأمر ليكون كلما قام المستخدم بتغيير مدخلات النموذج، يتم حينها تحديث الحالة لتعكس هذه التغييرات. المكون `FilterableProductTable` هو من يملك الحالة، فهو فقط من يمكنه استدعاء الدالتين `setFilterText` و `setInStockOnly`. للسماح للمكون `SearchBar` بأن يقوم بتحديث حالة المكون `FilterableProductTable`، سيكون عليك أيضا أن تمرر هذه الدوال للمكون `SearchBar`: +عليك أن تجعل الأمر ليكون كلما قام المستخدم بتغيير مدخلات النموذج، يتم حينها تحديث الحالة لتعكس هذه التغييرات. المكون `FilterableProductTable` هو من يملك الحالة، فهو فقط من يمكنه استدعاء الدالتين `setFilterText` و`setInStockOnly`. للسماح للمكون `SearchBar` بأن يقوم بتحديث حالة المكون `FilterableProductTable`، سيكون عليك أيضا أن تمرر هذه الدوال للمكون `SearchBar`: ```js {2,3,10,11} function FilterableProductTable({ products }) { @@ -488,7 +488,7 @@ function FilterableProductTable({ products }) { onFilterTextChange(e.target.value)} /> ``` @@ -595,7 +595,7 @@ function SearchBar({
onFilterTextChange(e.target.value)} />
); @@ -646,4 +646,4 @@ td { ## ماذا بعد؟ {/*where-to-go-from-here*/} -كانت هذه مقدمة مختصرة جدا لكيف يمكنك أن تفكر في بناء المكونات والتطبيقات باستخدام React. يمكنك [البدء في كتابة مشروع بـ React](/learn/installation) فورا أو [أن تتعمق أكثر في الصيغ](/learn/describing-the-ui) المستخدمة في هذا الشرح. +كانت هذه مقدمة مختصرة جدًا لكيفية التفكير في بناء المكونات والتطبيقات باستخدام React. يمكنك [البدء في كتابة مشروع بـ React](/learn/installation) فورا أو [أن تتعمق أكثر في الصيغ](/learn/describing-the-ui) المستخدمة في هذا الشرح.