From 04b8355d1065d4de477c5a0918eb025f79ccacae Mon Sep 17 00:00:00 2001 From: A7med3bdulBaset Date: Sat, 29 Apr 2023 15:20:48 +0300 Subject: [PATCH 01/34] Translate tutorial-tic-tac-toe into arabic part 1 from 1st line to 740th line --- src/content/learn/tutorial-tic-tac-toe.md | 187 +++++++++++----------- 1 file changed, 97 insertions(+), 90 deletions(-) diff --git a/src/content/learn/tutorial-tic-tac-toe.md b/src/content/learn/tutorial-tic-tac-toe.md index 28d997b04..3c7b84ec4 100644 --- a/src/content/learn/tutorial-tic-tac-toe.md +++ b/src/content/learn/tutorial-tic-tac-toe.md @@ -1,31 +1,31 @@ --- -title: 'Tutorial: Tic-Tac-Toe' +title: 'برنامج تعليمي: لعبة tic-tac-toe (X-O)' --- -You will build a small tic-tac-toe game during this tutorial. This tutorial does not assume any existing React knowledge. The techniques you'll learn in the tutorial are fundamental to building any React app, and fully understanding it will give you a deep understanding of React. +سنبني في هذا الدليل التطبيقي لعبة tic-tac-toe (X-O) صغيرة. لا يفترض هذا الدليل التطبيقي أي معرفة سابقة بـ React. التقنيات التي ستتعلمها في هذا البرنامج أساسية لبناء أي تطبيق React ، وفهمها بشكل كامل سيمنحك فهمًا عميقًا لـ React. -This tutorial is designed for people who prefer to **learn by doing** and want to quickly try making something tangible. If you prefer learning each concept step by step, start with [Describing the UI.](/learn/describing-the-ui) +هذا الدليل التطبيقي مصمم للأشخاص الذين يفضلون **التعلم العملي**، ويريدون تجربة صنع شيء ملموس بسرعة. إذا كنت تفضل تعلم كل مفهوم خطوة بخطوة ، فابدأ بـ [وصف واجهة المستخدم.](/learn/describing-the-ui) -The tutorial is divided into several sections: +هذا الدليل التطبيقي مقسم إلى عدة أقسام: -- [Setup for the tutorial](#setup-for-the-tutorial) will give you **a starting point** to follow the tutorial. -- [Overview](#overview) will teach you **the fundamentals** of React: components, props, and state. -- [Completing the game](#completing-the-game) will teach you **the most common techniques** in React development. -- [Adding time travel](#adding-time-travel) will give you **a deeper insight** into the unique strengths of React. +- [التجهيز للبرنامج التعليمي](#setup-for-the-tutorial): سيعطيك **نقطة انطلاق** لمتابعة الدليل التطبيقي. +- [نظرة عامة](#overview): سيعلمك **أساسيات React**؛ المكونات، الخصائص، والحالة. +- [إكمال اللعبة](#completing-the-game): سيعلمك **أكثر التقنيات شيوعًا** في تطوير React. +- [إضافة السفر عبر الزمن](#adding-time-travel): سيعطيك **فهمًا أعمق** لقوة React الفريدة. -### What are you building? {/*what-are-you-building*/} +### ماذا ستبني؟ {/*what-are-you-building*/} -In this tutorial, you'll build an interactive tic-tac-toe game with React. +في هذا الدليل التطبيقي، ستبني لعبة tic-tac-toe (X-O) تفاعلية باستخدام React. -You can see what it will look like when you're finished here: +يمكنك أن ترى كيف ستبدو عند الانتهاء من هنا: @@ -57,9 +57,9 @@ function Board({ xIsNext, squares, onPlay }) { const winner = calculateWinner(squares); let status; if (winner) { - status = 'Winner: ' + winner; + status = 'الفائز: ' + winner; } else { - status = 'Next player: ' + (xIsNext ? 'X' : 'O'); + status = 'اللاعب التالي: ' + (xIsNext ? 'X' : 'O'); } return ( @@ -103,9 +103,9 @@ export default function Game() { const moves = history.map((squares, move) => { let description; if (move > 0) { - description = 'Go to move #' + move; + description = 'الذهاب إلى الخطوة #' + move; } else { - description = 'Go to game start'; + description = 'اذهب إلى بداية اللعبة'; } return (
  • @@ -156,6 +156,7 @@ body { font-family: sans-serif; margin: 20px; padding: 0; + direction: rtl; } .square { @@ -194,15 +195,15 @@ body { -If the code doesn't make sense to you yet, or if you are unfamiliar with the code's syntax, don't worry! The goal of this tutorial is to help you understand React and its syntax. +إذا لم يكن الكود منطقيًا بالنسبة لك بعد ، أو إذا كنت غير معتاد على بناء الكود ، فلا تقلق! الهدف من هذا الدليل التطبيقي هو مساعدتك على فهم React وبناء الكود فيها. -We recommend that you check out the tic-tac-toe game above before continuing with the tutorial. One of the features that you'll notice is that there is a numbered list to the right of the game's board. This list gives you a history of all of the moves that have occurred in the game, and it is updated as the game progresses. +نوصيك بتجربة لعبة tic-tac-toe أعلاه قبل الاستمرار في الدليل التطبيقي. أحد الميزات التي ستلاحظها هي أن هناك قائمة مرقمة على يمين لوحة اللعبة. تعطيك هذه القائمة تاريخ جميع الحركات التي حدثت في اللعبة ، ويتم تحديثها مع تقدم اللعبة. -Once you've played around with the finished tic-tac-toe game, keep scrolling. You'll start with a simpler template in this tutorial. Our next step is to set you up so that you can start building the game. +بمجرد أن تنهى لعبة tic-tac-toe، استمر في التمرير. ستبدأ بقالب أبسط في هذا الدليل التطبيقي. خطوتنا التالية هي إعدادك حتى تتمكن من بدء بناء اللعبة. -## Setup for the tutorial {/*setup-for-the-tutorial*/} +## التجهيز للبرنامج التعليمي {/*setup-for-the-tutorial*/} -In the live code editor below, click **Fork** in the top-right corner to open the editor in a new tab using the website CodeSandbox. CodeSandbox lets you write code in your browser and preview how your users will see the app you've created. The new tab should display an empty square and the starter code for this tutorial. +في محرر الكود المباشر أدناه ، انقر فوق **Fork** في الزاوية اليمنى العليا لفتح المحرر في علامة تبويب جديدة باستخدام موقع CodeSandbox. يتيح لك CodeSandbox كتابة الكود في المتصفح ومعاينة كيف سيرى مستخدموك التطبيق الذي قمت بإنشائه. يجب أن تعرض علامة التبويب الجديدة مربعًا فارغًا ورمز البداية لهذا الدليل التطبيقي. @@ -261,33 +262,33 @@ body { -You can also follow this tutorial using your local development environment. To do this, you need to: +يمكنك أيضًا متابعة هذا الدليل التطبيقي باستخدام بيئة التطوير المحلية. للقيام بذلك ، تحتاج إلى: -1. Install [Node.js](https://nodejs.org/en/) -1. In the CodeSandbox tab you opened earlier, press the top-left corner button to open the menu, and then choose **File > Export to ZIP** in that menu to download an archive of the files locally -1. Unzip the archive, then open a terminal and `cd` to the directory you unzipped -1. Install the dependencies with `npm install` -1. Run `npm start` to start a local server and follow the prompts to view the code running in a browser +1. تثبيت [Node.js](https://nodejs.org/ar/). +1. في نافذة CodeSandbox التي فتحتها مؤخرًا، اضغط على زر الزاوية اليسرى العليا لفتح القائمة، ثم اختر **File** > **Export to ZIP** في تلك القائمة لتنزيل أرشيف الملفات محليًا. +1. فك ضغط الأرشيف، ثم افتح موجه الأوامر واكتب `cd` للانتقال إلى الدليل الذي فككت ضغطه. +1. قم بتثبيت الاعتمادات باستخدام `npm install`. +1. قم بتشغيل `npm start` لبدء خادم محلي واتبع التعليمات لعرض الكود عاملًا في المتصفح. -If you get stuck, don't let this stop you! Follow along online instead and try a local setup again later. +إذا واجهتك مشكلة، لا تدع هذا يوقفك! تابع الدليل التطبيقي عبر الإنترنت بدلاً من ذلك وحاول إعداد محلي مرة أخرى لاحقًا. -## Overview {/*overview*/} +## نظرة عامة {/*overview*/} -Now that you're set up, let's get an overview of React! +الآن أنت مستعد للبدء، دعنا نلقي نظرة عامة على React! -### Inspecting the starter code {/*inspecting-the-starter-code*/} +### فحص الكود المبدئي {/*examining-the-starter-code*/} -In CodeSandbox you'll see three main sections: +في CodeSandbox سترى ثلاثة أقسام رئيسية: -![CodeSandbox with starter code](../images/tutorial/react-starter-code-codesandbox.png) +![CodeSandbox مع الكود المبدئي](../images/tutorial/react-starter-code-codesandbox.png) -1. The _Files_ section with a list of files like `App.js`, `index.js`, `styles.css` and a folder called `public` -1. The _code editor_ where you'll see the source code of your selected file -1. The _browser_ section where you'll see how the code you've written will be displayed +1. القسم _Files_ فيه قائمة بالملفات مثل `App.js` و `index.js` و `styles.css` ومجلد يسمى `public`. +1. _code editor_ حيث سترى الكود للملف المحدد. +1. القسم _browser_ حيث سترى كيف سيتم عرض الكود الذي كتبته. -The `App.js` file should be selected in the _Files_ section. The contents of that file in the _code editor_ should be: +ملف _App.js_ يجب أن يكون محددًا في القسم _Files_. محتويات ذلك الملف في _code editor_ يجب أن تكون: ```jsx export default function Square() { @@ -295,15 +296,15 @@ export default function Square() { } ``` -The _browser_ section should be displaying a square with a X in it like this: +قسم _browser_ يجب أن يعرض مربعًا مع X فيه مثل هذا: -![x-filled square](../images/tutorial/x-filled-square.png) +![مربع يحتوي على X](../images/tutorial/x-filled-square.png) -Now let's have a look at the files in the starter code. +والآن دعنا نلقي نظرة على الملفات في الكود المبدئي. #### `App.js` {/*appjs*/} -The code in `App.js` creates a _component_. In React, a component is a piece of reusable code that represents a part of a user interface. Components are used to render, manage, and update the UI elements in your application. Let's look at the component line by line to see what's going on: +الكود في `App.js` ينشئ _مكونًا_ (Component). في React, المكون هو جزء من الكود قابل لإعادة الاستخدام يقدم جزءًا من واجهة المستخم. المكونان تستخدم لعرض وإدارة وتحديث عناصر واجهة المستخدم في تطبيقك. دعنا نلقي نظرة على المكون سطرًا بسطر لنرى ما يحدث: ```js {1} export default function Square() { @@ -311,7 +312,7 @@ export default function Square() { } ``` -The first line defines a function called `Square`. The `export` JavaScript keyword makes this function accessible outside of this file. The `default` keyword tells other files using your code that it's the main function in your file. +السطر الأول يعرّف وظيفة مسماه `Square`. الكلمة الأساسية `export` في JavaScript تجعل هذه الوظيفة متاحة خارج هذا الملف. الكلمة الأساسية `default` تخبر الملفات الأخرى التي تستخدم كودك أنها الوظيفة الرئيسية في ملفك. ```js {2} export default function Square() { @@ -319,15 +320,15 @@ export default function Square() { } ``` -The second line returns a button. The `return` JavaScript keyword means whatever comes after is returned as a value to the caller of the function. `` closes the JSX element to indicate that any following content shouldn't be placed inside the button. +السطر الثاني يرجع زرًّا. الكلمة الأساسية `return` في JavaScript تعني أن أي شيء يأتي بعدها يعاد كقيمة لمن يستدعي الوظيفة. `` يغلق عنصر JSX ليشير إلى أن أي محتوى يليه لا ينبغي وضعه داخل الزرّ. #### `styles.css` {/*stylescss*/} -Click on the file labeled `styles.css` in the _Files_ section of CodeSandbox. This file defines the styles for your React app. The first two _CSS selectors_ (`*` and `body`) define the style of large parts of your app while the `.square` selector defines the style of any component where the `className` property is set to `square`. In your code, that would match the button from your Square component in the `App.js` file. +اضغط على الملف المسمى `styles.css` في قسم _Files_ في CodeSandbox. يحدد هذا الملف الأنماط لتطبيق React الخاص بك. _محددان CSS_ الأولان (`*` و `body`) يحددان نمط أجزاء كبيرة من تطبيقك بينما المحدد `.square` يحدد نمط أي مكون يتم تعيين خاصية `className` إلى `square`. في كودك، سيتطابق ذلك مع الزرّ من مكون Square في ملف `App.js`. #### `index.js` {/*indexjs*/} -Click on the file labeled `index.js` in the _Files_ section of CodeSandbox. You won't be editing this file during the tutorial but it is the bridge between the component you created in the `App.js` file and the web browser. +اضغط على الملف المسمى `index.js` في قسم _Files_ في CodeSandbox. لن تقوم بتحرير هذا الملف خلال الدليل التطبيقي ولكنه هو الجسر بين المكون الذي أنشأته في ملف `App.js` ومتصفح الويب. ```jsx import { StrictMode } from 'react'; @@ -337,20 +338,21 @@ import './styles.css'; import App from './App'; ``` -Lines 1-5 brings all the necessary pieces together: +الأسطر من 1 إلى 5 تجمع كل القطع اللازمة معًا: * React -* React's library to talk to web browsers (React DOM) -* the styles for your components -* the component you created in `App.js`. +* مكتبة React للتحدث مع متصفحات الويب (React DOM) +* الأنماط لمكوناتك +* المكون الذي أنشأته في `App.js`. -The remainder of the file brings all the pieces together and injects the final product into `index.html` in the `public` folder. +باقي الملف يجمع كل القطع معًا ويضيف المنتج النهائي إلى `index.html` في مجلد `public`. -### Building the board {/*building-the-board*/} -Let's get back to `App.js`. This is where you'll spend the rest of the tutorial. +### بناء اللوحة {/*building-the-board*/} -Currently the board is only a single square, but you need nine! If you just try and copy paste your square to make two squares like this: +لنعد إلى `App.js`. هذا هو المكان الذي ستقضي فيه بقية الدليل التطبيقي. + +حاليًا اللوحة تحتوي على مربع واحد فقط، ولكنك تحتاج إلى تسعة! إذا حاولت نسخ ولصق المربع لتصنع مربعين مثل هذا: ```js {2} export default function Square() { @@ -358,7 +360,7 @@ export default function Square() { } ``` -You'll get this error: +ستحصل على هذا الخطأ: @@ -366,7 +368,7 @@ You'll get this error: -React components need to return a single JSX element and not multiple adjacent JSX elements like two buttons. To fix this you can use *fragments* (`<>` and ``) to wrap multiple adjacent JSX elements like this: +تحتاج مكونات React إلى إرجاع عنصر JSX واحد وليس عناصر JSX المجاورة مثل زرين. لإصلاح هذا يمكنك استخدام *الأجزاء* (Fragments) (`<>` و ``) لتجميع عناصر JSX المجاورة مثل هذا: ```js {3-6} export default function Square() { @@ -379,17 +381,17 @@ export default function Square() { } ``` -Now you should see: +الآن يجب أن ترى: -![two x-filled squares](../images/tutorial/two-x-filled-squares.png) +![زرين مملوئين بـX](../images/tutorial/two-x-filled-squares.png) -Great! Now you just need to copy-paste a few times to add nine squares and... +رائع! الآن تحتاج فقط إلى نسخ ولصق عدة مرات لإضافة تسعة مربعات و... -![nine x-filled squares in a line](../images/tutorial/nine-x-filled-squares.png) +![تسع مربعات مملوءة بـX في سطر](../images/tutorial/nine-x-filled-squares.png) -Oh no! The squares are all in a single line, not in a grid like you need for our board. To fix this you'll need to group your squares into rows with `div`s and add some CSS classes. While you're at it, you'll give each square a number to make sure you know where each square is displayed. +أوه لا! المربعات كلها في سطر واحد، وليس في شبكة كما تحتاج للوحة. لإصلاح هذا، ستحتاج إلى تجميع المربعات في صفوف مع `div`s وإضافة بعض فئات CSS. بينما أنت في ذلك، ستعطي كل مربع رقمًا للتأكد من أنك تعرف أين يتم عرض كل مربع. -In the `App.js` file, update the `Square` component to look like this: +في ملف `App.js`، عدّل مكون `Square` ليبدو مثل هذا: ```js {3-19} export default function Square() { @@ -415,11 +417,11 @@ export default function Square() { } ``` -The CSS defined in `styles.css` styles the divs with the `className` of `board-row`. Now that you've grouped your components into rows with the styled `div`s you have your tic-tac-toe board: +تنسيقات _CSS_ المحددة في `styles.css` تنسق الـ `div`s التي تحمل `className` بقيمة `board-row`. الآن بعد تجميع المكونات في صفوف مع الـ `div`s المنسقة، لديك لوحة الـ tic-tac-toe: -![tic-tac-toe board filled with numbers 1 through 9](../images/tutorial/number-filled-board.png) +![لوحة tic-tac-toe مملوءة بالأرقام من 1 إلى 9](../images/tutorial/number-filled-board.png) -But you now have a problem. Your component named `Square`, really isn't a square anymore. Let's fix that by changing the name to `Board`: +لكن الآن لديك مشكلة. المكون الذي يحمل اسم `Square`، ليس مربعًا بعد الآن. دعنا نصلح ذلك عن طريق تغيير الاسم إلى `Board`: ```js {1} export default function Board() { @@ -427,7 +429,7 @@ export default function Board() { } ``` -At this point your code should look something like this: +في هذه النقطة يجب أن يبدو الكود الخاص بك مثل هذا: @@ -464,6 +466,7 @@ body { font-family: sans-serif; margin: 20px; padding: 0; + direction: rtl; } .square { @@ -504,15 +507,17 @@ body { -Psssst... That's a lot to type! It's okay to copy and paste code from this page. However, if you're up for a little challenge, we recommend only copying code that you've manually typed at least once yourself. +جيد، يمكنك نسخ ولصق الكود من هذه الصفحة. ولكن حاول كتابته بنفسك أولاً! + +هذا كثير للكتابة! لا بأس بنسخ ولصق الكود من هذه الصفحة. ومع ذلك، إذا كنت تريد تحديًا صغيرًا، فنحن نوصي بنسخ الكود الذي كتبته يدويًا مرة واحدة على الأقل بنفسك. -### Passing data through props {/*passing-data-through-props*/} +### تمرير بيانات من خلال الخصائص (props) {/*passing-data-through-props*/} -Next, you'll want to change the value of a square from empty to "X" when the user clicks on the square. With how you've built the board so far you would need to copy-paste the code that updates the square nine times (once for each square you have)! Instead of copy-pasting, React's component architecture allows you to create a reusable component to avoid messy, duplicated code. +لاحقًا، ستريد تغيير قيمة المربع من فارغة إلى "X" عندما ينقر المستخدم على المربع. مع كيفية بناء اللوحة حتى الآن، ستحتاج إلى نسخ ولصق الكود الذي يعدل المربع تسع مرات (مرة واحدة لكل مربع لديك)! بدلاً من النسخ واللصق، تسمح لك هندسة المكونات في React بإنشاء مكون قابل لإعادة الاستخدام لتجنب الكود المكرر الفوضوي. -First, you are going to copy the line defining your first square (``) from your `Board` component into a new `Square` component: +أولاً، ستقوم بنسخ السطر الذي يحدد المربع الأول (``) من مكون `Board` إلى مكون `Square` جديد: ```js {1-3} function Square() { @@ -524,7 +529,7 @@ export default function Board() { } ``` -Then you'll update the Board component to render that `Square` component using JSX syntax: +لاحقًا، ستعدل مكون `Board` لتقديم مكون `Square` باستخدام بناء الجملة JSX: ```js {5-19} // ... @@ -551,15 +556,15 @@ export default function Board() { } ``` -Note how unlike the browser `div`s, your own components `Board` and `Square` must start with a capital letter. +لاحظ كيف _على عكس عناصر `div` في المتصفح_، يجب أن تبدأ المكونات الخاصة بك `Board` و `Square` بحرف كبير. -Let's take a look: +دعنا نلقي نظرة: -![one-filled board](../images/tutorial/board-filled-with-ones.png) +![لوحة مملوءة بـ1](../images/tutorial/board-filled-with-ones.png) -Oh no! You lost the numbered squares you had before. Now each square says "1". To fix this, you will use *props* to pass the value each square should have from the parent component (`Board`) to its child (`Square`). +أوه لا! لقد فقدت المربعات المرقمة التي كانت لديك من قبل. الآن يقول كل مربع "1". لإصلاح هذا، ستستخدم *الخصائص (props)* لتمرير القيمة التي يجب أن يكون لكل مربع من المكون الأصلي (`Board`) إلى مكونه الابن (`Square`). -Update the `Square` component to read the `value` prop that you'll pass from the `Board`: +عدّل مكون `Square` لقراءة خاصية `value` التي ستمررها من `Board`: ```js {1} function Square({ value }) { @@ -567,9 +572,9 @@ function Square({ value }) { } ``` -`function Square({ value })` indicates the Square component can be passed a prop called `value`. +تشير `function Square({ value })` إلى أن مكون Square يمكن أن يُمرر إليه خاصية تسمى `value`. -Now you want to display that `value` instead of `1` inside every square. Try doing it like this: +الآن تريد عرض هذه القيمة بدلاً من `1` داخل كل مربع. حاول القيام بذلك بهذه الطريقة: ```js {2} function Square({ value }) { @@ -577,11 +582,11 @@ function Square({ value }) { } ``` -Oops, this is not what you wanted: +أوبس! هذا ليس ما تريده: -![value-filled board](../images/tutorial/board-filled-with-value.png) +![لوحة مملوءة بـvalue](../images/tutorial/board-filled-with-value.png) -You wanted to render the JavaScript variable called `value` from your component, not the word "value". To "escape into JavaScript" from JSX, you need curly braces. Add curly braces around `value` in JSX like so: +لقد أردت عرض متغير JavaScript يسمى `value` من مكونك، وليس كلمة "value". لـ"التخطي إلى JavaScript" من JSX، تحتاج إلى الأقواس المنحنية (curly braces). أضف الأقواس المنحنية حول `value` في JSX على النحو التالي: ```js {2} function Square({ value }) { @@ -589,11 +594,11 @@ function Square({ value }) { } ``` -For now, you should see an empty board: +الآن، يجب أن ترى لوحة فارغة: -![empty board](../images/tutorial/empty-board.png) +![لوحة فارغة](../images/tutorial/empty-board.png) -This is because the `Board` component hasn't passed the `value` prop to each `Square` component it renders yet. To fix it you'll add the `value` prop to each `Square` component rendered by the `Board` component: +هذا لأن مكون `Board` لم يمرر خاصية `value` إلى كل مكون `Square` يقوم بتقديمه بعد. لإصلاحه، ستضيف خاصية `value` إلى كل مكون `Square` يقوم بتقديمه مكون `Board`: ```js {5-7,10-12,15-17} export default function Board() { @@ -619,11 +624,11 @@ export default function Board() { } ``` -Now you should see a grid of numbers again: +الآن يجب أن ترى شبكة من الأرقام مرة أخرى: -![tic-tac-toe board filled with numbers 1 through 9](../images/tutorial/number-filled-board.png) +![لوحة tic-tac-toe معبأة بالأرقام من 1 إلى 9](../images/tutorial/number-filled-board.png) -Your updated code should look like this: +كودك المعدل يجب أن يبدو كالتالي: @@ -664,6 +669,7 @@ body { font-family: sans-serif; margin: 20px; padding: 0; + direction: rtl; } .square { @@ -702,14 +708,15 @@ body { -### Making an interactive component {/*making-an-interactive-component*/} +### إعداد مكون تفاعلي {/*making-an-interactive-component*/} + +لنملأ مكون `Square` بـ `X` عند النقر عليه. أعلن عن دالة (Function) تسمى `handleClick` داخل `Square`. ثم، أضف `onClick` إلى خصائص عنصر JSX الزر المُرجع من `Square`: -Let's fill the `Square` component with an `X` when you click it. Declare a function called `handleClick` inside of the `Square`. Then, add `onClick` to the props of the button JSX element returned from the `Square`: ```js {2-4,9} function Square({ value }) { function handleClick() { - console.log('clicked!'); + console.log('ضُغطت!'); } return ( @@ -723,11 +730,11 @@ function Square({ value }) { } ``` -If you click on a square now, you should see a log saying `"clicked!"` in the _Console_ tab at the bottom of the _Browser_ section in CodeSandbox. Clicking the square more than once will log `"clicked!"` again. Repeated console logs with the same message will not create more lines in the console. Instead, you will see an incrementing counter next to your first `"clicked!"` log. +إذا ضغطت على مربع الآن، يجب أن ترى log في علامة التبويب _Console_ في أسفل قسم _Browser_ في CodeSandbox يقول `"ضُغطت!"`. الضغط على المربع أكثر من مرة سيؤدي إلى طباعة `"ضُغطت!"` مرة أخرى. تكرار `console.log("ضُغطت!")` بنفس الرسالة لن ينشئ سطرًا جديدًا في الـ console. بدلاً من ذلك، سترى عدادًا متزايدًا بجانب أول طباعة `"ضُغطت!"` لديك. -If you are following this tutorial using your local development environment, you need to open your browser's Console. For example, if you use the Chrome browser, you can view the Console with the keyboard shortcut **Shift + Ctrl + J** (on Windows/Linux) or **Option + ⌘ + J** (on macOS). +إن كنت تتابع هذا الدليل التطبيقي باستخدام بيئة التطوير المحلية الخاصة بك، فستحتاج إلى فتح Console المتصفح الخاص بك. على سبيل المثال، إذا كنت تستخدم متصفح Chrome، يمكنك عرض Console باستخدام اختصار لوحة المفاتيح **Shift + Ctrl + J** (على نظامي التشغيل Windows/Linux) أو **Option + ⌘ + J** (على نظام التشغيل macOS). From 214f0eec814eecee2cf443a8448e860fe59b4c51 Mon Sep 17 00:00:00 2001 From: A7med3bdulBaset Date: Sat, 29 Apr 2023 19:15:56 +0300 Subject: [PATCH 02/34] Part 2 --- src/content/learn/tutorial-tic-tac-toe.md | 51 +++++++++++++---------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/src/content/learn/tutorial-tic-tac-toe.md b/src/content/learn/tutorial-tic-tac-toe.md index 3c7b84ec4..9f942ac8f 100644 --- a/src/content/learn/tutorial-tic-tac-toe.md +++ b/src/content/learn/tutorial-tic-tac-toe.md @@ -783,7 +783,7 @@ export default function Board() { } ``` -Now you'll change `Square` to display an "X" when clicked. Replace the `console.log("clicked!");` event handler with `setValue('X');`. Now your `Square` component looks like this: +الآن ستغير `Square` لعرض "X" عند النقر عليه. استبدل معالج الحدث `console.log("ضُغطت!");` بـ `setValue('X');`. الآن يبدو مكون `Square` الخاص بك على النحو التالي: ```js {5} function Square() { @@ -804,13 +804,13 @@ function Square() { } ``` -By calling this `set` function from an `onClick` handler, you're telling React to re-render that `Square` whenever its `` يغلق عنصر JSX ليشير إلى أن أي محتوى يليه لا ينبغي وضعه داخل الزرّ. +السطر الثاني يرجع زرًّا. الكلمة الأساسية `return` في JavaScript تعني أن أي شيء يأتي بعدها يعاد كقيمة لمن يستدعي الوظيفة. `` يغلق عنصر JSX ليشير إلى أن أي محتوى يليه لا ينبغي وضعه داخل الزرّ. #### `styles.css` {/*stylescss*/} @@ -389,7 +389,7 @@ export default function Square() { ![تسع مربعات مملوءة بـX في سطر](../images/tutorial/nine-x-filled-squares.png) -أوه لا! المربعات كلها في سطر واحد، وليس في شبكة كما تحتاج للوحة. لإصلاح هذا، ستحتاج إلى تجميع المربعات في صفوف مع `div`s وإضافة بعض فئات CSS. بينما أنت في ذلك، ستعطي كل مربع رقمًا للتأكد من أنك تعرف أين يتم عرض كل مربع. +أوه لا! المربعات كلها في سطر واحد، وليس في شبكة كما تحتاج للوحة. لإصلاح هذا، ستحتاج إلى تجميع المربعات في صفوف مع `div` وإضافة بعض فئات CSS. بينما أنت في ذلك، ستعطي كل مربع رقمًا للتأكد من أنك تعرف أين يتم عرض كل مربع. في ملف `App.js`، عدّل مكون `Square` ليبدو مثل هذا: @@ -417,9 +417,9 @@ export default function Square() { } ``` -تنسيقات _CSS_ المحددة في `styles.css` تنسق الـ `div`s التي تحمل `className` بقيمة `board-row`. الآن بعد تجميع المكونات في صفوف مع الـ `div`s المنسقة، لديك لوحة التيك تاك تو: +تنسيقات _CSS_ المحددة في `styles.css` تنسق الـ `div` التي تحمل `className` بقيمة `board-row`. الآن بعد تجميع المكونات في صفوف مع الـ `div` المنسقة، لديك لوحة التيك تاك تو: -![لوحة 'تيك تاك تو' مملوءة بالأرقام من 1 إلى 9](../images/tutorial/number-filled-board.png) +![لوحة "تيك تاك تو" مملوءة بالأرقام من 1 إلى 9](../images/tutorial/number-filled-board.png) لكن الآن لديك مشكلة. المكون الذي يحمل اسم `Square`، ليس مربعًا بعد الآن. دعنا نصلح ذلك من خلال تغيير الاسم إلى `Board`: @@ -509,7 +509,7 @@ body { جيد، يمكنك نسخ ولصق الكود من هذه الصفحة. ولكن حاول كتابته بنفسك أولاً! -هذا كثير للكتابة! لا بأس بنسخ ولصق الكود من هذه الصفحة. ومع ذلك، إذا كنت تريد تحديًا صغيرًا، فنحن نوصي بنسخ الكود الذي كتبته يدويًا مرة واحدة على الأقل بنفسك. +هذا كثير للكتابة! لا بأس بنسخ ولصق الكود من هذه الصفحة. ومع ذلك، إذا كنت تريد تحديًا صغيرًا، فنحن نوصي بكتابة الكود يدويًا مرة على الأقل. @@ -626,7 +626,7 @@ export default function Board() { الآن يجب أن ترى شبكة من الأرقام مرة أخرى: -![لوحة 'تيك تاك تو' معبأة بالأرقام من 1 إلى 9](../images/tutorial/number-filled-board.png) +![لوحة "تيك تاك تو" معبأة بالأرقام من 1 إلى 9](../images/tutorial/number-filled-board.png) كودك المعدل يجب أن يبدو كالتالي: @@ -738,11 +738,11 @@ function Square({ value }) { -As a next step, you want the Square component to "remember" that it got clicked, and fill it with an "X" mark. To "remember" things, components use *state*. +كخطوة تالية، تريد أن يتذكر مكون `Square` أنه تم النقر عليه، وملءه بعلامة "X". لـ "تذكر" الأشياء، يستخدم المكونات *الحالة*. -React provides a special function called `useState` that you can call from your component to let it "remember" things. Let's store the current value of the `Square` in state, and change it when the `Square` is clicked. +تقدم React دالة خاصة تسمى `useState` يمكنك استدعاؤها من مكونك لتمكينه من "تذكر" الأشياء. دعنا نخزن القيمة الحالية لـ `Square` في الحالة، ونغيرها عند النقر على `Square`. -Import `useState` at the top of the file. Remove the `value` prop from the `Square` component. Instead, add a new line at the start of the `Square` that calls `useState`. Have it return a state variable called `value`: +استيراد `useState` في أعلى الملف. قم بإزالة خاصية `value` من مكون `Square`. بدلاً من ذلك، أضف سطرًا جديدًا في بداية `Square` يستدعي `useState`. اجعله يعيد متغير حالة يسمى `value`: ```js {1,3,4} import { useState } from 'react'; @@ -754,9 +754,9 @@ function Square() { //... ``` -`value` stores the value and `setValue` is a function that can be used to change the value. The `null` passed to `useState` is used as the initial value for this state variable, so `value` here starts off equal to `null`. +`value` تحتفظ بالقيمة و `setValue` هي الدالة التي تستخدم لتعديل القيمة. الـ`null` المُمر إلى `useState` يستخدم كالقيمة الأولية لمتغير الحالة هذا، لذا `value` هنا يبدأ بالتساوي مع `null`. -Since the `Square` component no longer accepts props anymore, you'll remove the `value` prop from all nine of the Square components created by the Board component: +لأن مكون `Square` لم يعد يقبل الخصائص (props) بعد الآن، ستقوم بإزالة خاصية `value` من جميع المربعات التسعة التي أنشأها مكون `Board`: ```js {6-8,11-13,16-18} // ... @@ -927,7 +927,7 @@ body { ### رفع الحالة لأعلى (Lifting State Up) {/*lifting-state-up*/} -حاليًا، كل مكون `Square` يحتفظ بجزء من حالة اللعبة. للتحقق من وجود فائز في لعبة 'تيك تاك تو'، سيحتاج `Board` إلى معرفة حالة كل من مكونات `Square` التسعة. +حاليًا، كل مكون `Square` يحتفظ بجزء من حالة اللعبة. للتحقق من وجود فائز في لعبة "تيك تاك تو"، سيحتاج `Board` إلى معرفة حالة كل من مكونات `Square` التسعة. كيف ستحقق ذلك؟ في البداية، قد تخمن أن `Board` يحتاج إلى "سؤال" كل `Square` عن حالته. على الرغم من أن هذا النهج ممكن تقنيًا في React، إلا أننا ننصح بعدم استخدامه لأن الكود يصبح من الصعب فهمه، وعرضة للأخطاء (bugs)، وصعب التعديل. بدلاً من ذلك، أفضل نهج هو تخزين حالة اللعبة في مكون `Board` الأصل بدلاً من كل `Square`. يمكن لمكون `Board` أن يخبر كل `Square` ما يجب عليه عرضه عن طريق تمرير خاصية (prop)، مثلما فعلت عندما قمت بتمرير رقم إلى كل `Square`. @@ -1384,7 +1384,7 @@ const nextSquares = ['X', null, null, null, null, null, null, null, null]; ### أخذ الأدوار {/*taking-turns*/} -الآن وقت إصلاح عيب رئيسي في لعبة 'تيك تاك تو': لا يمكن وضع علامات "O" على اللوحة. +الآن وقت إصلاح عيب رئيسي في لعبة "تيك تاك تو": لا يمكن وضع علامات "O" على اللوحة. ستقوم بتعيين الخطوة الأولى لتكون "X" افتراضيًا. دعونا نتتبع هذا عن طريق إضافة قطعة أخرى من الحالة إلى مكون `Board`: @@ -1616,7 +1616,7 @@ export default function Board() { } ``` -مبارك! لديك الآن لعبة 'تيك تاك تو' تعمل. ولقد تعلمت للتو أساسيات React أيضًا. لذا أنت الفائز الحقيقي هنا. هنا ما يجب أن يبدو الكود: +مبارك! لديك الآن لعبة "تيك تاك تو" تعمل. ولقد تعلمت للتو أساسيات React أيضًا. لذا أنت الفائز الحقيقي هنا. هنا ما يجب أن يبدو الكود: @@ -2285,7 +2285,7 @@ body { بمجرد أن تمر على مصفوفة `history` بالدالة التي قمت بتمريرها إلى `map`، فإن معامل `squares` argument يمر على كل عنصر من عناصر `history`، ومعامل `move` يمر على كل مسلسل في المصفوفة: `0`، `1`، `2`، …. (في معظم الحالات، ستحتاج إلى عناصر المصفوفة الفعلية، ولكن لتقديم قائمة من الخطوات، ستحتاج فقط إلى الفهارس.) -لكل حركة في تاريخ لعبة 'تيك تاك تو'، تنشئ عنصر قائمة `
  • ` يحتوي على زر `` يغلق عنصر JSX ليشير إلى أن أي محتوى يليه لا ينبغي وضعه داخل الزرّ. +السطر الثاني يرجع زرًّا. الكلمة الأساسية `return` في JavaScript تعني أن أي شيء يأتي بعدها يعاد كقيمة لمن يستدعي الوظيفة. `` يغلق عنصر JSX ليشير إلى أن أي محتوى يليه لا ينبغي وضعه داخل الزرّ. #### `styles.css` {/*stylescss*/} -اضغط على الملف المسمى `styles.css` في قسم _Files_ في CodeSandbox. يحدد هذا الملف الأنماط لتطبيق React الخاص بك. _محددان CSS_ الأولان (`*` و `body`) يحددان نمط أجزاء كبيرة من تطبيقك بينما المحدد `.square` يحدد نمط أي مكون يتم تعيين خاصية `className` إلى `square`. في كودك، سيتطابق ذلك مع الزرّ من مكون Square في ملف `App.js`. +اضغط على الملف المسمى `styles.css` في قسم _الملفات_ في CodeSandbox. يحدد هذا الملف الأنماط لتطبيق React الخاص بك. _محددان CSS_ الأولان (`*` و `body`) يحددان نمط أجزاء كبيرة من تطبيقك بينما المحدد `.square` يحدد نمط أي مكون يتم تعيين خاصية `className` إلى `square`. في كودك، سيتطابق ذلك مع الزرّ من مكون Square في ملف `App.js`. #### `index.js` {/*indexjs*/} -اضغط على الملف المسمى `index.js` في قسم _Files_ في CodeSandbox. لن تقوم بتحرير هذا الملف خلال الشرح التطبيقي ولكنه هو الجسر بين المكون الذي أنشأته في ملف `App.js` ومتصفح الويب. +اضغط على الملف المسمى `index.js` في قسم الملفات في CodeSandbox. لن تقوم بتحرير هذا الملف خلال الدرس ولكنه هو الجسر بين المكون الذي أنشأته في ملف `App.js` ومتصفح الويب. ```jsx import { StrictMode } from 'react'; @@ -338,7 +338,7 @@ import './styles.css'; import App from './App'; ``` -الأسطر من 1 إلى 5 تجمع كل القطع اللازمة معًا: +الأسطر من 1 إلى 5 تستدعي كل القطع اللازمة معًا: * React * مكتبة React للتحدث مع متصفحات الويب (React DOM) @@ -350,7 +350,7 @@ import App from './App'; ### بناء اللوحة {/*building-the-board*/} -لنعد إلى `App.js`. هذا هو المكان الذي ستقضي فيه بقية الشرح التطبيقي. +لنعد إلى `App.js`. هذا هو المكان الذي ستقضي فيه بقية الدرس. حاليًا اللوحة تحتوي على مربع واحد فقط، ولكنك تحتاج إلى تسعة! إذا حاولت نسخ ولصق المربع لتصنع مربعين مثل هذا: @@ -385,7 +385,7 @@ export default function Square() { ![زرين مملوئين بـX](../images/tutorial/two-x-filled-squares.png) -رائع! الآن تحتاج فقط إلى نسخ ولصق عدة مرات لإضافة تسعة مربعات و... +رائع! الآن تحتاج فقط إلى نسخه ولصقه عدة مرات لإضافة تسعة مربعات و... ![تسع مربعات مملوءة بـX في سطر](../images/tutorial/nine-x-filled-squares.png) From e3033f2031b1e48b2443810bca19dd75de0a4e2e Mon Sep 17 00:00:00 2001 From: Ahmed Abdelbaset Date: Thu, 8 Jun 2023 19:44:47 +0300 Subject: [PATCH 25/34] to 700 --- src/content/learn/tutorial-tic-tac-toe.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/learn/tutorial-tic-tac-toe.md b/src/content/learn/tutorial-tic-tac-toe.md index 85f1b52c8..0d3560073 100644 --- a/src/content/learn/tutorial-tic-tac-toe.md +++ b/src/content/learn/tutorial-tic-tac-toe.md @@ -515,7 +515,7 @@ body { ### تمرير بيانات من خلال الخصائص (props) {/*passing-data-through-props*/} -لاحقًا، ستريد تغيير قيمة المربع من فارغة إلى "X" عندما ينقر المستخدم على المربع. مع كيفية بناء اللوحة حتى الآن، ستحتاج إلى نسخ ولصق الكود الذي يعدل المربع تسع مرات (مرة واحدة لكل مربع لديك)! بدلاً من النسخ واللصق، تسمح لك هندسة المكونات في React بإنشاء مكون قابل لإعادة الاستخدام لتجنب الكود المكرر الفوضوي. +لاحقًا، ستريد تغيير قيمة المربع من فارغة إلى "X" عندما ينقر المستخدم على المربع. مع كيفية بناء اللوحة حتى الآن، ستحتاج إلى نسخ ولصق الكود الذي يعدل المربع تسع مرات (مرة واحدة لكل مربع لديك)! بدلاً من النسخ واللصق، تسمح لك هندسة المكونات في React بإنشاء مكون قابل لإعادة الاستخدام لتجنب فوضى تكرار الكود. أولاً، ستقوم بنسخ السطر الذي يحدد المربع الأول (``) من مكون `Board` إلى مكون `Square` جديد: @@ -556,7 +556,7 @@ export default function Board() { } ``` -لاحظ كيف _على عكس عناصر `div` في المتصفح_، يجب أن تبدأ المكونات الخاصة بك `Board` و `Square` بحرف كبير. +لاحظ كيف تبدأ المكونات الخاصة بك `Board` و `Square` بحرف كبير _على عكس عناصر `div` في المتصفح_. دعنا نلقي نظرة: From e0e42a5050d62caa21fb8390e55d0dd012d54dc1 Mon Sep 17 00:00:00 2001 From: Ahmed Abdelbaset Date: Thu, 8 Jun 2023 20:01:15 +0300 Subject: [PATCH 26/34] to 1340 --- src/content/learn/tutorial-tic-tac-toe.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/content/learn/tutorial-tic-tac-toe.md b/src/content/learn/tutorial-tic-tac-toe.md index 0d3560073..ab8c0c868 100644 --- a/src/content/learn/tutorial-tic-tac-toe.md +++ b/src/content/learn/tutorial-tic-tac-toe.md @@ -730,17 +730,17 @@ function Square({ value }) { } ``` -إذا ضغطت على مربع الآن، يجب أن ترى log في علامة التبويب _Console_ في أسفل قسم _Browser_ في CodeSandbox يقول `"ضُغطت!"`. الضغط على المربع أكثر من مرة سيؤدي إلى طباعة `"ضُغطت!"` مرة أخرى. تكرار `console.log("ضُغطت!")` بنفس الرسالة لن ينشئ سطرًا جديدًا في الـ console. بدلاً من ذلك، سترى عدادًا متزايدًا بجانب أول طباعة `"ضُغطت!"` لديك. +إذا ضغطت على مربع الآن، يجب أن ترى رسالة في علامة التبويب _Console_ في أسفل قسم _Browser_ في CodeSandbox يقول `"ضُغطت!"`. الضغط على المربع أكثر من مرة سيؤدي إلى طباعة `"ضُغطت!"` مرة أخرى. تكرار `console.log("ضُغطت!")` بنفس الرسالة لن ينشئ سطرًا جديدًا في الـ console. بدلاً من ذلك، سترى عدادًا متزايدًا بجانب أول طباعة `"ضُغطت!"` لديك. -إن كنت تتابع هذا الشرح التطبيقي باستخدام بيئة التطوير المحلية الخاصة بك، فستحتاج إلى فتح Console المتصفح الخاص بك. على سبيل المثال، إذا كنت تستخدم متصفح Chrome، يمكنك عرض Console باستخدام اختصار لوحة المفاتيح **Shift + Ctrl + J** (على نظامي التشغيل Windows/Linux) أو **Option + ⌘ + J** (على نظام التشغيل macOS). +إن كنت تتابع هذا الشرح باستخدام بيئة التطوير المحلية الخاصة بك، فستحتاج إلى فتح Console المتصفح الخاص بك. على سبيل المثال، إذا كنت تستخدم متصفح Chrome، يمكنك عرض Console باستخدام اختصار لوحة المفاتيح **Shift + Ctrl + J** (على نظامي التشغيل Windows/Linux) أو **Option + ⌘ + J** (على نظام التشغيل macOS). -كخطوة تالية، تريد أن يتذكر مكون `Square` أنه تم النقر عليه، وملءه بعلامة "X". لـ "تذكر" الأشياء، يستخدم المكونات *الحالة*. +كخطوة تالية، تريد أن يتذكر مكون `Square` أنه تم النقر عليه، وكتابة "X" فيه. "لتذكر" الأشياء، يستخدم المكونات *الحالة (State)*. -تقدم React دالة خاصة تسمى `useState` يمكنك استدعاؤها من مكونك لتمكينه من "تذكر" الأشياء. دعنا نخزن القيمة الحالية لـ `Square` في الحالة، ونغيرها عند النقر على `Square`. +تقدم React دالة خاصة تسمى `useState` يمكنك استدعاؤها من مكونك لتمكنه "تذكر" الأشياء. دعنا نخزن القيمة الحالية لـ `Square` في الحالة، ونغيرها عند النقر على `Square`. استيراد `useState` في أعلى الملف. قم بإزالة خاصية `value` من مكون `Square`. بدلاً من ذلك، أضف سطرًا جديدًا في بداية `Square` يستدعي `useState`. اجعله يعيد متغير حالة يسمى `value`: @@ -905,9 +905,9 @@ body { -### أدوات مطوري React (React DevTools) {/*react-developer-tools*/} +### أدوات مطور React (React DevTools) {/*react-developer-tools*/} -أدوات مطوري React تتيح لك التحقق من الخصائص والحالة لمكونات React الخاصة بك. يمكنك العثور على علامة تبويب أدوات مطوري React في أسفل قسم المتصفح في CodeSandbox: +أدوات مطور React تتيح لك التحقق من الخصائص والحالة لمكونات React الخاصة بك. يمكنك العثور على علامة تبويب أدوات مطوري React في أسفل قسم المتصفح في CodeSandbox: ![أدوات مطوري React في CodeSandbox](../images/tutorial/codesandbox-devtools.png) @@ -931,7 +931,7 @@ body { كيف ستحقق ذلك؟ في البداية، قد تخمن أن `Board` يحتاج إلى "سؤال" كل `Square` عن حالته. على الرغم من أن هذا النهج ممكن تقنيًا في React، إلا أننا ننصح بعدم استخدامه لأن الكود يصبح من الصعب فهمه، وعرضة للأخطاء (bugs)، وصعب التعديل. بدلاً من ذلك، أفضل نهج هو تخزين حالة اللعبة في مكون `Board` الأصل بدلاً من كل `Square`. يمكن لمكون `Board` أن يخبر كل `Square` ما يجب عليه عرضه عن طريق تمرير خاصية (prop)، مثلما فعلت عندما قمت بتمرير رقم إلى كل `Square`. -**لجمع بيانات من أطفال (children)، أو لجعل مكونين طفلين يتواصلان مع بعضهما البعض، قم بتعريف الحالة المشتركة في مكونهما الأصل بدلاً من ذلك. يمكن لمكون الأصل أن يمرر هذه الحالة إلى الأطفال عن طريق خصائص (props). هذا يحافظ على تزامن مكونات الأطفال مع بعضها البعض ومع مكونها الأصل.** +**لجمع بيانات من أطفال (children)، أو لجعل مكونين طفلين يتواصلان مع بعضهما البعض، قم بتعريف الحالة المشتركة في مكونهما الأصل بدلاً من ذلك. يمكن للمكون الأصلي أن يمرر هذه الحالة إلى الأطفال عن طريق الخصائص (props). هذا يحافظ على تزامن مكونات الأطفال مع بعضها البعض ومع مكونها الأصل.** رفع الحالة إلى مكون أصل (lifting state up) هو أمر شائع عند إعادة تنظيم مكونات React. @@ -1079,7 +1079,7 @@ body { -كل مربع سيتلقة خاصية `value` التي ستكون إما `'X'` أو `'O'` أو `null` للمربعات الفارغة. +كل مربع سيتلقى خاصية `value` التي ستكون إما `'X'` أو `'O'` أو `null` للمربعات الفارغة. لاحقًا ستغير ما يحدث عند النقر على `Square`. مكون `Board` الآن يحتفظ بالمربعات المملوءة. ستحتاج إلى إيجاد طريقة لتحديث حالة `Board`. لأن الحالة هي خاصة بالمكون الذي يحددها، لا يمكنك تحديث حالة `Board` مباشرة من `Square`. @@ -1211,9 +1211,9 @@ export default function Board() { } ``` -لاحظ الصيغة الجديدة `() =>`. هنا، `() => handleClick(0)` هي *دالة سهم* (Arrow Function)، وهي طريقة أقصر لتعريف الدوال. عندما ينقر المربع، سيتم تشغيل الكود بعد السهم `=>`، والذي سيستدعي `handleClick(0)`. +لاحظ الصيغة الجديدة `() =>`. هنا، `() => handleClick(0)` هي *دالة سهمية* (Arrow Function)، وهي طريقة أقصر لتعريف الدوال. عندما ينقر المربع، سيتم تشغيل الكود بعد السهم `=>`، والذي سيستدعي `handleClick(0)`. -الآن تحتاج إلى تعديل المربعات الثمانية الأخرى لاستدعاء `handleClick` من الدوال السهم التي تمررها. تأكد من أن الوسيط لكل استدعاء لـ `handleClick` يتوافق مع فهرس المربع الصحيح: +الآن تحتاج إلى تعديل المربعات الثمانية الأخرى لاستدعاء `handleClick` من الدوال السهمية التي تمررها. تأكد من أن الوسيط لكل استدعاء لـ `handleClick` يتوافق مع فهرس المربع الصحيح: ```js {6-8,11-13,16-18} export default function Board() { From d80fe89b6e5e3acdee1f0f501e488e3b30850c68 Mon Sep 17 00:00:00 2001 From: Ahmed Abdelbaset Date: Thu, 8 Jun 2023 20:09:38 +0300 Subject: [PATCH 27/34] 1400 --- src/content/learn/tutorial-tic-tac-toe.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/content/learn/tutorial-tic-tac-toe.md b/src/content/learn/tutorial-tic-tac-toe.md index ab8c0c868..f45c21143 100644 --- a/src/content/learn/tutorial-tic-tac-toe.md +++ b/src/content/learn/tutorial-tic-tac-toe.md @@ -1340,7 +1340,7 @@ body { -الآن إدارة حالتك في مكون `Board` ، يمرر مكون `Board` الأصلي الخاص بك الخاصيات إلى مكونات `Square` الفرعية حتى يتم عرضها بشكل صحيح. عند النقر فوق `Square` ، يطلب مكون `Square` الفرعي الآن من مكون `Board` الأصلي تحديث حالة اللوحة. عندما تتغير حالة `Board` ، يتم إعادة تقديم كل من مكون `Board` و `Square` الفرعي تلقائيًا. إبقاء حالة جميع المربعات في مكون `Board` سيسمح له بتحديد الفائز في المستقبل. +الآن إدارة حالتك في مكون `Board` ، يمرر مكونك `Board` الأصلي الخاصيات إلى مكونات `Square` الفرعية كي يعرضها بشكل صحيح. عند النقر فوق `Square` ، يطلب مكون `Square` الفرعي الآن من مكون `Board` الأصلي تحديث حالة اللوحة. عندما تتغير حالة `Board` ، يتم إعادة تقديم كل من مكون `Board` و `Square` الفرعي تلقائيًا. إبقاء حالة جميع المربعات في مكون `Board` سيسمح له بتحديد الفائز في المستقبل. لنلخص ما يحدث عندما ينقر المستخدم على المربع الأيسر العلوي في اللوحة الخاصة بك لإضافة `X` إليه: @@ -1378,9 +1378,9 @@ const nextSquares = ['X', null, null, null, null, null, null, null, null]; النتيجة واحدة ولكن عن طريق عدم تغيير البيانات مباشرةً (تغيير البيانات الأساسية) ، تحصل على عدة فوائد. -عدم التغيير يجعل المميزات المعقدة أكثر سهولة في التنفيذ. لاحقًا في هذا الشرح التطبيقي، ستنفذ ميزة "السفر عبر الزمن" التي تتيح لك مراجعة تاريخ اللعبة و "الانتقال إلى الوراء" إلى الحركات السابقة. هذه الميزة ليست محدودة بالألعاب - القدرة على التراجع وإعادة الإجراءات ميزة شائعة للتطبيقات. عدم تغيير البيانات المباشر يتيح لك الاحتفاظ بالإصدارات السابقة من البيانات سليمة، وإعادة استخدامها لاحقًا. +عدم التغيير يجعل المميزات المعقدة أكثر سهولة في التنفيذ. لاحقًا في هذا الشرح التطبيقي، ستنفذ ميزة "السفر عبر الزمن" التي تتيح لك مراجعة تاريخ اللعبة و "الرجوع إلى الوراء" إلى الحركات السابقة. هذه الميزة ليست محدودة بالألعاب - القدرة على التراجع وإعادة الإجراءات ميزة شائعة للتطبيقات. عدم تغيير البيانات المباشر يتيح لك الاحتفاظ بالإصدارات السابقة من البيانات سليمة، وإعادة استخدامها لاحقًا. -هناك أيضًا فائدة أخرى لعدم التغيير. افترضيًا، كل العناصر الفرعية (الأبناء) تقوم بإعادة الإنشاء (re-render) تلقائيًا عندما يتغير حالة عنصر أب (الأب). هذا يشمل حتى العناصر الفرعية التي لم تتأثر بالتغيير. على الرغم من أن إعادة الإنشاء ليست بحد ذاتها ملحوظة للمستخدم (لا يجب عليك التحمس لمحاولة تجنبها!) ، قد ترغب في تخطي إعادة إنشاء جزء من الشجرة التي لم تتأثر بوضوح به لأسباب أدائية (Performance). عدم التغيير يجعل من السهل جدًا على العناصر مقارنة ما إذا كانت بياناتها قد تغيرت أم لا. يمكنك معرفة المزيد حول كيفية اختيار React عند إعادة إنشاء عنصر في [مرجع API `memo`](/reference/react/memo). +هناك أيضًا فائدة أخرى لعدم التغيير. افترضيًا، كل العناصر الفرعية (الأبناء) تقوم بإعادة التصيير (re-render) تلقائيًا عندما يتغير حالة عنصر أب. هذا يشمل حتى العناصر الفرعية التي لم تتأثر بالتغيير. على الرغم من أن إعادة التصيير ليست ملحوظة للمستخدم (لا يجب عليك التحمس لمحاولة تجنبها!)، قد ترغب في تخطي إعادة تصيير جزء من الشجرة التي لم تتأثر به لأسباب أدائية (Performance). عدم التغيير يجعل من السهل جدًا على العناصر مقارنة ما إذا كانت بياناتها قد تغيرت أم لا. يمكنك معرفة المزيد حول كيفية اختيار React متى يعيد تصيير عنصر في [مرجع API `memo`](/reference/react/memo). ### أخذ الأدوار {/*taking-turns*/} @@ -1395,9 +1395,11 @@ function Board() { // ... } +```ا +``` +``` ``` -Each time a player moves, `xIsNext` (a boolean) will be flipped to determine which player goes next and the game's state will be saved. You'll update the `Board`'s `handleClick` function to flip the value of `xIsNext`: في كل مرة يتحرك لاعب، سيتم تبديل `xIsNext` (قيمة منطقية) لتحديد أي لاعب يأتي بعد ذلك وسيتم حفظ حالة اللعبة. ستقوم بتحديث دالة `handleClick` في `Board` لتبديل قيمة `xIsNext`: From bfbfd69262a6e7b1fb9489f0ff797fa5f9fd880c Mon Sep 17 00:00:00 2001 From: Ahmed Abdelbaset Date: Thu, 8 Jun 2023 20:12:35 +0300 Subject: [PATCH 28/34] 1545 --- src/content/learn/tutorial-tic-tac-toe.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/content/learn/tutorial-tic-tac-toe.md b/src/content/learn/tutorial-tic-tac-toe.md index f45c21143..b469fd530 100644 --- a/src/content/learn/tutorial-tic-tac-toe.md +++ b/src/content/learn/tutorial-tic-tac-toe.md @@ -1395,11 +1395,7 @@ function Board() { // ... } -```ا ``` -``` -``` - في كل مرة يتحرك لاعب، سيتم تبديل `xIsNext` (قيمة منطقية) لتحديد أي لاعب يأتي بعد ذلك وسيتم حفظ حالة اللعبة. ستقوم بتحديث دالة `handleClick` في `Board` لتبديل قيمة `xIsNext`: @@ -1425,13 +1421,13 @@ export default function Board() { } ``` -الآن، بمجرد أن تضغط على مربعات مختلفة، سيتبدلون بين `X` و `O`، كما يجب أن يكونوا! +الآن، بمجرد أن تضغط على مربعات مختلفة، ستتبادل بين `X` و `O`، كما يُفترض أن يكونوا! لكن لحظة، هناك مشكلة. جرب النقر على نفس المربع عدة مرات: ![O تطغى على X](../images/tutorial/o-replaces-x.gif) -الـ `X` تمت الكتابة فوقها بـ `O`! بينما سيضيف هذا لمسة مثيرة للاهتمام للعبة، سنلتزم بالقواعد الأصلية الآن. +الـ `X` تمت الكتابة فوقها بـ `O`! بينما سيضيف هذا لمسة مثيرة للعبة، لكننا سنلتزم بالقواعد الأصلية الآن. عندما تحدد مربع بـ `X` أو `O` فأنت لا تتحقق أولاً مما إذا كان المربع يحتوي بالفعل على قيمة `X` أو `O`. يمكنك إصلاح هذا عن طريق *الخروج مبكرًا*. ستتحقق مما إذا كان المربع يحتوي بالفعل على `X` أو `O`. إذا كان المربع ممتلئًا بالفعل، فستقوم بـ `return` في دالة `handleClick` مبكرًا - قبل محاولة تحديث حالة اللوحة. From 3a7d4586b1d22ebaf8755cc2302d1fe6031691d5 Mon Sep 17 00:00:00 2001 From: Ahmed Abdelbaset Date: Thu, 8 Jun 2023 20:22:41 +0300 Subject: [PATCH 29/34] 1747 --- src/content/learn/tutorial-tic-tac-toe.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/content/learn/tutorial-tic-tac-toe.md b/src/content/learn/tutorial-tic-tac-toe.md index b469fd530..1d7e2eff9 100644 --- a/src/content/learn/tutorial-tic-tac-toe.md +++ b/src/content/learn/tutorial-tic-tac-toe.md @@ -1546,7 +1546,7 @@ body { ### الإعلان عن الفائز {/*declaring-a-winner*/} -الآن بما أن اللاعبين يمكنهم التناوب، ستريد أن تظهر عندما يفوز اللاعب ولا يوجد المزيد من الدورات للعب. للقيام بذلك، ستضيف دالة مساعدة تسمى `calculateWinner` تأخذ مصفوفة من 9 مربعات، وتتحقق من الفائز وتعيد `'X'`، `'O'`، أو `null` حسب الاقتضاء. لا تقلق كثيرًا بشأن دالة `calculateWinner` ليست شيئًا خاصًا بـ React. إنها مجرد JavaScript. +الآن بما أن اللاعبين يمكنهم التناوب، ستريد أن تظهر شيئا عندما يفوز لاعب وعند عدم وجود المزيد من المحاولات للعب. للقيام بذلك، ستضيف دالة مساعدة تسمى `calculateWinner` تأخذ مصفوفة من 9 مربعات، وتتحقق من الفائز وتعيد `'X'`، `'O'`، أو `null` حسب الحاجة. لا تقلق كثيرًا بشأن دالة `calculateWinner` ليست شيئًا خاصًا بـ React. إنها مجرد JavaScript. ```js App.js export default function Board() { @@ -1576,7 +1576,7 @@ function calculateWinner(squares) { -لا يهم ما إذا أعلنت عن `calculateWinner` قبل أو بعد `Board`. دعنا نضعها في النهاية حتى لا تضطر إلى التمرير فوقها في كل مرة تقوم فيها بتحرير مكوناتك. +لا يهم ما إذا أعلنت عن `calculateWinner` قبل أو بعد `Board`. دعنا نضعها في النهاية حتى لا تضطر إلى التمرير عليها في كل مرة تقوم فيها بتحرير مكوناتك. @@ -1592,7 +1592,7 @@ function handleClick(i) { } ``` -لإعلام اللاعبين عندما تنتهي اللعبة، يمكنك عرض نص مثل "الفائز: X" أو "الفائز: O". للقيام بذلك، ستضيف قسم `status` إلى مكون `Board`. سيعرض `status` الفائز إذا انتهت اللعبة وإذا كانت اللعبة قائمة ستعرض أي لاعب هو الأول: +لإعلام اللاعبين عندما تنتهي اللعبة، يمكنك عرض نص مثل "الفائز: X" أو "الفائز: O". للقيام بذلك، ستضيف قسم `status` إلى مكون `Board`. سيعرض `status` الفائز إذا انتهت اللعبة، وإذا كانت اللعبة لا تزال قائمة ستعرض أي لاعب عليه الدور في اللعب: ```js {3-9,13} export default function Board() { From b60394afb1c4a7ea4adcaef20f8eefc5eda4f66c Mon Sep 17 00:00:00 2001 From: Ahmed Abdelbaset Date: Thu, 8 Jun 2023 20:32:09 +0300 Subject: [PATCH 30/34] 2050 --- src/content/learn/tutorial-tic-tac-toe.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/content/learn/tutorial-tic-tac-toe.md b/src/content/learn/tutorial-tic-tac-toe.md index 1d7e2eff9..c36e83b38 100644 --- a/src/content/learn/tutorial-tic-tac-toe.md +++ b/src/content/learn/tutorial-tic-tac-toe.md @@ -1754,9 +1754,9 @@ body { إذا قمت بتغيير `squares` array، فإن تنفيذ السفر عبر الزمن سيكون صعبًا جدًا. -ومع ذلك لقد استخدمنا `slice()` لإنشاء نسخة جديدة من `squares` array بعد كل خطوة، وعاملناها على أنها لا تتغير. هذا سيسمح لك بتخزين كل نسخة سابقة من `squares` array، والتنقل بين الدورات التي حدثت بالفعل. +ومع ذلك لقد استخدمنا `slice()` لإنشاء نسخة جديدة من مصفوفة `squares` array بعد كل خطوة، وعاملناها على أنها لا تتغير. هذا سيسمح لك بتخزين كل نسخة سابقة من مصفوفة `squares` array، والتنقل بين اللعبات التي حدثت بالفعل. -ستخزن الدورات السابقة لـ `squares` في مصفوفة أخرى تسمى `history`، والتي ستخزنها كمتغير حالة جديد. تمثل مصفوفة `history` جميع حالات اللوحة، من الخطوة الأولى إلى الخطوة الأخيرة، ولها شكل مثل هذا: +ستخزن اللعبات السابقة لـ `squares` في مصفوفة أخرى تسمى `history`، والتي ستخزنها كمتغير حالة جديد. تمثل مصفوفة `history` جميع حالات اللوحة، من الخطوة الأولى إلى الخطوة الأخيرة، ولها شكل مثل هذا: ```jsx [ @@ -1774,9 +1774,9 @@ body { ستنشئ الآن مكونًا جديدًا على المستوى الأعلى يسمى `Game` لعرض قائمة بالخطوات السابقة. هنا ستضع حالة `history` التي تحتوي على تاريخ اللعبة بأكمله. -نقل `history` إلى مكون `Game` سيسمح لك بإزالة حالة `squares` من مكون `Board` الفرعي. تمامًا مثلما "رفعت الحالة لأعلى" من مكون `Square` إلى مكون `Board`، سترفعها الآن من `Board` إلى مكون `Game` على المستوى الأعلى. هذا يمنح مكون `Game` السيطرة الكاملة على بيانات `Board` ويتيح له تعليم `Board` بتقديم الدورات السابقة من `history`. +نقل `history` إلى مكون `Game` سيسمح لك بإزالة حالة `squares` من مكون `Board` الفرعي. تمامًا مثلما "رفعت الحالة لأعلى" من مكون `Square` إلى مكون `Board`، سترفعها الآن من `Board` إلى مكون `Game` على المستوى الأعلى. هذا يمنح مكون `Game` السيطرة الكاملة على بيانات `Board` ويتيح له `Board` تقديم اللعبات السابقة من `history`. -أولًا، أضف `export default` إلى مكون `Game`. ثم اجعله يقوم بتقديم مكون `Board` وبعض البناء (markup) الإضافي: +أولًا، أضف `export default` إلى مكون `Game`. ثم اجعله يقوم بتقديم مكون `Board` وبعض الترميز (markup) الإضافي: ```js {1,5-16} function Board() { @@ -1797,7 +1797,7 @@ export default function Game() { } ``` -تذكر أن تزيل `export default` قبل الإعلان عن `function Board() {...}` وتضيفها قبل الإعلان عن `function Game() {...}`. هذا يخبر ملف `index.js` بأن يستخدم مكون `Game` كمكون رئيسي بدلاً من مكون `Board` الخاص بك. الـ `div` الإضافية التي تعود بها مكون `Game` تقوم بإنشاء مساحة لمعلومات اللعبة التي ستضيفها إلى اللوحة لاحقًا. +تذكر أن تزيل `export default` قبل الإعلان عن `function Board() {...}` وتضيفها قبل الإعلان عن `function Game() {...}`. هذا يخبر ملف `index.js` بأن يستخدم مكون `Game` كمكون رئيسي بدلاً من مكون `Board` الخاص بك. الـ `div` الإضافية التي يرجعها مكون `Game` تقوم بإنشاء مساحة لمعلومات اللعبة التي ستضيفها إلى اللوحة لاحقًا. أضف بعض الحالة إلى مكون `Game` لتتبع اللاعب التالي وتاريخ الخطوات: @@ -1848,7 +1848,7 @@ export default function Game() { } ``` -لنجعل مكون `Board` متحكمًّا به بالكامل من خلال الخصائص التي يستقبلها، غيِّر مكون `Board` ليأخذ ثلاث خصائص: `xIsNext` و `squares` ودالة `onPlay` جديدة يمكن لـ `Board` استدعاؤها مع مصفوفة المربعات المُحدَّثة عندما يقوم اللاعب باللعب. ثم، احذف السطرين الأولين من دالة `Board` التي تستدعيان `useState`: +لنجعل مكون `Board` متحكمًّا به بالكامل من خلال الخصائص التي يستقبلها، عدّل مكون `Board` ليأخذ ثلاث خصائص: `xIsNext` و `squares` ودالة `onPlay` جديدة يمكن لـ `Board` استدعاؤها مع مصفوفة المربعات المُحدَّثة عندما يلعب اللاعب. ثم، احذف السطرين الأولين من دالة `Board` التي تستدعيان `useState`: ```js {1} function Board({ xIsNext, squares, onPlay }) { @@ -1883,7 +1883,7 @@ function Board({ xIsNext, squares, onPlay }) { ماذا يجب أن تفعل `handlePlay` عند استدعائها؟ تذكر أن مكون `Board` كان يستدعي `setSquares` مع مصفوفة مُحدَّثة؛ الآن يمرر مصفوفة `squares` المُحدَّثة إلى `onPlay`. -دالة `handlePlay` تحتاج لتعديل حالة `Game` لتشغيل إعادة التقديم (Re-rendering)، لكن ليس لديك دالة `setSquares` يمكنك استدعاؤها بعد الآن - أنت تستخدم الآن متغير الحالة `history` لتخزين هذه المعلومات. ستريد تحديث `history` عن طريق إضافة مصفوفة `squares` المُحدَّثة كإدخال جديد في `history`. كما تريد تبديل `xIsNext`، تمامًا كما كان يفعل `Board`: +دالة `handlePlay` تحتاج لتعديل حالة `Game` لتشغيل إعادة التصيير (Re-rendering)، لكن ليس لديك دالة `setSquares` يمكنك استدعاؤها بعد الآن - أنت تستخدم الآن متغير الحالة `history` لتخزين هذه المعلومات. ستحتاج تحديث `history` عن طريق إضافة مصفوفة `squares` المُحدَّثة كإدخال جديد في `history`. كما تحتاج تبديل `xIsNext`، تمامًا كما كان يفعل `Board`: ```js {4-5} export default function Game() { @@ -1896,7 +1896,7 @@ export default function Game() { } ``` -هنا، `[...history, nextSquares]` تنشئ مصفوفة جديدة تحتوي على جميع العناصر في `history`، تليها `nextSquares`. (يمكنك قراءة `...history` [*بناء الجملة*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax) كـ "جميع العناصر في `history`".) +هنا، `[...history, nextSquares]` تنشئ مصفوفة جديدة تحتوي على جميع العناصر في `history`، تليها `nextSquares`. (يمكنك قراءة `...history` [*Spread Operator*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax) كـ "جميع العناصر في `history`".) علي سبيل المثال، إذا كانت `history` هي `[[null,null,null], ["X",null,null]]` وكان `nextSquares` هو `["X",null,"O"]`، فإن المصفوفة الجديدة `[...history, nextSquares]` ستكون `[[null,null,null], ["X",null,null], ["X",null,"O"]]`. From d149f0f43f170f702f1a0bd2f46937e82ae05ad0 Mon Sep 17 00:00:00 2001 From: Ahmed Abdelbaset Date: Wed, 14 Jun 2023 19:47:50 +0300 Subject: [PATCH 31/34] 2330 --- src/content/learn/tutorial-tic-tac-toe.md | 26 +++++++++++------------ 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/content/learn/tutorial-tic-tac-toe.md b/src/content/learn/tutorial-tic-tac-toe.md index c36e83b38..1c47dd2e4 100644 --- a/src/content/learn/tutorial-tic-tac-toe.md +++ b/src/content/learn/tutorial-tic-tac-toe.md @@ -2052,17 +2052,17 @@ body { ### عرض الخطوات السابقة {/*showing-the-past-moves*/} -منذ أن تتبعت تاريخ اللعبة ، يمكنك الآن عرض قائمة بالخطوات السابقة للاعب. +لأنك تتبعت تاريخ اللعبة، يمكنك الآن عرض قائمة بالخطوات السابقة للاعب. -عناصر React مثل `