diff --git a/content/tutorial/tutorial.md b/content/tutorial/tutorial.md
index 57b5e39f4..e0a976a74 100644
--- a/content/tutorial/tutorial.md
+++ b/content/tutorial/tutorial.md
@@ -1,6 +1,6 @@
---
id: tutorial
-title: "Tutorial: Intro to React"
+title: "الدليل التطبيقي: مدخل إلى React"
layout: tutorial
sectionid: tutorial
permalink: tutorial/tutorial.html
@@ -12,97 +12,95 @@ redirect_from:
- "docs/tutorial-zh-CN.html"
---
-This tutorial doesn't assume any existing React knowledge.
+لا يفترض هذا الدليل أي معرفة مسبقة بمكتبة React.
-## Before We Start the Tutorial {#before-we-start-the-tutorial}
+## قبل أن نبدأ بالدليل التطبيقي {#before-we-start-the-tutorial}
-We will build a small game during this tutorial. **You might be tempted to skip it because you're not building games -- but give it a chance.** The techniques you'll learn in the tutorial are fundamental to building any React app, and mastering it will give you a deep understanding of React.
+سنبني لعبة صغيرة خلال هذا الدليل التطبيقي. **ربّما قد ترغب بتخطي هذا الدليل لأنّك لا تريد بناء الألعاب، ولكن أعطيها فرصة.** إنّ التقنيات التي ستتعلمها في هذا الدليل أساسيّة لبناء أي تطبيق React، وسيعطيك إتقانها فهمًا أعمق لمكتبة React.
->Tip
+>نصيحة
>
->This tutorial is designed for people who prefer to **learn by doing**. If you prefer learning concepts from the ground up, check out our [step-by-step guide](/docs/hello-world.html). You might find this tutorial and the guide complementary to each other.
+>هذا الدليل مُصمَّم للأشخاص الذين يُفضّلون **التعلّم بالممارسة**. إن كنت تُفضّل تعلّم المفاهيم من البداية راجع [مستندات React من البداية خطوة بخطوة](/docs/hello-world.html). قد تجد هذا الدليل متكاملًا مع مستندات React.
-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.
-You don't have to complete all of the sections at once to get the value out of this tutorial. Try to get as far as you can -- even if it's one or two sections.
+لا يجب عليك إكمال جميع الأقسام دفعة واحدة للحصول على الفائدة المرجوة من هذا الدليل. حاول الذهاب أبعد ما يمكن حتى ولو كان قسمًا أو قسمين.
-### What Are We Building? {#what-are-we-building}
+لا بأس من نسخ ولصق الشيفرة عند متابعتك مع هذا الدليل، ولكن نوصي أن تكتبها بيدك. سيُساعدك ذلك بتطوير ذاكرتك وبإعطائك فهمًا أعمق لمكتبة React.
-In this tutorial, we'll show how to build an interactive tic-tac-toe game with React.
+###ماذا سنبني؟ {#what-are-we-building}
-You can see what we'll be building here: **[Final Result](https://codepen.io/gaearon/pen/gWWZgR?editors=0010)**. If the code doesn't make sense to you, 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.
+سنرى في هذا الدليل كيفيّة بناء لعبة إكس-أو (اسمها بالإنجليزيّة tic-tac-toe) باستخدام React.
-We recommend that you check out the tic-tac-toe game 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 is updated as the game progresses.
+بإمكانك أن ترى **[النتيجة النهائيّة لما سنبنيه من هنا](https://codepen.io/gaearon/pen/gWWZgR?editors=0010)**. إن كانت الشيفرة غير مفهومة بالنسبة لك أو كنتَ غير متآلف مع صياغة الشيفرة، فلا تقلق! فالهدف من هذا الدليل هو مساعدتك على فهم React وصياغتها.
-You can close the tic-tac-toe game once you're familiar with it. We'll be starting from a simpler template in this tutorial. Our next step is to set you up so that you can start building the game.
+نوصي بأن تلقي نظرة على لعبة إكس-أو قبل المتابعة. إحدى الميزات التي ستلاحظها وجود قائمة مُرقّمة على يمين لوحة اللعبة. تُعطيك هذه القائمة سجلًّا عن كل التحركات التي حصلت في اللعبة، وتُحدَّث بينما تستمر اللعبة.
-### Prerequisites {#prerequisites}
+تستطيع إغلاق لعبة إكس-أو بعدما تتآلف معها. سننطلق من قالب بسيط في هذا الدليل. خطوتنا التالية هي إتمام الإعداد لكي تستطيع البدء ببناء اللعبة.
-We'll assume that you have some familiarity with HTML and JavaScript, but you should be able to follow along even if you're coming from a different programming language. We'll also assume that you're familiar with programming concepts like functions, objects, arrays, and to a lesser extent, classes.
+### المتطلّبات الأساسيّة {#prerequisites}
-If you need to review JavaScript, we recommend reading [this guide](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript). Note that we're also using some features from ES6 -- a recent version of JavaScript. In this tutorial, we're using [arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions), [classes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes), [`let`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let), and [`const`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const) statements. You can use the [Babel REPL](babel://es5-syntax-example) to check what ES6 code compiles to.
+سنفترض أنّك متآلف مع HTML و JavaScript، ولكن يجب أن تكون قادرًا على المتابعة حتى ولو كنت قادمًا من لغة برمجة أخرى. سنفترض أنّك متآلف مع المفاهيم البرمجيّة مثل الدوال، والكائنات، والمصفوفات، وبدرجة أقل الأصناف.
-## Setup for the Tutorial {#setup-for-the-tutorial}
+إن احتجت لمراجعة JavaScript نوصيك بالرجوع إلى [مستندات JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript) في موسوعة حسوب. لاحظ أنّنا نستخدم بعض الميزات من ES6، وهي إصدار جديد من JavaScript. سنستخدم في هذا الدليل [الدوال السهمية](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)، [الأصناف](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes)، والتصريحين [`let`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let) و [`const`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const). بإمكانك استخدام [Babel REPL](babel://es5-syntax-example) لتتحقّق إلى ماذا تُصرَّف شيفرة ES6.
-There are two ways to complete this tutorial: you can either write the code in your browser, or you can set up a local development environment on your computer.
+## الإعداد من أجل الدليل {#setup-for-the-tutorial}
-### Setup Option 1: Write Code in the Browser {#setup-option-1-write-code-in-the-browser}
+هناك طريقتان لإكمال هذا الدليل، بإمكانك إمّا كتابة الشيفرة في متصفحك، أو إعداد بيئة تطوير محلية على حاسوبك.
-This is the quickest way to get started!
+### الخيار الأول للإعداد: كتابة الشيفرة في المتصفح {#setup-option-1-write-code-in-the-browser}
-First, open this **[Starter Code](https://codepen.io/gaearon/pen/oWWQNa?editors=0010)** in a new tab. The new tab should display an empty tic-tac-toe game board and React code. We will be editing the React code in this tutorial.
+هذه أسرع طريقة للبدء.
-You can now skip the second setup option, and go to the [Overview](#overview) section to get an overview of React.
+في البداية افتح **[هذه الشيفرة المبدئيّة](https://codepen.io/gaearon/pen/oWWQNa?editors=0010)** في نافذة جديدة. يجب أن تعرض النافذة الجديدة لوحة لعبة إكس-أو وشيفرة React. سنُعدِّل شيفرة React في هذا الدليل.
-### Setup Option 2: Local Development Environment {#setup-option-2-local-development-environment}
+بإمكانك الآن تجاوز الخيار الثاني للإعداد والذهاب إلى قسم [لمحة عامّة](#overview) للحصول على لمحة عامّة عن React.
-This is completely optional and not required for this tutorial!
+### الخيار الثاني للإعداد: بيئة التطوير المحليّة {#setup-option-2-local-development-environment}
+
+هذا الخيار اختياري وغير مطلوب من أجل هذا الدليل.
-Optional: Instructions for following along locally using your preferred text editor
+اختياري: تعليمات للمتابعة بشكل محلي باستخدام مُحرِّر النصوص المفضّل لديك
-This setup requires more work but allows you to complete the tutorial using an editor of your choice. Here are the steps to follow:
+يتطلّب هذا الإعداد المزيد من العمل ولكنّه يسمح لك بمتابعة هذا الدليل باستخدام مُحرِّر نصوص من اختيارك. هذه هي الخطوات التي يجب عليك اتباعها:
-1. Make sure you have a recent version of [Node.js](https://nodejs.org/en/) installed.
-2. Follow the [installation instructions for Create React App](/docs/create-a-new-react-app.html#create-react-app) to make a new project.
+1. تأكّد من امتلاكك لأحدث إصدار من [Node.js](https://nodejs.org/en/).
+2. اتبع [تعليمات التثبيت لإنشاء تطبيق React](/docs/create-a-new-react-app.html#create-react-app) لصنع مشروع جديد
```bash
npx create-react-app my-app
```
-3. Delete all files in the `src/` folder of the new project
-
-> Note:
->
->**Don't delete the entire `src` folder, just the original source files inside it.** We'll replace the default source files with examples for this project in the next step.
+1. احذف كافة الملفات الموجودة في المجلّد src/ للمشروع الجديد (لا تحذف هذا المجلّد، فقط محتوياته).
```bash
cd my-app
cd src
-# If you're using a Mac or Linux:
+# إن كنت تستخدم نظام ماك او لينكس
rm -f *
-# Or, if you're on Windows:
+# أو، إن كنت تستخدم نظام ويندوز
del *
-# Then, switch back to the project folder
+# ثم، عد إلى مجلد المشروع
cd ..
```
-4. Add a file named `index.css` in the `src/` folder with [this CSS code](https://codepen.io/gaearon/pen/oWWQNa?editors=0100).
+1. أضف ملفًّا يُدعى `index.css` في المجلّد `src/` مع [وضع شيفرة CSS هذه ضمنه](https://codepen.io/gaearon/pen/oWWQNa?editors=0100).
-5. Add a file named `index.js` in the `src/` folder with [this JS code](https://codepen.io/gaearon/pen/oWWQNa?editors=0010).
+2. أضف ملفًّا يُدعى `index.js` في المجلّد `src/` مع [ضع شيفرة JavaScript هذه ضمنه](https://codepen.io/gaearon/pen/oWWQNa?editors=0010).
-6. Add these three lines to the top of `index.js` in the `src/` folder:
+3. أضف هذه الأسطر الثلاثة إلى بداية الملف `index.js` في المجلّد `src/`:
```js
import React from 'react';
@@ -110,32 +108,32 @@ import ReactDOM from 'react-dom';
import './index.css';
```
-Now if you run `npm start` in the project folder and open `http://localhost:3000` in the browser, you should see an empty tic-tac-toe field.
+إن نفّذت الآن الأمر `npm start` في مجلّد المشروع وفتحت الرابط `http://localhost:3000` في المتصفّح، فبإمكانك أن ترى حقل فارغ للعبة إكس-أو.
-We recommend following [these instructions](https://babeljs.io/docs/editors/) to configure syntax highlighting for your editor.
+نوصي بمتابعة [هذه التعليمات](https://babeljs.io/docs/editors/) لإعداد ميّزة تعليم الصياغة (syntax highlighting) في مُحرِّر النصوص لديك.
-### Help, I'm Stuck! {#help-im-stuck}
+### ساعدني، أنا عالق! {#help-im-stuck}
-If you get stuck, check out the [community support resources](/community/support.html). In particular, [Reactiflux Chat](https://discord.gg/0ZcbPKXt5bZjGY5n) is a great way to get help quickly. If you don't receive an answer, or if you remain stuck, please file an issue, and we'll help you out.
+إن وجدت أيّة صعوبات، تحقّق من [مصادر مجتمع React](/community/support.html)، بالأخص [دردشة Reactiflux](https://discord.gg/0ZcbPKXt5bZjGY5n) هي طريقة رائعة للحصول على المساعدة بسرعة. إن لم تتلقى أي إجابة أو بقيت عالقًا عند مشكلة ما، يُرجى تقديم المشكلة وسنساعدك في حلّها.
-## Overview {#overview}
+## لمحة عامّة {#overview}
-Now that you're set up, let's get an overview of React!
+الآن بعد أن قمت بالإعداد ، دعنا نلقي نظرة عامة على React!
-### What Is React? {#what-is-react}
+### ما هي React؟ {#what-is-react}
-React is a declarative, efficient, and flexible JavaScript library for building user interfaces. It lets you compose complex UIs from small and isolated pieces of code called "components".
+React هي مكتبة JavaScript مرنة، وفعّالة، وتصريحيّة لبناء واجهات المستخدم. تُتيح لك تركيب واجهات مستخدم مُعقّدة من قطع معزولة وصغيرة من الشيفرة تُدعى المكوّنات "components".
-React has a few different kinds of components, but we'll start with `React.Component` subclasses:
+تمتلك React أنواع مختلفة من المكوّنات، ولكن سنبدأ بالمكوّنات التي هي أصناف فرعية من الصنف `React.Component`:
```javascript
class ShoppingList extends React.Component {
render() {
return (
-
Shopping List for {this.props.name}
+
قائمة تسوق لأجل {this.props.name}
Instagram
WhatsApp
@@ -146,14 +144,14 @@ class ShoppingList extends React.Component {
}
}
-// Example usage:
+// مثال عن استخدام المكون
```
-We'll get to the funny XML-like tags soon. We use components to tell React what we want to see on the screen. When our data changes, React will efficiently update and re-render our components.
+سنتحدّث قريبًا عن هذه العناصر التي تشبه عناصر XML. نستخدم المكوّنات لنخبر React ما الذي نرغب برؤيته على الشاشة. عندما تتغيّر بياناتنا ستُحدِّث React بكفاءة وتُعيد تصيير مكوّناتنا.
-Here, ShoppingList is a **React component class**, or **React component type**. A component takes in parameters, called `props` (short for "properties"), and returns a hierarchy of views to display via the `render` method.
+في المثال السابق ShoppingList هي **مكوّن React على شكل صنف**، وهي **من نوع المكوّنات في React**. يأخذ المكوّن مُعامِلات تُدعى الخاصيّات `props` (اختصارًا للكلمة "properties")، وتُعيد تسلسل هيكلي من المشاهد التي يجب عرضها عبر التابع `render`.
-The `render` method returns a *description* of what you want to see on the screen. React takes the description and displays the result. In particular, `render` returns a **React element**, which is a lightweight description of what to render. Most React developers use a special syntax called "JSX" which makes these structures easier to write. The `
` syntax is transformed at build time to `React.createElement('div')`. The example above is equivalent to:
+يُعيد تابع التصيير `render` وصفًا لما ترغب برؤيته على الشاشة. تأخذ React الوصف وتعرض النتيجة. يُعيد التابع `render` بشكلٍ خاص **عنصر React**، والذي هو وصف بسيط لما ترغب بتصييره. يستخدم معظم مطوري React صياغة خاصّة تُدعى "JSX" والتي تُسهِّل عمليّة كتابة مثل هذه البُنى. فمثلًا تُحوَّل الصياغة `
` في زمن البناء إلى `React.createElement('div')`. يُكافِئ المثال السابق ما يلي:
```javascript
return React.createElement('div', {className: 'shopping-list'},
@@ -162,35 +160,33 @@ return React.createElement('div', {className: 'shopping-list'},
);
```
-[See full expanded version.](babel://tutorial-expanded-version)
+[انظر إلى الإصدار الكامل الموسّع من هذا المثال.](babel://tutorial-expanded-version)
-If you're curious, `createElement()` is described in more detail in the [API reference](/docs/react-api.html#createelement), but we won't be using it in this tutorial. Instead, we will keep using JSX.
+إن كنت فضوليًّا فالتابع `createElement()` مشروح بالتفصيل في [مرجع واجهة برمجة التطبيق](/docs/react-api.html#createelement) في React، ولكنّنا لن نستخدمه في هذا الدليل، بل سنستمر في استخدام JSX بدلًا من ذلك.
-JSX comes with the full power of JavaScript. You can put *any* JavaScript expressions within braces inside JSX. Each React element is a JavaScript object that you can store in a variable or pass around in your program.
+تأتي JSX مع القوة الكاملة للغة JavaScript. بإمكانك وضع **أي** تعابير JavaScript ضمن الأقواس بداخل JSX. كل عنصر React هو كائن JavaScript تستطيع تخزينه في متغيّر أو تمريره ضمن برنامجك.
-The `ShoppingList` component above only renders built-in DOM components like `
` and ` `. But you can compose and render custom React components too. For example, we can now refer to the whole shopping list by writing ` `. Each React component is encapsulated and can operate independently; this allows you to build complex UIs from simple components.
+يُصيِّر المكوّن `ShoppingList` المذكور في الأعلى مكوّنات مُضمَّنة في DOM مثل `
` و ` `، ولكن تستطيع تركيب وتصيير مكوّنات React مُخصَّصة أيضًا. على سبيل المثال تستطيع الآن الإشارة إلى كامل قائمة التسوّق عن طريقة كتابة ` `. يكون كل مكوّن React مُغلّفًا وبإمكانه العمل بشكل مستقل. يسمح لك ذلك ببناء واجهات مستخدم مُعقّدة من مكوّنات بسيطة.
-## Inspecting the Starter Code {#inspecting-the-starter-code}
+## تفحّص شيفرة البدء {#inspecting-the-starter-code}
-If you're going to work on the tutorial **in your browser,** open this code in a new tab: **[Starter Code](https://codepen.io/gaearon/pen/oWWQNa?editors=0010)**. If you're going to work on the tutorial **locally,** instead open `src/index.js` in your project folder (you have already touched this file during the [setup](#setup-option-2-local-development-environment)).
+إن كنت ستجرّب شيفرة الدليل التطبيقي **على متصفحك،** افتح **[شيفرة البدء](https://codepen.io/gaearon/pen/oWWQNa?editors=0010)** في نافذة جديدة. أمّا إن كنت ستجرّبها بشكل **محلّي،** فافتح الملف `src/index.js` الموجود في مجلّد مشروعك (لقد تعرّفت مسبقًا على هذا الملف خلال [خطوة الإعداد](#setup-option-2-local-development-environment)).
-This Starter Code is the base of what we're building. We've provided the CSS styling so that you only need to focus on learning React and programming the tic-tac-toe game.
+شيفرة البدء هذه هي الأساس لما نبنيه. زوّدناك بتنسيق CSS لكي تحتاج للتركيز فقط على تعلّم React وبرمجة لعبة إكس-أو.
-By inspecting the code, you'll notice that we have three React components:
+ستلاحظ بتفحّص الشيفرة أنّنا نمتلك ثلاثة مكوّنات:
-* Square
-* Board
-* Game
+* مكوّن المربّع `Square`
+* مكوّن لوحة اللعبة `Board`
+* مكوّن اللعبة `Game`
-The Square component renders a single `` and the Board renders 9 squares. The Game component renders a board with placeholder values which we'll modify later. There are currently no interactive components.
+يُصيِّر المكوّن `Square` عنصر زر `` واحد، ويُصيِّر المكوّن `Board` تسعة مربّعات. يُصيِّر المكوّن `Game` لوحة مع وجود قيم للتلميح والتي سنُعدّلها لاحقًا. لا يوجد حتى الآن أي مكوّن تفاعلي.
-### Passing Data Through Props {#passing-data-through-props}
+### تمرير البيانات عبر الخاصيّات {#passing-data-through-props}
-To get our feet wet, let's try passing some data from our Board component to our Square component.
+لتدريب أنفسنا فلنحاول تمرير بعض البيانات من المكوّن `Board` إلى المكوّن `Square`.
-We strongly recommend typing code by hand as you're working through the tutorial and not using copy/paste. This will help you develop muscle memory and a stronger understanding.
-
-In Board's `renderSquare` method, change the code to pass a prop called `value` to the Square:
+في التابع `renderSquare` الموجود في المكوّن `Board`، غيّر الشيفرة لتمرير خاصيّة تُدعى `value` إلى المكوّن `Square`:
```js{3}
class Board extends React.Component {
@@ -199,7 +195,7 @@ class Board extends React.Component {
}
```
-Change Square's `render` method to show that value by replacing `{/* TODO */}` with `{this.props.value}`:
+غيّر التابع `render` في المكوّن Square لإظهار القيم عن طريق وضع `{this.props.value}` بدلًا من `{/* TODO */}`:
```js{5}
class Square extends React.Component {
@@ -213,28 +209,27 @@ class Square extends React.Component {
}
```
-Before:
+قبل التغييرات:
![React Devtools](../images/tutorial/tictac-empty.png)
-After: You should see a number in each square in the rendered output.
+بعد التغييرات: يجب أن ترى عددًا في كل مربّع من الناتج المُصيَّر:
![React Devtools](../images/tutorial/tictac-numbers.png)
-**[View the full code at this point](https://codepen.io/gaearon/pen/aWWQOG?editors=0010)**
+**[انظر إلى كامل الشيفرة عند هذه النقطة.](https://codepen.io/gaearon/pen/aWWQOG?editors=0010)**
-Congratulations! You've just "passed a prop" from a parent Board component to a child Square component. Passing props is how information flows in React apps, from parents to children.
+تهانينا! لقد "مرّرت الآن خاصيّة `prop`" من المكوّن `Board` الأب إلى المكوّن `Square` الابن. تمرير الخاصيّات هو طريقة عبور المعلومات في تطبيقات React، من المكوّنات الآباء إلى المكوّنات الأبناء.
-### Making an Interactive Component {#making-an-interactive-component}
+### صنع مكوّن تفاعلي{#making-an-interactive-component}
-Let's fill the Square component with an "X" when we click it.
-First, change the button tag that is returned from the Square component's `render()` function to this:
+فلنملأ المكوّن `Square` بإشارة "X" عند النقر عليه. فلنغيّر أولًا العنصر `button` الذي يُعاد من تابع التصيير الخاص بالمكوّن `Square` إلى ما يلي:
```javascript{4}
class Square extends React.Component {
render() {
return (
-
+
{this.props.value}
);
@@ -242,17 +237,17 @@ class Square extends React.Component {
}
```
-If you click on a Square now, you should see an alert in your browser.
+إن قمت بالنقر على المربّع فينبغي ظهور تحذير في المتصفح.
->Note
+>ملاحظة:
>
->To save typing and avoid the [confusing behavior of `this`](https://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/), we will use the [arrow function syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) for event handlers here and further below:
+>لتقليل الكتابة وتجنّب [ السلوك المُربِك للكلمة المفتاحية `this`](https://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/)، سنستخدم صياغة [الدوال السهمية](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) من أجل مُعالِجات الأحداث هنا وحتى في باقي أجزاء الشيفرة:
>
>```javascript{4}
>class Square extends React.Component {
> render() {
> return (
-> alert('click')}>
+> alert('نقرة')}>
> {this.props.value}
>
> );
@@ -260,13 +255,13 @@ If you click on a Square now, you should see an alert in your browser.
>}
>```
>
->Notice how with `onClick={() => alert('click')}`, we're passing *a function* as the `onClick` prop. React will only call this function after a click. Forgetting `() =>` and writing `onClick={alert('click')}` is a common mistake, and would fire the alert every time the component re-renders.
+>لاحظ كيف في الشيفرة `onClick={() => alert('نقرة')}` نقوم بتمرير *دالة* إلى الخاصيّة `onClick`. وهي تُطلَق فقط عند النقر. من الشائع نسيان `() =>` وكتابة `onClick={alert('نقرة')}`، والذي يُؤدّي إلى إطلاق التحذير في كل مرّة يُعاد فيها تصيير المكوّن.
-As a next step, we 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`. لتذكر الأشياء تستخدم المكوّنات الحالة **state**.
-React components can have state by setting `this.state` in their constructors. `this.state` should be considered as private to a React component that it's defined in. Let's store the current value of the Square in `this.state`, and change it when the Square is clicked.
+تستطيع مكوّنات React أن تمتلك حالة عن طريق تعيين `this.state` في الدالة البانية لها. يجب اعتبار `this.state` خاصّة (private) بالنسبة لمكوّن React المُعرَّفة ضمنه. فلنُخزِّن القيمة الحاليّة للمربّع في `this.state` ونُغيّرها عند النقر عليه.
-First, we'll add a constructor to the class to initialize the state:
+سنضيف في البداية دالة بانية إلى الصنف لتهيئة الحالة:
```javascript{2-7}
class Square extends React.Component {
@@ -279,7 +274,7 @@ class Square extends React.Component {
render() {
return (
- alert('click')}>
+ alert('نقرة')}>
{this.props.value}
);
@@ -287,17 +282,17 @@ class Square extends React.Component {
}
```
->Note
+>ملاحظة:
>
->In [JavaScript classes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes), you need to always call `super` when defining the constructor of a subclass. All React component classes that have a `constructor` should start it with a `super(props)` call.
+>يجب عليك دومًا في [أصناف JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes) أن تستدعي الكلمة `super` عند تعريف الدالة البانية للصنف الفرعي. يجب أن تبدأ جميع مكوّنات الأصناف في React التي تمتلك دالة بانية `constructor` باستدعاء `super(props)`.
-Now we'll change the Square's `render` method to display the current state's value when clicked:
+سنُغيّر الآن تابع التصيير `render` للمكوّن Square ليعرض قيمة الحالة الحاليّة عند النقر عليه:
-* Replace `this.props.value` with `this.state.value` inside the `` tag.
-* Replace the `onClick={...}` event handler with `onClick={() => this.setState({value: 'X'})}`.
-* Put the `className` and `onClick` props on separate lines for better readability.
+* ضع `this.state.value` بدلًا من `this.props.value` بداخل العنصر ``.
+* ضع `onClick={() => this.setState({value: 'X'})}` بدلًا من `onClick={...}`.
+* ضع الخاصيّتين `className` و `onClick` في أسطر منفصلة لسهولة القراءة.
-After these changes, the `` tag that is returned by the Square's `render` method looks like this:
+بعد هذه التغييرات سيبدو العنصر `` المُعاد من تابع التصيير للمكوّن `Square` كما يلي:
```javascript{12-13,15}
class Square extends React.Component {
@@ -321,44 +316,44 @@ class Square extends React.Component {
}
```
-By calling `this.setState` from an `onClick` handler in the Square's `render` method, we tell React to re-render that Square whenever its `` is clicked. After the update, the Square's `this.state.value` will be `'X'`, so we'll see the `X` on the game board. If you click on any Square, an `X` should show up.
+عن طريق استدعاء `this.setState` من مُعالِج الأحداث `onClick` في تابع التصيير للمكوّن Square، نُخبِر React بأن تُعيد تصيير المكوّن Square عند النقر على الزر `` الخاص به. بعد التحديث ستُصبِح قيمة `this.state.value` هي `'X'`، لذا سنرى `'X'` في لوحة اللعبة. إن نقرت على أي مربّع يجب أن تظهر الإشارة `X`.
-When you call `setState` in a component, React automatically updates the child components inside of it too.
+عندما تستدعي التابع `setState` في المكوّن، تُحدِّث React بشكل تلقائي المكوّنات الأبناء بداخله أيضًا.
-**[View the full code at this point](https://codepen.io/gaearon/pen/VbbVLg?editors=0010)**
+**[انظر إلى كامل الشيفرة عند هذه النقطة](https://codepen.io/gaearon/pen/VbbVLg?editors=0010)**
-### Developer Tools {#developer-tools}
+### أدوات المطوّر {#developer-tools}
-The React Devtools extension for [Chrome](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en) and [Firefox](https://addons.mozilla.org/en-US/firefox/addon/react-devtools/) lets you inspect a React component tree with your browser's developer tools.
+تُتيح لك إضافة أدوات تطوير React من أجل متصفّح [Chrome](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en) و [Firefox](https://addons.mozilla.org/en-US/firefox/addon/react-devtools/) أن تتفحّص شجرة مكوّنات React باستخدام أدوات تطوير المتصفّح.
-The React DevTools let you check the props and the state of your React components.
+تُتيح لك أدوات تطوير React التحقّق من خاصيّات وحالة المكوّنات.
-After installing React DevTools, you can right-click on any element on the page, click "Inspect" to open the developer tools, and the React tab will appear as the last tab to the right.
+تستطيع بعد تثبيت أدوات تطوير React أن تنقر بالزر الأيمن على أي عنصر في الصفحة، ثمّ تضغط على كلمة "Inspect" لفتح أدوات المطوّر، وستظهر نافذة React كآخر نافذة إلى اليمين.
-**However, note there are a few extra steps to get it working with CodePen:**
+**لاحظ وجود بعض الخطوات الإضافيّة لكي تعمل الأدوات مع CodePen:**
-1. Log in or register and confirm your email (required to prevent spam).
-2. Click the "Fork" button.
-3. Click "Change View" and then choose "Debug mode".
-4. In the new tab that opens, the devtools should now have a React tab.
+1. سجّل الدخول إلى الموقع أو سجّل في الموقع مع تأكيد بريدك الإلكتروني (مطلوب لتجنّب البريد المزعج spam).
+2. اضغط على الزر "Fork".
+3. اضغط على "Change View" واختر بعدها "Debug mode".
+4. ستملك الآن أدوات التطوير نافذة React ضمن النافذة الجديدة التي ستفتح.
-## Completing the Game {#completing-the-game}
+## إكمال اللعبة {#completing-the-game}
-We now have the basic building blocks for our tic-tac-toe game. To have a complete game, we now need to alternate placing "X"s and "O"s on the board, and we need a way to determine a winner.
+لدينا الآن أساسات البناء للعبة إكس-أو. للحصول على لعبة كاملة سنحتاج الآن إلى وضع إشارات "X" و "O" على لوحة اللعبة، وإلى إيجاد طريقة لتحديد الفائز.
-### Lifting State Up {#lifting-state-up}
+### رفع الحالة للمستوى الأعلى {#lifting-state-up}
-Currently, each Square component maintains the game's state. To check for a winner, we'll maintain the value of each of the 9 squares in one location.
+يحتفظ حاليًّا كل مكوّن مربّع `Square` بحالة اللعبة. لتحديد الفائز يجب علينا إبقاء قيمة كل مربّع من المربّعات التسعة في مكان واحد.
-We may think that Board should just ask each Square for the Square's state. Although this approach is possible in React, we discourage it because the code becomes difficult to understand, susceptible to bugs, and hard to refactor. Instead, the best approach is to store the game's state in the parent Board component instead of in each Square. The Board component can tell each Square what to display by passing a prop, [just like we did when we passed a number to each Square](#passing-data-through-props).
+قد تعتقد أنّه من الأفضل أن يسأل مكوّن لوحة اللعبة `Board` كل مكوّن مربّع `Square` عن حالته. على الرغم من أنّ هذه الطريقة ممكنة في React ولكنّنا لا نفضّلها لأنّ الشيفرة ستصبح صعبة الفهم، وقابلة لوجود أخطاء فيها، ومن الصعب إعادة استخدامها. أفضل طريقة هي تخزين حالة اللعبة في مكوّن لوحة اللعبة `Board` واعتباره مكوّن أب بدلًا من تخزينها في كل مربّع. يتمكّن المكوّن `Board` من إخبار كل مربّع بما يجب عرضه عن طريق تمرير خاصيّة `prop`،[كما فعلنا عندما مرّرنا عددًا لكل مربّع](#passing-data-through-props).
-**To collect data from multiple children, or to have two child components communicate with each other, you need to declare the shared state in their parent component instead. The parent component can pass the state back down to the children by using props; this keeps the child components in sync with each other and with the parent component.**
+**لتجميع البيانات من المكوّنات الأبناء المتعددة، ولامتلاك مكوّنين أبناء يتواصلان مع بعضهما البعض، يجب التصريح عن الحالة المشتركة في المكوّن الأب لها. يستطيع المكوّن الأب تمرير الحالة إلى المكوّنات الأبناء له عن طريق الخاصيّات. يُبقي هذا المكوّنات الأبناء بحالة تزامن مع بعضها ومع المكوّن الأب.**
-Lifting state into a parent component is common when React components are refactored -- let's take this opportunity to try it out.
+رفع الحالة إلى المكوّن الأب هو أسلوب شائع عند إعادة تصنيع المكوّنات (refactoring).
-Add a constructor to the Board and set the Board's initial state to contain an array of 9 nulls corresponding to the 9 squares:
+سنضيف دالة بانية إلى لوحة اللعبة وسنُعيّن الحالة المبدئيّة لمكوّن اللوحة كي تحتوي على مصفوفة تتضمّن 9 قيم `null`. تتوافق هذه القيم التسعة مع المربعات التسعة الموجودة في اللعبة:
```javascript{2-7}
class Board extends React.Component {
@@ -374,7 +369,7 @@ class Board extends React.Component {
}
```
-When we fill the board in later, the `this.state.squares` array will look something like this:
+عندما نملأ لوحة اللعبة لاحقًا فستبدو كما يلي:
```javascript
[
@@ -384,7 +379,7 @@ When we fill the board in later, the `this.state.squares` array will look someth
]
```
-The Board's `renderSquare` method currently looks like this:
+يبدو حاليًّا التابع `renderSquare` الموجود في المكوّن `Board` كما يلي:
```javascript
renderSquare(i) {
@@ -392,9 +387,9 @@ The Board's `renderSquare` method currently looks like this:
}
```
-In the beginning, we [passed the `value` prop down](#passing-data-through-props) from the Board to show numbers from 0 to 8 in every Square. In a different previous step, we replaced the numbers with an "X" mark [determined by Square's own state](#making-an-interactive-component). This is why Square currently ignores the `value` prop passed to it by the Board.
+في البداية [مرّرنا الخاصيّة `value`](#passing-data-through-props) من المكوّن `Board` لإظهار الأعداد من 0 إلى 8 في كل مربّع، وفي خطوة سابقة وضعنا إشارات `X` بدلًا من الأعداد، حيث [يُحدِّد هذه الإشارة حالة المكوّن `Sqaure`](#making-an-interactive-component). ولهذا يتجاهل حاليًّا الخاصيّة `value` المُمرَّرة إليه عن طريق المكوّن `Board`.
-We will now use the prop passing mechanism again. We will modify the Board to instruct each individual Square about its current value (`'X'`, `'O'`, or `null`). We have already defined the `squares` array in the Board's constructor, and we will modify the Board's `renderSquare` method to read from it:
+سنستخدم الآن آليّة تمرير الخاصيّة مرّة أخرى. سنُعدِّل المكوّن Board ليستعلم من كل مربّع عن قيمته الحاليّة (`'X'`، أو `'O'`، أو `null`). لقد عرّفنا مسبقًا المصفوفة `squares` في الدالة البانية للمكوّن `Board`، وسنُعدِّل التابع `renderSquare` الموجود ضمنه ليقرأ من تلك المصفوفة:
```javascript{2}
renderSquare(i) {
@@ -402,13 +397,13 @@ We will now use the prop passing mechanism again. We will modify the Board to in
}
```
-**[View the full code at this point](https://codepen.io/gaearon/pen/gWWQPY?editors=0010)**
+**[انظر إلى كامل الشيفرة عند هذه النقطة](https://codepen.io/gaearon/pen/gWWQPY?editors=0010)**
-Each Square will now receive a `value` prop that will either be `'X'`, `'O'`, or `null` for empty squares.
+سيستقبل كل مربّع الآن الخاصيّة `value` والتي ستكون إمّا `'X'`، أو `'O'`، أو `null` بالنسبة للمربّعات الفارغة.
-Next, we need to change what happens when a Square is clicked. The Board component now maintains which squares are filled. We need to create a way for the Square to update the Board's state. Since state is considered to be private to a component that defines it, we cannot update the Board's state directly from Square.
+سنحتاج الآن إلى تغيير ما يحدث عند النقر على المربّع. يعرف الآن المكوّن `Board` ما هي المربّعات الممتلئة. يجب علينا إيجاد طريقة للمكوّن `Square` لكي يُحدِّث حالة المكوّن `Board`. بما أنّ الحالة تُعتبر خاصّة (private) للمكوّن الذي يُعرفها، فلن نستطيع تحديث حالة المكوّن `Board` مباشرةً من المكوّن `Square`.
-Instead, we'll pass down a function from the Board to the Square, and we'll have Square call that function when a square is clicked. We'll change the `renderSquare` method in Board to:
+للحفاظ على خصوصيّة حالة المكوّن `Board` سنُمرِّر دالة من المكوّن `Board` إلى `Square`. تُستدعى هذه الدالة عند النقر على المربّع. سنغيّر التابع `renderSquare` في المكوّن `Board` إلى:
```javascript{5}
renderSquare(i) {
@@ -421,17 +416,17 @@ Instead, we'll pass down a function from the Board to the Square, and we'll have
}
```
->Note
+>ملاحظة:
>
->We split the returned element into multiple lines for readability, and added parentheses so that JavaScript doesn't insert a semicolon after `return` and break our code.
-
-Now we're passing down two props from Board to Square: `value` and `onClick`. The `onClick` prop is a function that Square can call when clicked. We'll make the following changes to Square:
+>نُقسِّم العنصر المُعاد إلى عدّة أسطر لسهولة القراءة، وأضفنا أقواس لكي لا تُدخِل JavaScript فاصلة منقوطة بعد الكلمة `return` وتؤدي إلى حدوث خطأ في شيفرتنا.
-* Replace `this.state.value` with `this.props.value` in Square's `render` method
-* Replace `this.setState()` with `this.props.onClick()` in Square's `render` method
-* Delete the `constructor` from Square because Square no longer keeps track of the game's state
+نُمرِّر الآن خاصيتين من المكوّن `Board` إلى `Square` وهما `value` و `onClick`. الخاصيّة `onClick` هي عبارة عن دالة يستطيع المكوّن `Square` استدعاءها عند النقر عليه. سنجري التغييرات التالية بالمكوّن `Square`:
-After these changes, the Square component looks like this:
+* نضع `this.props.value` بدلًا من `this.state.value` في تابع التصيير `render` له.
+* نضع `this.props.onClick()` بدلًا من `this.setState()` في تابع التصيير `render` له.
+* نحذف الدالة البانية `constructor` منه لأنّ المربّع لم يعد يحتاج لتتبع حالة اللعبة.
+
+سيبدو المكوّن `Square` بعد التغييرات كما يلي:
```javascript{1,2,6,8}
class Square extends React.Component {
@@ -448,19 +443,19 @@ class Square extends React.Component {
}
```
-When a Square is clicked, the `onClick` function provided by the Board is called. Here's a review of how this is achieved:
+عند النقر على المربّع تُستدعى الدالة `onClick` المُزوَّدة من قبل المكوّن `Board`. وهذا ملخّص لكيفية تحقيق ذلك:
-1. The `onClick` prop on the built-in DOM `` component tells React to set up a click event listener.
-2. When the button is clicked, React will call the `onClick` event handler that is defined in Square's `render()` method.
-3. This event handler calls `this.props.onClick()`. The Square's `onClick` prop was specified by the Board.
-4. Since the Board passed `onClick={() => this.handleClick(i)}` to Square, the Square calls `this.handleClick(i)` when clicked.
-5. We have not defined the `handleClick()` method yet, so our code crashes. If you click a square now, you should see a red error screen saying something like "this.handleClick is not a function".
+1. تُخبِر الخاصيّة `onClick` الموجودة في المكوّن `` مكتبة React بأن تُعِد مُستمِع لحدث النقر.
+2. عند النقر على الزر، ستستدعي React مُعالِج الحدث `onClick` المُعرَّف في التابع `render()` للمكوّن Square.
+3. يستدعي مُعالِج الأحداث هذا `this.props.onClick()`. الخاصيّة `onClick` الموجودة في المكوّن Square مُحدَّدة من قبل المكوّن `Board`.
+4. بما أنّ المكوّن `Board` مرَّر `onClick={() => this.handleClick(i)}` إلى `Square`، فسيستدعي هذا الأخير `this.handleClick(i)` عند النقر عليه.
+5. لم نُعرِّف التابع `handleClick()` حتى الآن، لذا تنهار الشيفرة لدينا.
->Note
+>ملاحظة:
>
->The DOM `` element's `onClick` attribute has a special meaning to React because it is a built-in component. For custom components like Square, the naming is up to you. We could give any name to the Square's `onClick` prop or Board's `handleClick` method, and the code would work the same. In React, it's conventional to use `on[Event]` names for props which represent events and `handle[Event]` for the methods which handle the events.
+>تمتلك الخاصيّة `onClick` الموجودة في العنصر `` معنى مميز بالنسبة لمكتبة React لأنّه مكوّن مُضمَّن في DOM. أمّا بالنسبة للمكوّنات المُخصَّصة مثل `Square` فلك حريّة اختيار أسماء الخاصيّات. كان بإمكاننا تسمية الخاصيّة `onClick` في المكوّن `Square` أو التابع `handleClick` في المكوّن `Board` بشكلٍ مختلف. على أيّة حال هناك اتفاق في React باستخدام النمط `on[Event]` لتسمية الخاصيّة التي تُمثِّل أحداثًا والنمط `handle[Event]` لتسمية التوابع التي تُعالِج هذه الأحداث.
-When we try to click a Square, we should get an error because we haven't defined `handleClick` yet. We'll now add `handleClick` to the Board class:
+عندما نحاول الآن النقر على المربّع يجب أن نحصل على خطأ لأنّنا لم نُعرِّف التابع `handleClick` حتى الآن. سنضيف التابع `handleClick` إلى صنف المكوّن `Board`:
```javascript{9-13}
class Board extends React.Component {
@@ -513,63 +508,64 @@ class Board extends React.Component {
}
```
-**[View the full code at this point](https://codepen.io/gaearon/pen/ybbQJX?editors=0010)**
+**[انظر إلى كامل الشيفرة عند هذه النقط](https://codepen.io/gaearon/pen/ybbQJX?editors=0010)**
-After these changes, we're again able to click on the Squares to fill them, the same as we had before. However, now the state is stored in the Board component instead of the individual Square components. When the Board's state changes, the Square components re-render automatically. Keeping the state of all squares in the Board component will allow it to determine the winner in the future.
+بعد هذه التغييرات أصبحنا قادرين على النقر على المربّعات لملئها مع تخزين الحالة ضمن المكوّن `Board` بدلًا من وضعها ضمن كل مكوّن مربّع `Square`. عندما تتغير حالة المكوّن `Board` فستُعيد مكوّنات المربّعات التصيير بشكل تلقائي. سيسمح لك الاحتفاظ بحالة جميع المربعات ضمن المكوّن `Board` بتحديد الفائز لاحقًا.
-Since the Square components no longer maintain state, the Square components receive values from the Board component and inform the Board component when they're clicked. In React terms, the Square components are now **controlled components**. The Board has full control over them.
+بما أنّ مكوّنات المربعات لم تعد تحتفظ بالحالة فسيستقبل المكوّن `Square` القيم من المكوّن `Board` ويُخبره عند النقر عليه. بمصطلحات React نستطيع القول عن المكوّن `Square` بأنّه **مكوّن مضبوط**، لأنّ المكوّن `Board` أصبح يمتلك كامل التحكم به.
-Note how in `handleClick`, we call `.slice()` to create a copy of the `squares` array to modify instead of modifying the existing array. We will explain why we create a copy of the `squares` array in the next section.
+لاحظ كيف أنّنا نستدعي ضمن `handleClick` التابع `.slice()` لإنشاء نسخة عن المصفوفة `squares` لتعديلها بدلًا من تعديل المصفوفة الموجودة. لنشرح لماذا نفعل ذلك في القسم التالي.
-### Why Immutability Is Important {#why-immutability-is-important}
+### لماذا تكون عدم القابلية للتغير مهمة؟ {#why-immutability-is-important}
-In the previous code example, we suggested that you use the `.slice()` method to create a copy of the `squares` array to modify instead of modifying the existing array. We'll now discuss immutability and why immutability is important to learn.
+اقترحنا في مثال الشيفرة السابق استخدام المُعامِل `.slice()` لإنشاء نسخة عن المصفوفة `squares` لتعديلها بدلًا من تعديل المصفوفة الموجودة. سنناقش الآن عدم القابلية للتعديل (immutability) وأهمية تعلّمها.
-There are generally two approaches to changing data. The first approach is to *mutate* the data by directly changing the data's values. The second approach is to replace the data with a new copy which has the desired changes.
+هنالك طريقتان لتغيير البيانات. الطريقة الأولى هي **تعديل** البيانات مباشرة بتغيير قيمها. والطريقة الثانية هي الحصول على نسخة جديدة من البيانات تمتلك التغييرات المطلوبة ووضعها بدل البيانات الأصليّة.
-#### Data Change with Mutation {#data-change-with-mutation}
+#### تغيير البيانات عن طريق تعديلها بشكل مباشر {#data-change-with-mutation}
```javascript
var player = {score: 1, name: 'Jeff'};
player.score = 2;
-// Now player is {score: 2, name: 'Jeff'}
+// قيمة الـ player الان : {score: 2, name: 'Jeff'}
```
-#### Data Change without Mutation {#data-change-without-mutation}
+#### تغيير البيانات بدون تعديلها بشكل مباشر {#data-change-without-mutation}
```javascript
var player = {score: 1, name: 'Jeff'};
var newPlayer = Object.assign({}, player, {score: 2});
-// Now player is unchanged, but newPlayer is {score: 2, name: 'Jeff'}
+// الآن يبقى player بدون تغيير
+// ولكن تكون قيمة newPlayer هي {score: 2, name: 'Jeff'}
-// Or if you are using object spread syntax proposal, you can write:
+/// أو إن كنت تستخدم اقتراح صياغة نشر الكائنات تستطيع كتابة
// var newPlayer = {...player, score: 2};
```
-The end result is the same but by not mutating (or changing the underlying data) directly, we gain several benefits described below.
+النتيجة النهائيّة هي نفسها ولكن نكسب عدّة فوائد عن طريق عدم تغيير البيانات بشكل مباشر، سنذكر هذه الفوائد الآن.
-#### Complex Features Become Simple {#complex-features-become-simple}
+#### تبسيط الميزات المعقدة {#complex-features-become-simple}
-Immutability makes complex features much easier to implement. Later in this tutorial, we will implement a "time travel" feature that allows us to review the tic-tac-toe game's history and "jump back" to previous moves. This functionality isn't specific to games -- an ability to undo and redo certain actions is a common requirement in applications. Avoiding direct data mutation lets us keep previous versions of the game's history intact, and reuse them later.
+تجعل عدم قابلية التغيير من الأسهل تنفيذ الميزات المعقدة. لاحقًا في هذا الدليل سنُنفِّذ ميزة السفر عبر الزمن والتي تسمح لنا بمراجعة تاريخ الحركات السابقة في لعبة إكس-أو مع إمكانية القفز إلى الحركات السابقة. هذه الميزة ليست خاصة بالألعاب، فالقدرة على التراجع والعودة عن أفعال محددة هي متطلب شائع في التطبيقات. يسمح لك تجنّب التعديل المباشر للبيانات بالاحتفاظ بإصدارات من تاريخ تحركات اللعبة وإعادة استخدامها لاحقًا.
-#### Detecting Changes {#detecting-changes}
+#### كشف التغيرات {#detecting-changes}
-Detecting changes in mutable objects is difficult because they are modified directly. This detection requires the mutable object to be compared to previous copies of itself and the entire object tree to be traversed.
+يصعب كشف التغيّرات في الكائنات القابلة للتعديل لأنّها تُعدَّل بشكل مباشر. يتطلب هذا الكشف مقارنة الكائنات القابلة للتعديل مع النسخ السابقة منها وكامل شجرة الكائنات المطلوبة.
-Detecting changes in immutable objects is considerably easier. If the immutable object that is being referenced is different than the previous one, then the object has changed.
+يُعتبَر كشف التغيّرات في الكائنات غير القابلة للتعديل أسهل. إن كان الكائن غير القابل للتعديل مختلفًا عن السابق فنعتبر أنّ الكائن قد تغيّر.
-#### Determining When to Re-Render in React {#determining-when-to-re-render-in-react}
+#### تحديد متى يتم إعادة التصيير في React {#determining-when-to-re-render-in-react}
-The main benefit of immutability is that it helps you build _pure components_ in React. Immutable data can easily determine if changes have been made which helps to determine when a component requires re-rendering.
+الفائدة الأساسيّة من عدم القابلية للتعديل هي أنّها تساعدك على بناء __مكوّنات نقيّة__ في React. تستطيع البيانات غير القابلة للتعديل أن تُحدِّد بسهولة إذا ما قد أُجريت أي تغييرات، والذي يُساعد بتحديد متى يحتاج المكوّن لإعادة التصيير.
-You can learn more about `shouldComponentUpdate()` and how you can build *pure components* by reading [Optimizing Performance](/docs/optimizing-performance.html#examples).
+بإمكانك تعلّم المزيد حول التابع `shouldComponentUpdate()` وكيفيّة بناء *مكوّنات نقية* من خلال قراءة مستند [تحسين الأداء](/docs/optimizing-performance.html#examples).
-### Function Components {#function-components}
+### مكونات الدوال {#function-components}
-We'll now change the Square to be a **function component**.
+سنغيّر الآن المكوّن `Square` ليُصبِح **مكوّن دالّة**.
-In React, **function components** are a simpler way to write components that only contain a `render` method and don't have their own state. Instead of defining a class which extends `React.Component`, we can write a function that takes `props` as input and returns what should be rendered. Function components are less tedious to write than classes, and many components can be expressed this way.
+**مكوّنات الدوال** في React هي طريقة أبسط لكتابة المكوّنات التي تحتوي فقط على تابع التصيير `render` بدون أن تمتلك حالتها الخاصّة. فبدلًا من تعريف صنف يمتد إلى الصنف `React.Component` نستطيع كتابة دالة تأخذ خاصيّات `props` وحقل إدخال وتُعيد ما ينبغي تصييره. من الأسهل كتابة مكوّنات الدوال بدلًا من الأصناف، ويُمكِن التعبير عن الكثير من المكوّنات بهذه الطريقة.
-Replace the Square class with this function:
+ضع هذه الدالة بدلًا من الصنف `Square`:
```javascript
function Square(props) {
@@ -581,19 +577,19 @@ function Square(props) {
}
```
-We have changed `this.props` to `props` both times it appears.
+غيّرنا `this.props` إلى `props` في المرّات التي ظهرت فيها.
-**[View the full code at this point](https://codepen.io/gaearon/pen/QvvJOv?editors=0010)**
+**[انظر إلى كامل الشيفرة عند هذه النقطة](https://codepen.io/gaearon/pen/QvvJOv?editors=0010)**
->Note
+>ملاحظة
>
->When we modified the Square to be a function component, we also changed `onClick={() => this.props.onClick()}` to a shorter `onClick={props.onClick}` (note the lack of parentheses on *both* sides).
+>عندما عدّلنا المكوّن Square ليصبح مكوّن دالة، فقد غيّرنا أيضًا `onClick={() => this.props.onClick()}` إلى الشكل المختصر `onClick={props.onClick}` (لاحظ عدم وجود الأقواس على الجانبين). في حال الصنف استخدمنا الدوال السهميّة للوصول إلى قيمة `this` الصحيحة، ولكن في مكوّنات الدوال لا حاجة للقلق حول `this`.
-### Taking Turns {#taking-turns}
+### أخذ الأدوار {#taking-turns}
-We now need to fix an obvious defect in our tic-tac-toe game: the "O"s cannot be marked on the board.
+نحتاج الآن لإصلاح عيب واضح في لعبة إكس-أو لدينا، فلا يُمكِن وضع الإشارة "O" على لوحة اللعبة.
-We'll set the first move to be "X" by default. We can set this default by modifying the initial state in our Board constructor:
+سنُعيِّن أول خطوة لتكون "X" افتراضيًّا. نستطيع تعيين هذه القيمة الافتراضيّة عن طريق تعديل الحالة المبدئيّة في الدالة البانية للمكوّن `Board`:
```javascript{6}
class Board extends React.Component {
@@ -606,7 +602,7 @@ class Board extends React.Component {
}
```
-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. We'll update the Board's `handleClick` function to flip the value of `xIsNext`:
+في كل مرة يتحرّك بها اللاعب ستنقلب قيمة المتغيّر `xIsNext` (متغير منطقي) لتحديد أي لاعب سيلعب الخطوة التالية وستُحفَظ حالة اللعبة. سنُحدِّث الدالة `handleClick` للمكوّن `Board` لتقلب قيمة `xIsNext`:
```javascript{3,6}
handleClick(i) {
@@ -619,19 +615,19 @@ Each time a player moves, `xIsNext` (a boolean) will be flipped to determine whi
}
```
-With this change, "X"s and "O"s can take turns. Try it!
+بها التغيير تستطيع `X` و `O` أخذ الأدوار.
-Let's also change the "status" text in Board's `render` so that it displays which player has the next turn:
+فلنُغيِّر أيضًا نص الحالة في التابع `render` للمكوّن `Board` بحيث يعرض من هو اللاعب الذي سيلعب الدور التالي:
```javascript{2}
render() {
const status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O');
return (
- // the rest has not changed
+ // لم تتغير بقية الشيفرة
```
-After applying these changes, you should have this Board component:
+بعد تطبيق هذه التغييرات يجب أن تملك مكوّن `Board` مماثل لما يلي:
```javascript{6,11-16,29}
class Board extends React.Component {
@@ -688,11 +684,11 @@ class Board extends React.Component {
}
```
-**[View the full code at this point](https://codepen.io/gaearon/pen/KmmrBy?editors=0010)**
+**[انظر إلى كامل الشيفرة عند هذه النقطة](https://codepen.io/gaearon/pen/KmmrBy?editors=0010)**
-### Declaring a Winner {#declaring-a-winner}
+### التصريح عن الفائز {#declaring-a-winner}
-Now that we show which player's turn is next, we should also show when the game is won and there are no more turns to make. Copy this helper function and paste it at the end of the file:
+الآن بعد أن عرضنا من هو اللاعب الذي سيلعب الدور التالي، فيجب علينا أن نعرض عبارة عندما يفوز اللاعب باللعبة ولا تتبقى أيّة أدوار للعبها. نستطيع تحديد الفائز عن طريق إضافة هذه الدالة المساعدة إلى نهاية الملف:
```javascript
function calculateWinner(squares) {
@@ -716,9 +712,7 @@ function calculateWinner(squares) {
}
```
-Given an array of 9 squares, this function will check for a winner and return `'X'`, `'O'`, or `null` as appropriate.
-
-We will call `calculateWinner(squares)` in the Board's `render` function to check if a player has won. If a player has won, we can display text such as "Winner: X" or "Winner: O". We'll replace the `status` declaration in Board's `render` function with this code:
+سنستدعي التابع `calculateWinner(squares)` في تابع التصيير `render` للمكوّن `Board` للتحقّق من فوز اللاعب. إن فاز اللاعب فنستطيع عرض نص مثل "الفائز: X" أو "الفائز: O". سنضع هذه الشيفرة بدلًا من تصريح `الحالة` الموجود في التابع `render` للمكوّن `Board`:
```javascript{2-8}
render() {
@@ -731,10 +725,10 @@ We will call `calculateWinner(squares)` in the Board's `render` function to chec
}
return (
- // the rest has not changed
+ // لم تتغير بقية الشيفرة
```
-We can now change the Board's `handleClick` function to return early by ignoring a click if someone has won the game or if a Square is already filled:
+نستطيع الآن تغيير الدالة `handleClick` للمكوّن `Board` لتُعيد قيمتها باكرًا عن طريق تجاهل النقرة إن فاز أحد باللعبة أو إن كان المربّع يحتوي على قيمة مسبقًا:
```javascript{3-5}
handleClick(i) {
@@ -750,25 +744,25 @@ We can now change the Board's `handleClick` function to return early by ignoring
}
```
-**[View the full code at this point](https://codepen.io/gaearon/pen/LyyXgK?editors=0010)**
+**[انظر إلى كامل الشيفرة عند هذه النقطة.](https://codepen.io/gaearon/pen/LyyXgK?editors=0010)**
-Congratulations! You now have a working tic-tac-toe game. And you've just learned the basics of React too. So *you're* probably the real winner here.
+تهانينا! تمتلك الآن لعبة إكس-أو تعمل بشكل جيّد. وقد تعلّمت أساسيّات React أيضًا. لذا قد تكون أنت الرابح الحقيقي هنا.
-## Adding Time Travel {#adding-time-travel}
+## إضافة السفر عبر الزمن {#adding-time-travel}
-As a final exercise, let's make it possible to "go back in time" to the previous moves in the game.
+كتمرين أخير فلنجعل من الممكن الرجوع إلى الخلف بالوقت إلى التحركات السابقة في اللعبة.
-### Storing a History of Moves {#storing-a-history-of-moves}
+### تخزين تاريخ التحركات {#storing-a-history-of-moves}
-If we mutated the `squares` array, implementing time travel would be very difficult.
+إن عدّلنا المصفوفة `squares` سيكون تنفيذ السفر عبر الزمن أمرًا صعبًا.
-However, we used `slice()` to create a new copy of the `squares` array after every move, and [treated it as immutable](#why-immutability-is-important). This will allow us to store every past version of the `squares` array, and navigate between the turns that have already happened.
+ولكننا استخدمنا التابع `slice()` لإنشاء نسخة من المصفوفة `squares` بعد كل تحرّك، [والتعامل معها كمصفوفة غير قابلة للتعديل](#why-immutability-is-important). يسمح لك ذلك بتخزين كل إصدار قديم من هذه المصفوفة، والتنقل بين الأدوار التي حدثت سابقًا.
-We'll store the past `squares` arrays in another array called `history`. The `history` array represents all board states, from the first to the last move, and has a shape like this:
+سنُخزِّن مصفوفات `squares` السابقة ضمن مصفوفة أخرى تُدعى `history` والتي تُمثِّل حالات لوحة اللعبة من أو إلى آخر تحرّك، ويكون شكلها كما يلي:
```javascript
history = [
- // Before first move
+ // قبل التحرك الأول
{
squares: [
null, null, null,
@@ -776,7 +770,7 @@ history = [
null, null, null,
]
},
- // After first move
+ // بعد التحرك الأول
{
squares: [
null, null, null,
@@ -784,7 +778,7 @@ history = [
null, null, null,
]
},
- // After second move
+ // بعد التحرك الثاني
{
squares: [
null, null, null,
@@ -796,15 +790,16 @@ history = [
]
```
-Now we need to decide which component should own the `history` state.
+نحتاج الآن إلى أن نقرّر أي مكوّن ينبغي أن يمتلك الحالة `history`.
+
+### رفع الحالة مرّة أخرى {#lifting-state-up-again}
-### Lifting State Up, Again {#lifting-state-up-again}
+نريد من المكوّن الموجود في أعلى مستوى من اللعبة أن يعرض قائمة بالتحركات السابقة. سيحتاج إلى الوصول إلى الحالة `history` لفعل ذلك، لذا سنضعها في المكوّن ذو المستوى الأعلى في اللعبة واسمه `Game`.
-We'll want the top-level Game component to display a list of past moves. It will need access to the `history` to do that, so we will place the `history` state in the top-level Game component.
+يُتيح لنا وضع الحالة `history` في المكوّن `Game` أن نزيل الحالة `squares` من المكوّن الابن له وهو `Board`. كما [رفعنا الحالة](#lifting-state-up) من المكوّن `Square` إلى `Board`، سنرفعها الآن من `Board` إلى المكوّن ذو المستوى الأعلى في اللعبة `Game`. يُعطي هذا المكوّن `Game` التحكّم الكامل ببيانات المكوّن `Board`، ويسمح له بأن يأمر المكوّن `Board` بتصيير الأدوار السابقة من `history`.
-Placing the `history` state into the Game component lets us remove the `squares` state from its child Board component. Just like we ["lifted state up"](#lifting-state-up) from the Square component into the Board component, we are now lifting it up from the Board into the top-level Game component. This gives the Game component full control over the Board's data, and lets it instruct the Board to render previous turns from the `history`.
+سنُعِد في البداية الحالة المبدئيّة للمكوّن `Game` ضمن الدالة البانية له:
-First, we'll set up the initial state for the Game component within its constructor:
```javascript{2-10}
class Game extends React.Component {
@@ -834,13 +829,13 @@ class Game extends React.Component {
}
```
-Next, we'll have the Board component receive `squares` and `onClick` props from the Game component. Since we now have a single click handler in Board for many Squares, we'll need to pass the location of each Square into the `onClick` handler to indicate which Square was clicked. Here are the required steps to transform the Board component:
+نمتلك الآن المكوّن `Board` الذي يستقبل الخاصيّتين `squares` و `onClick` من المكوّن `Game`. بما أنّنا نمتلك الآن مُعالِج وحيد لحدث النقر في المكوّن `Board` للعديد من مكوّنات `Square`، فسنحتاج لتمرير موقع كل مكوّن `Square` إلى المُعالِج `onClick` للإشارة إلى أي مربّع هو الذي نقرنا عليه. هذه هي الخطوات المطلوبة لتحويل المكوّن `Board`:
-* Delete the `constructor` in Board.
-* Replace `this.state.squares[i]` with `this.props.squares[i]` in Board's `renderSquare`.
-* Replace `this.handleClick(i)` with `this.props.onClick(i)` in Board's `renderSquare`.
+* احذف الدالة البانية `constructor` من المكوّن `Board`.
+* ضع `this.props.squares[i]` بدلًا من `this.state.squares[i]` في التابع `renderSquare` الموجود ضمن المكوّن `Board`.
+* ضع `this.props.onClick(i)` بدلًا من `this.handleClick(i)` في التابع `renderSquare` الموجود ضمن المكوّن `Board`.
-The Board component now looks like this:
+يبدو المكوّن `Board` الآن على الشكل التالي:
```javascript{17,18}
class Board extends React.Component {
@@ -898,7 +893,7 @@ class Board extends React.Component {
}
```
-We'll update the Game component's `render` function to use the most recent history entry to determine and display the game's status:
+سنُحدِّث التابع `render` للمكوّن `Game` ليستخدم آخر حالة `history` موجودة لتحديد وعرض حالة اللعبة:
```javascript{2-11,16-19,22}
render() {
@@ -930,7 +925,7 @@ We'll update the Game component's `render` function to use the most recent histo
}
```
-Since the Game component is now rendering the game's status, we can remove the corresponding code from the Board's `render` method. After refactoring, the Board's `render` function looks like this:
+بما أنّ المكوّن `Game` يُصيّر الآن حالة اللعبة فنستطيع إزالة الشيفرة الموافقة من التابع `render` للمكوّن `Board`. بعد فعل ذلك سيبدو التابع `render` للمكوّن `Board` كما يلي:
```js{1-4}
render() {
@@ -956,7 +951,7 @@ Since the Game component is now rendering the game's status, we can remove the c
}
```
-Finally, we need to move the `handleClick` method from the Board component to the Game component. We also need to modify `handleClick` because the Game component's state is structured differently. Within the Game's `handleClick` method, we concatenate new history entries onto `history`.
+نحتاج أخيرًا لنقل التابع `handleClick` من المكوّن `Board` إلى المكوّن `Game`. نحتاج أيضًا لتعديل الدالة `handleClick` لأنّ حالة مكوّن اللعبة `Game` مبنية بشكل مختلف. سنجمع الآن مُدخلات التاريخ الجديد مع الحالة `history` ضمن الدالة `handleClick` في المكوّن `Game`:
```javascript{2-4,10-12}
handleClick(i) {
@@ -976,30 +971,30 @@ Finally, we need to move the `handleClick` method from the Board component to th
}
```
->Note
+>ملاحظة
>
->Unlike the array `push()` method you might be more familiar with, the `concat()` method doesn't mutate the original array, so we prefer it.
+>على عكس التابع `push()` الخاص بالمصفوفات والذي قد تكون مُتآلفًا معه، فإنّ التابع `concat()` لا يُعدِّل المصفوفة الأصليّة لذلك نُفضّله.
-At this point, the Board component only needs the `renderSquare` and `render` methods. The game's state and the `handleClick` method should be in the Game component.
+عند هذه النقطة يحتاج المكوّن `Board` فقط إلى التابعين `render` و `renderSquare`. يجب أن تكون حالة اللعبة والتابع `handleClick` فيجب أن تكون في المكوّن `Game`.
-**[View the full code at this point](https://codepen.io/gaearon/pen/EmmOqJ?editors=0010)**
+**[انظر إلى كامل الشيفرة عند هذه النقطة](https://codepen.io/gaearon/pen/EmmOqJ?editors=0010)**
-### Showing the Past Moves {#showing-the-past-moves}
+### عرض التحركات السابقة {#showing-the-past-moves}
-Since we are recording the tic-tac-toe game's history, we can now display it to the player as a list of past moves.
+بما أنّنا نُسجِّل تاريخ تحرّكات لعبة إكس-أو، فبإمكاننا الآن عرضها للاعب كقائمة من التحركات السابقة.
-We learned earlier that React elements are first-class JavaScript objects; we can pass them around in our applications. To render multiple items in React, we can use an array of React elements.
+تعلمنا سابقًا أنّ عناصر React هي عبارة عن كائنات JavaScript نستطيع تمريرها في تطبيقنا. لتصيير عناصر متعددة في React نستطيع استخدام مصفوفة من عناصر React.
-In JavaScript, arrays have a [`map()` method](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) that is commonly used for mapping data to other data, for example:
+تمتلك المصفوفات في JavaScript [التابع `map()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) والذي من الشائع استخدامه لربط بيانات إلى بيانات أخرى كما يلي:
```js
const numbers = [1, 2, 3];
const doubled = numbers.map(x => x * 2); // [2, 4, 6]
```
-Using the `map` method, we can map our history of moves to React elements representing buttons on the screen, and display a list of buttons to "jump" to past moves.
+نستطيع باستخدام التابع `map` أن نربط تاريخ التحركات بعناصر React التي تمثل أزرار على الشاشة، ومن ثمّ نعرض قائمة بالأزرار للتنقل إلى التحركات السابقة.
-Let's `map` over the `history` in the Game's `render` method:
+فلنربط الحالة `history` في التابع `render` للمكوّن `Game`:
```javascript{6-15,34}
render() {
@@ -1042,62 +1037,62 @@ Let's `map` over the `history` in the Game's `render` method:
}
```
-**[View the full code at this point](https://codepen.io/gaearon/pen/EmmGEa?editors=0010)**
+**[انظر إلى كامل الشيفرة عند هذه النقطة](https://codepen.io/gaearon/pen/EmmGEa?editors=0010)**
-For each move in the tic-tac-toes's game's history, we create a list item `` which contains a button ``. The button has a `onClick` handler which calls a method called `this.jumpTo()`. We haven't implemented the `jumpTo()` method yet. For now, we should see a list of the moves that have occurred in the game and a warning in the developer tools console that says:
+نُنشِئ لكل تحرك في تاريخ اللعبة عنصرًا بالقائمة `` يحتوي على زر ``. يمتلك الزر مُعالِج للأحداث `onClick` والذي يستدعي تابًعا يُدعى `this.jumpTo()`. لم ننفذ هذا التابع حتى الآن. ينبغي أن نرى الآن قائمة بالتحركات التي حصلت في اللعبة وتحذير في النافذة console ضمن أدوات التطوير يقول:
-> Warning:
-> Each child in an array or iterator should have a unique "key" prop. Check the render method of "Game".
+> تحذير:
+> يجب أن يمتلك كل عنصر ابن في المصفوفة خاصية مفتاح `key`. تحقق من التابع `render` للمكوّن `Game`.
-Let's discuss what the above warning means.
+فلنناقش معنى التحذير السابق.
-### Picking a Key {#picking-a-key}
+### انتقاء مفتاح {#picking-a-key}
-When we render a list, React stores some information about each rendered list item. When we update a list, React needs to determine what has changed. We could have added, removed, re-arranged, or updated the list's items.
+عند تصيير قائمة تُخزن React بعض المعلومات حول كل عنصر منها. عندما نحدث القائمة تحتاج React لتحديد ما تغيّر. بإمكاننا إضافة، وإزالة، وإعادة ترتيب، وتحديث عناصر القائمة.
-Imagine transitioning from
+تخيل الانتقال من:
```html
-Alexa: 7 tasks left
-Ben: 5 tasks left
+أليكسا: 7 مهام متبقية
+بَنْ: 5 مهام متبقية
```
-to
+إلى:
```html
-Ben: 9 tasks left
-Claudia: 8 tasks left
-Alexa: 5 tasks left
+بَنْ: 9 مهام متبقية
+كلوديا: 8 مهام متبقية
+أليكسا: 5 مهام متبقية
```
-In addition to the updated counts, a human reading this would probably say that we swapped Alexa and Ben's ordering and inserted Claudia between Alexa and Ben. However, React is a computer program and does not know what we intended. Because React cannot know our intentions, we need to specify a *key* property for each list item to differentiate each list item from its siblings. One option would be to use the strings `alexa`, `ben`, `claudia`. If we were displaying data from a database, Alexa, Ben, and Claudia's database IDs could be used as keys.
+من وجهة نظرنا، بدل الانتقال بين ترتيب أليكسا وبن وأدخل كلوديا بينهما، ولكنّ React هي برنامج حاسوب ولا تفهم مقصدنا من ذلك، نحتاج لتحديد خاصيّة مفتاح *key* لكل عنصر قائمة لتمييزه عن العناصر الأشقاء له. بإمكاننا استخدام السلاسل النصيّة "`أليكسا`"، و "`بَنْ`"، و "`كلوديا`" كمفاتيح. إن كان لدينا الوصول إلى قاعدة البيانات فنستطيع استخدام المُعرِّفات (IDs) لأليكسا وكلوديا وبَنْ من قاعدة البيانات كمفاتيح:
```html
-{user.name}: {user.taskCount} tasks left
+{user.name}: {user.taskCount} مهام متبقية
```
-When a list is re-rendered, React takes each list item's key and searches the previous list's items for a matching key. If the current list has a key that didn't exist before, React creates a component. If the current list is missing a key that existed in the previous list, React destroys the previous component. If two keys match, the corresponding component is moved. Keys tell React about the identity of each component which allows React to maintain state between re-renders. If a component's key changes, the component will be destroyed and re-created with a new state.
+عند إعادة تصيير القائمة، تأخذ React مفتاح كل عنصر وتبحث بالقائمة القديمة عن مفتاح مُطابِق. إن كانت القائمة الحالية تحتوي على مفتاح غير موجود بالقائمة السابقة، فستُنشِئ React مكوّنًا جديدًا. وإن كانت القائمة الحاليّة تفتقد لمفتاح موجود في القائمة السابقة، فستُدمِّر React المكوّن. تُخبِر المفاتيح React عن هوية كل مكوّن والتي تسمح لمكتبة React بأن تُحافِظ على الحالة بين إعادات التصيير. إن تغيّر مفتاح المكوّن سيُدمَّر ويُعاد إنشاؤه مع حالة جديدة.
-`key` is a special and reserved property in React (along with `ref`, a more advanced feature). When an element is created, React extracts the `key` property and stores the key directly on the returned element. Even though `key` may look like it belongs in `props`, `key` cannot be referenced using `this.props.key`. React automatically uses `key` to decide which components to update. A component cannot inquire about its `key`.
+المفتاح `key` هو خاصيّة محجوزة في React (مع الخاصيّة `ref`، وهي ميزة أكثر تقدّمًا). عند إنشاء عنصر تستخرج React الخاصيّة `key` وتخزن المفتاح بشكل مباشر في العنصر المُعاد. على الرغم من أنّ المفتاح يبدو أنّه ينتمي للخاصيّات `props` فلا يمكننا الرجوع إليه عن طريق `this.props.key`. تستخدم React الكلمة `key` تلقائيًّا لتقرر أي مكوّن يجب تحديثه. لا يستطيع المكوّن الاستعلام عن `مفتاحـ`ـه.
-**It's strongly recommended that you assign proper keys whenever you build dynamic lists.** If you don't have an appropriate key, you may want to consider restructuring your data so that you do.
+**من المفضل أن تُعيّن المفاتيح الملائمة عندما تبني قوائم ديناميكيّة.** إن لم تمتلك المفتاح المناسب فانظر في إعادة بناء بياناتك بحيث يُصبِح لديك مفتاح ملائم للاستخدام.
-If no key is specified, React will present a warning and use the array index as a key by default. Using the array index as a key is problematic when trying to re-order a list's items or inserting/removing list items. Explicitly passing `key={i}` silences the warning but has the same problems as array indices and is not recommended in most cases.
+إن لم يُحدَّد مفتاح، فستعرض React تحذيرًا وستستخدم فهرس المصفوفة كمفتاح بشكل افتراضي. يكون استخدام الفهرس كمفتاح مشكلة عند محاولة إعادة ترتيب عناصر القائمة أو عند إدخال وإزالة العناصر. يؤدي تمرير `key={i}` إلى إيقاف التحذير ولكن يمتلك نفس المشاكل لأنّ فهرس المصفوفات غير مفضّل كمفتاح في معظم الحالات.
-Keys do not need to be globally unique; they only need to be unique between components and their siblings.
+لا يجب على المفاتيح أن تكون فريدة ضمن المجال العام (global)، بل يجب فقط أن تكون فريدة بين المكوّنات وأشقائها.
-### Implementing Time Travel {#implementing-time-travel}
+### تنفيذ ميزة السفر عبر الزمن {#implementing-time-travel}
-In the tic-tac-toe game's history, each past move has a unique ID associated with it: it's the sequential number of the move. The moves are never re-ordered, deleted, or inserted in the middle, so it's safe to use the move index as a key.
+في تاريخ لعبة إكس-أو يملك كل تحرّك سابق مُعرِّف (ID) فريد مرتبط معه، وهو الرقم التسلسلي للتحرّك. لا يُعاد ترتيب التحركات، أو حذفها، أو إدخالها في الوسط، لذا من الآن استخدام فهرس التحرّك كمفتاح هنا.
-In the Game component's `render` method, we can add the key as `` and React's warning about keys should disappear:
+نستطيع في تابع التصيير `render` للمكوّن `Game` أن نُضيف المفتاح ` ` وسيختفي تحذير React حول المفاتيح:
```js{6}
const moves = history.map((step, move) => {
const desc = move ?
- 'Go to move #' + move :
- 'Go to game start';
+ 'انتقل إلى التحرك #' + move :
+ 'انتقل إلى بداية اللعبة';
return (
this.jumpTo(move)}>{desc}
@@ -1106,11 +1101,11 @@ In the Game component's `render` method, we can add the key as ` `
});
```
-**[View the full code at this point](https://codepen.io/gaearon/pen/PmmXRE?editors=0010)**
+**[انظر إلى كامل الشيفرة عند هذه النقطة](https://codepen.io/gaearon/pen/PmmXRE?editors=0010)**
-Clicking any of the list item's buttons throws an error because the `jumpTo` method is undefined. Before we implement `jumpTo`, we'll add `stepNumber` to the Game component's state to indicate which step we're currently viewing.
+سيُظهر "يرمي" النقر على أي زر من عناصر القائمة خطأً لأنّ التابع `jumpTo` غير مُعرَّف. قبل تنفيذ التابع `jumpTo` سنُضيف رقم الخطوة `stepNumber` إلى حالة مكوّن اللعبة `Game` للإشارة إلى رقم الخطوة التي نشاهدها حاليًّا.
-First, add `stepNumber: 0` to the initial state in Game's `constructor`:
+أضف في البداية `stepNumber: 0` إلى الحالة المبدئيّة في `الدالة البانية` للمكوّن `Game`:
```js{8}
class Game extends React.Component {
@@ -1126,11 +1121,11 @@ class Game extends React.Component {
}
```
-Next, we'll define the `jumpTo` method in Game to update that `stepNumber`. We also set `xIsNext` to true if the number that we're changing `stepNumber` to is even:
+سنُعرِّف الآن التابع `jumpTo` في المكوّن `Game` لتحديث رقم الخطوة `stepNumber`. نُعيِّن أيضًا قيمة `xIsNext` إلى `true` إن كان الرقم الذي نُغيّره زوجيًّا:
```javascript{5-10}
handleClick(i) {
- // this method has not changed
+ // لم يتغير هذا التابع
}
jumpTo(step) {
@@ -1141,15 +1136,15 @@ Next, we'll define the `jumpTo` method in Game to update that `stepNumber`. We a
}
render() {
- // this method has not changed
+ // لم يتغير هذا التابع
}
```
-We will now make a few changes to the Game's `handleClick` method which fires when you click on a square.
+سنجري الآن بعض التغييرات على التابع `handleClick` للمكوّن `Game` والذي يُطلَق عند النقر على المربّع.
-The `stepNumber` state we've added reflects the move displayed to the user now. After we make a new move, we need to update `stepNumber` by adding `stepNumber: history.length` as part of the `this.setState` argument. This ensures we don't get stuck showing the same move after a new one has been made.
+تعكس الحالة `stepNumber` التي أضفناها التحرّك المعروض للمستخدم حاليًّا. بعد إجراء تحرّك جديد سنحتاج إلى تحديث `stepNumber` عن طريق إضافة `stepNumber: history.length` كجزء من الوسيط `this.setState`. يضمن هذا ألّا نعلق بإظهار نفس التحرك بعد القيام بتحرك جديد.
-We will also replace reading `this.state.history` with `this.state.history.slice(0, this.state.stepNumber + 1)`. This ensures that if we "go back in time" and then make a new move from that point, we throw away all the "future" history that would now become incorrect.
+سنضع أيضًا `this.state.history.slice(0, this.state.stepNumber + 1)` بدلًا من `this.state.history` . يضمن هذا أنّنا عندما نعود في الزمن ونجري تحرّك جديد من تلك النقطة، أن نمسح كل التاريخ المستقبلي الذي سيصبح الآن غير صحيح:
```javascript{2,13}
handleClick(i) {
@@ -1170,7 +1165,7 @@ We will also replace reading `this.state.history` with `this.state.history.slice
}
```
-Finally, we will modify the Game component's `render` method from always rendering the last move to rendering the currently selected move according to `stepNumber`:
+أخيرًا سنُعدِّل التابع `render` للمكوّن `Game` من تصيير التحرك الأخير دومًا إلى تصيير التحرك المُختار حاليًّا وفق قيمة `stepNumber`:
```javascript{3}
render() {
@@ -1178,33 +1173,33 @@ Finally, we will modify the Game component's `render` method from always renderi
const current = history[this.state.stepNumber];
const winner = calculateWinner(current.squares);
- // the rest has not changed
+ // بقية الشيفرة لم تتغير
```
-If we click on any step in the game's history, the tic-tac-toe board should immediately update to show what the board looked like after that step occurred.
+إن نقرنا على أي تحرك في تاريخ اللعبة، فستُحدَّث لوحة اللعبة فورًا لتظهر بالشكل المفروض بعد حدوث ذلك التحرّك.
-**[View the full code at this point](https://codepen.io/gaearon/pen/gWWZgR?editors=0010)**
+**[انظر إلى كامل الشيفرة عند هذه النقطة.](https://codepen.io/gaearon/pen/gWWZgR?editors=0010)**
-### Wrapping Up {#wrapping-up}
+### الملخص {#wrapping-up}
-Congratulations! You've created a tic-tac-toe game that:
+تهانينا! لقد أنشأتَ لعبة إكس-أو والَّتي:
-* Lets you play tic-tac-toe,
-* Indicates when a player has won the game,
-* Stores a game's history as a game progresses,
-* Allows players to review a game's history and see previous versions of a game's board.
+* تُتيح لك لعب إكس-أو.
+* تُخبرنا عندما يفوز اللاعب.
+* تُخزِّن تاريخ اللعبة أثناء تقدمّ اللعبة.
+* تسمح للاعبين بمراجعة تاريخ اللعبة ورؤية الإصدارات القديمة للوحة اللعبة.
-Nice work! We hope you now feel like you have a decent grasp on how React works.
+عمل رائع! نتمنى أن تشعر الآن بأنك تمتلك لمحة حول آليّة عمل React.
-Check out the final result here: **[Final Result](https://codepen.io/gaearon/pen/gWWZgR?editors=0010)**.
+تحقّق من النتيجة النهائيّة هن : **[النتيجةالنهائيّة](https://codepen.io/gaearon/pen/gWWZgR?editors=0010)**.
-If you have extra time or want to practice your new React skills, here are some ideas for improvements that you could make to the tic-tac-toe game which are listed in order of increasing difficulty:
+إن كان لديك المزيد من الوقت أو أردت ممارسة مهاراتك الجديدة التي تعلمتها في React، فهذه بعض الأفكار للتحسين والتي قد تجريها على لعبة إكس-أو وهي مرتبة بشكل تصاعدي حسب الصعوبة:
-1. Display the location for each move in the format (col, row) in the move history list.
-2. Bold the currently selected item in the move list.
-3. Rewrite Board to use two loops to make the squares instead of hardcoding them.
-4. Add a toggle button that lets you sort the moves in either ascending or descending order.
-5. When someone wins, highlight the three squares that caused the win.
-6. When no one wins, display a message about the result being a draw.
+1. عرض موقع كل تحرك بصيغة العامود والصف في قائمة تاريخ التحركات.
+2. تعيين تنسيق عريض (Bold) للعنصر المُحدَّد حاليًّا في قائمة التحركات.
+3. إعادة كتابة المكوّن `Board` ليستخدم حلقتين لإنشاء المربعات بدلًا من كتابتها حرفيًّا.
+4. إضافة زر لترتيب التحركات تصاعديًّا أو تنازليًّا.
+5. تعليم المربعات الثلاث عند فوز أحد اللاعبين والتي سببت فوزه.
+6. عرض رسالة بنتيجة التعادل عندما لا يفوز أحد.
-Throughout this tutorial, we touched on React concepts including elements, components, props, and state. For a more detailed explanation of each of these topics, check out [the rest of the documentation](/docs/hello-world.html). To learn more about defining components, check out the [`React.Component` API reference](/docs/react-component.html).
+تعلمنا خلال هذا الدليل مفاهيم في React تتضمّن العناصر، والمكوّنات، والخاصيّات، والحالة. للحصول على شرح مُفصَّل عن كل من هذه المواضيع تحقّق من [باقي مستندات React](/docs/hello-world.html). لتعلّم المزيد حول تعريف المكوّنات تحقّق من [مرجع واجهة برمجة التطبيق `React.Component`](/docs/react-component.html).