الفرق بين المراجعتين لصفحة: «ReactNative/intro react»
لا ملخص تعديل |
جميل-بيلوني (نقاش | مساهمات) ط مراجعة |
||
(5 مراجعات متوسطة بواسطة مستخدمين اثنين آخرين غير معروضة) | |||
سطر 1: | سطر 1: | ||
<noinclude>{{DISPLAYTITLE:أساسيات مكتبة React اللازمة لتعلم React Native}}</noinclude> | |||
يُشغَّل إطار عمل [[ReactNative|React Native]] على مكتبة [[React]]، وهي مكتبة شائعة ومفتوحة المصدر تُستخدَم لبناء واجهات المستخدم باستخدام لغة [[JavaScript]]. يجب فهم React فهمًا جيدًا لتحقيق أقصى استفادة من React Native. تساعدك هذه الصفحة للبدء أو لاستذكار المفاهيم الأساسية من React والتي هي: | يُشغَّل إطار عمل [[ReactNative|React Native]] على مكتبة [[React]]، وهي مكتبة شائعة ومفتوحة المصدر تُستخدَم لبناء واجهات المستخدم باستخدام لغة [[JavaScript]]. يجب فهم [[React]] فهمًا جيدًا لتحقيق أقصى استفادة من React Native. تساعدك هذه الصفحة للبدء أو لاستذكار المفاهيم الأساسية من [[React]] والتي هي: | ||
* المكونات components | * المكونات components | ||
سطر 9: | سطر 9: | ||
يمكنك الاطلاع على [[React|توثيق React]]، إن أردت التعمق أكثر. | يمكنك الاطلاع على [[React|توثيق React]]، إن أردت التعمق أكثر. | ||
== | == المكون الأول == | ||
يستخدم المثال التالي المكون Cat: | يستخدم المثال التالي المكون <code>Cat</code>: | ||
=== مكون الدالة Function component === | |||
<syntaxhighlight lang="javascript"> | إليك المثال التالي ([https://snack.expo.dev/@hsoubwiki/your-cat-function-component تجربة حية]):<syntaxhighlight lang="javascript"> | ||
import React from 'react'; | import React from 'react'; | ||
import { Text } from 'react-native'; | import { Text } from 'react-native'; | ||
سطر 29: | سطر 29: | ||
</syntaxhighlight>يبدأ مكونك كدالة:<syntaxhighlight lang="javascript"> | </syntaxhighlight>يبدأ مكونك كدالة:<syntaxhighlight lang="javascript"> | ||
const Cat = () => {}; | const Cat = () => {}; | ||
</syntaxhighlight>يمكن عد هذه المكونات كمخططات | </syntaxhighlight>يمكن عد هذه المكونات كمخططات أساسية. يُخرَج ما يعيده مكون الدالة كعنصر React مهما كان ذلك الشيء المعاد، إذ تتيح لك عناصر React وصف ما تريد رؤيته على الشاشة. | ||
فيما يلي سيُخرَج المكون <code>Cat</code> كعنصر <code><Text></code>:<syntaxhighlight lang="javascript"> | فيما يلي سيُخرَج المكون <code>Cat</code> كعنصر <code><Text></code>:<syntaxhighlight lang="javascript"> | ||
سطر 35: | سطر 35: | ||
return <Text>Hello, I am your cat!</Text>; | return <Text>Hello, I am your cat!</Text>; | ||
}; | }; | ||
</syntaxhighlight>يمكنك تصدير export مكون الدالة الخاص بك باستخدام | </syntaxhighlight>يمكنك تصدير export مكون الدالة الخاص بك باستخدام إعداد تصدير JavaScript الافتراضي <code>[[JavaScript/export|export default]]</code>، لاستخدامه في أي مكان ضمن تطبيقك كما يلي:<syntaxhighlight lang="javascript"> | ||
const Cat = () => { | const Cat = () => { | ||
return <Text>Hello, I am your cat!</Text>; | return <Text>Hello, I am your cat!</Text>; | ||
سطر 43: | سطر 43: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== مكون الصنف Class component === | |||
تميل مكونات الصنف إلى تكون مطوَّلةً أكثر من مكونات | تميل مكونات الصنف إلى تكون مطوَّلةً أكثر من مكونات الدالة، انظر المثال التالي المماثل تمامًا للمثال السابق ولكن باستعمال مكون صنف ([https://snack.expo.dev/@hsoubwiki/your-cat-class-component تجربة حية]):<syntaxhighlight lang="javascript"> | ||
import React, { Component } from 'react'; | import React, { Component } from 'react'; | ||
import { Text } from 'react-native'; | import { Text } from 'react-native'; | ||
سطر 61: | سطر 61: | ||
</syntaxhighlight>يبدأ المكون كصنفٍ يرث <code>Component</code> بدلًا من أن يكون كدالة:<syntaxhighlight lang="javascript"> | </syntaxhighlight>يبدأ المكون كصنفٍ يرث <code>Component</code> بدلًا من أن يكون كدالة:<syntaxhighlight lang="javascript"> | ||
class Cat extends Component {} | class Cat extends Component {} | ||
</syntaxhighlight>لمكونات الصنف | </syntaxhighlight>لمكونات الصنف دالةٌ باسم <code>()render</code>، ويُخرَج كل ما تعيده هذه الدالة كعنصر React:<syntaxhighlight lang="javascript"> | ||
class Cat extends Component { | class Cat extends Component { | ||
render() { | render() { | ||
سطر 75: | سطر 75: | ||
export default Cat; | export default Cat; | ||
</syntaxhighlight><blockquote>هذه إحدى الطرق العديدة لتصدير المكون الخاص بك، إذ يعمل هذا النوع من التصدير بصورةٍ جيدة مع أداة Snack Player التي تعمل على الإنترنت لتجربة الشيفرة على الفور. لكنك قد تحتاج إلى استخدام طريقة مختلفة بناءً على بنية ملف تطبيقك. يمكنك الاطلاع على [https:// | </syntaxhighlight><blockquote>هذه إحدى الطرق العديدة لتصدير المكون الخاص بك، إذ يعمل هذا النوع من التصدير بصورةٍ جيدة مع أداة [https://snack.expo.dev/@hsoubwiki/your-cat-class-component Snack Player] التي تعمل على الإنترنت لتجربة الشيفرة على الفور والتي نضع لك رابط لكل شيفرة لتجربتها مباشرة في كل هذا التوثيق. لكنك قد تحتاج إلى استخدام طريقة مختلفة بناءً على بنية ملف تطبيقك. يمكنك الاطلاع على [https://academy.hsoub.com/programming/javascript/%D8%AA%D8%B5%D8%AF%D9%8A%D8%B1-%D8%A7%D9%84%D9%88%D8%AD%D8%AF%D8%A7%D8%AA-%D9%88%D8%A7%D8%B3%D8%AA%D9%8A%D8%B1%D8%A7%D8%AF%D9%87%D8%A7-%D9%81%D9%8A-%D8%AC%D8%A7%D9%81%D8%A7%D8%B3%D9%83%D8%B1%D8%A8%D8%AA-r927/ طرق الاستيراد والتصدير في لغة JavaScript].</blockquote>لنلقِ نظرة على عبارة <code>return</code> وهي: <code><Text>Hello, I am your cat!</Text></code> التي تُعَد صياغةً بلغة [[JavaScript]] وتجعل كتابة العناصر مريحة، وهذه الصياغة هي JSX. | ||
== JSX == | |||
تستخدم React و React Native صياغة '''[[React/introducing jsx|JSX]]'''، وهي صياغة تتيح لك كتابة عناصر داخل شيفرة JavaScript مثل: <code><Text>Hello, I am your cat!</Text></code> . يمكن استخدام المتغيرات ضمن JSX لأنها شيفرة JavaScript. يصرّح المثال التالي عن اسم القطة <code>name</code> ويضمّنه داخل قوسين معقوصين في الوسم <code><Text></code>.<syntaxhighlight lang="javascript"> | |||
تستخدم React و React Native صياغة '''[[React/introducing jsx|JSX]]'''، وهي صياغة تتيح لك كتابة عناصر داخل شيفرة JavaScript مثل: <code><Text>Hello, I am your cat!</Text></code> . يمكن استخدام المتغيرات ضمن JSX لأنها شيفرة JavaScript. يصرّح المثال التالي عن اسم القطة <code>name</code> ويضمّنه داخل قوسين معقوصين في الوسم <code><Text></code>. | |||
إليك المثال ([https://snack.expo.dev/@hsoubwiki/curly-braces تجربة حية]):<syntaxhighlight lang="javascript"> | |||
import React from 'react'; | import React from 'react'; | ||
import { Text } from 'react-native'; | import { Text } from 'react-native'; | ||
سطر 90: | سطر 93: | ||
export default Cat; | export default Cat; | ||
</syntaxhighlight>سيُشغَّل أي تعبير بلغة JavaScript موجود بين القوسين المعقوصين بما في ذلك استدعاءات الدوال كالاستدعاء <code>{getFullName("Rum", "Tum", "Tugger")}</code>:<syntaxhighlight lang="javascript"> | </syntaxhighlight>سيُشغَّل أي تعبير بلغة JavaScript موجود بين القوسين المعقوصين بما في ذلك استدعاءات الدوال كالاستدعاء <code>{getFullName("Rum", "Tum", "Tugger")}</code>. | ||
إليك المثال ([https://snack.expo.dev/@hsoubwiki/curly-braces-2 تجربة حية]):<syntaxhighlight lang="javascript"> | |||
import React from 'react'; | import React from 'react'; | ||
import { Text } from 'react-native'; | import { Text } from 'react-native'; | ||
سطر 109: | سطر 114: | ||
</syntaxhighlight>يمكنك عدّ الأقواس المعقوصة كبوابة إلى جافاسكريبت ضمن JSX.<blockquote>تُضمَّن JSX في مكتبة React، وبالتالي فلن تعمل بصورة صحيحة إن لم تضع الترويسة <code>'import React from 'react</code> في أعلى الملف.</blockquote> | </syntaxhighlight>يمكنك عدّ الأقواس المعقوصة كبوابة إلى جافاسكريبت ضمن JSX.<blockquote>تُضمَّن JSX في مكتبة React، وبالتالي فلن تعمل بصورة صحيحة إن لم تضع الترويسة <code>'import React from 'react</code> في أعلى الملف.</blockquote> | ||
== المكونات المخصصة Custom Components == | |||
تحدثنا سابقًا عن [[ReactNative/intro react native components|مكونات React Native الأساسية]]، إذ تتيح مكتبة React أن تتداخل هذه المكونات ضمن بعضها البعض لإنشاء مكونات جديدة، وتُعَد هذه المكونات المتداخلة والقابلة لإعادة الاستخدام صميم نموذج React. | تحدثنا سابقًا عن [[ReactNative/intro react native components|مكونات React Native الأساسية]]، إذ تتيح مكتبة React أن تتداخل هذه المكونات ضمن بعضها البعض لإنشاء مكونات جديدة، وتُعَد هذه المكونات المتداخلة والقابلة لإعادة الاستخدام صميم نموذج React. | ||
يمكن وضع المكونين <code>Text</code> و <code>TextInput</code> داخل المكون <code>View</code> كما في المثال التالي، وتخرج render مكتبة React Native هذه المكونات معًا:<syntaxhighlight lang="javascript"> | يمكن وضع المكونين <code>Text</code> و <code>TextInput</code> داخل المكون <code>View</code> كما في المثال التالي، وتخرج render مكتبة React Native هذه المكونات معًا ([https://snack.expo.dev/@hsoubwiki/custom-components تجربة حية]):<syntaxhighlight lang="javascript"> | ||
import React from 'react'; | import React from 'react'; | ||
import { Text, TextInput, View } from 'react-native'; | import { Text, TextInput, View } from 'react-native'; | ||
سطر 135: | سطر 140: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== ملاحظات المطور === | |||
<blockquote>'''في نظام Android''': توضَع العروض views ضمن تخطيط <code>LinearLayout</code> أو <code>FrameLayout</code> أو <code>RelativeLayout</code> وما إلى ذلك من أجل تحديد طريقة ترتيب أبناء العرض view على الشاشة. يستخدم المكون <code>View</code> في React Native [[ReactNative/flexbox|التخطيط باستخدام Flexbox]] من أجل ترتيب المكونات الأبناء. | <blockquote>'''في نظام Android''': توضَع العروض views ضمن تخطيط <code>LinearLayout</code> أو <code>FrameLayout</code> أو <code>RelativeLayout</code> وما إلى ذلك من أجل تحديد طريقة ترتيب أبناء العرض view على الشاشة. يستخدم المكون <code>View</code> في React Native [[ReactNative/flexbox|التخطيط باستخدام Flexbox]] من أجل ترتيب المكونات الأبناء. أما في '''في الويب''': إن كنت على دراية بتطوير الويب، فقد يذكّرك المكوّنان <code><View></code> و <code><Text></code> بلغة [[HTML]]. يمكنك عدّ هذين المكوّنين وسومًا لتطوير التطبيقات مثل الوسمين <code><nowiki><div></nowiki></code> و <code><nowiki><p></nowiki></code> .</blockquote>يمكن إخراج المكون المخصَّص عدة مرات وبأماكن متعددة دون الحاجة إلى تكرار الشيفرة باستخدام <code><Cat></code> فقط، انظر المثال التالي ([https://snack.expo.dev/@hsoubwiki/multiple-components تجربة حية]):<syntaxhighlight lang="javascript"> | ||
'''في الويب''': إن كنت على دراية بتطوير الويب، فقد يذكّرك المكوّنان <code><View></code> و <code><Text></code> بلغة [[HTML]]. يمكنك عدّ هذين المكوّنين وسومًا لتطوير التطبيقات مثل الوسمين <code><nowiki><div></nowiki></code> و <code><nowiki><p></nowiki></code> .</blockquote>يمكن إخراج المكون المخصَّص عدة مرات وبأماكن متعددة دون الحاجة إلى تكرار الشيفرة باستخدام <code><Cat></code> | |||
import React from 'react'; | import React from 'react'; | ||
import { Text, TextInput, View } from 'react-native'; | import { Text, TextInput, View } from 'react-native'; | ||
سطر 164: | سطر 167: | ||
</syntaxhighlight>يُدعَى أي مكوّنٍ يخرج renders مكونًا آخر '''بالمكوّن الأب parent component'''، فالمكوّن <code>Cafe</code> هو المكون الأب في مثالنا وكل مكون <code>Cat</code> هو '''مكون ابن child component'''. يمكنك وضع العدد الذي تريده من المكونات <code>Cat</code> ضمن المكون <code>Cafe</code>، ويخرج كل مكون <code><Cat></code> عنصرًا مختلفًا عن غيره، إذ يمكنك تخصيص هذا العنصر باستخدام props. | </syntaxhighlight>يُدعَى أي مكوّنٍ يخرج renders مكونًا آخر '''بالمكوّن الأب parent component'''، فالمكوّن <code>Cafe</code> هو المكون الأب في مثالنا وكل مكون <code>Cat</code> هو '''مكون ابن child component'''. يمكنك وضع العدد الذي تريده من المكونات <code>Cat</code> ضمن المكون <code>Cafe</code>، ويخرج كل مكون <code><Cat></code> عنصرًا مختلفًا عن غيره، إذ يمكنك تخصيص هذا العنصر باستخدام props. | ||
== | == الخاصيات Props == | ||
Props هي اختصار للكلمة "properties" أي خصائص، وعملها مساعدتك على تخصيص مكوّنات React. تمرر كل <code><Cat></code> في المثال التالي اسمًا مختلفًا <code>name</code> للمكون <code>Cat</code> من أجل إخراجه:<syntaxhighlight lang="javascript"> | |||
Props هي اختصار للكلمة "properties" أي خصائص، وعملها مساعدتك على تخصيص مكوّنات [[React]]. تمرر كل <code><Cat></code> في المثال التالي اسمًا مختلفًا <code>name</code> للمكون <code>Cat</code> من أجل إخراجه ([https://snack.expo.dev/@hsoubwiki/multiple-props تجربة حية للمثال]):<syntaxhighlight lang="javascript"> | |||
import React from 'react'; | import React from 'react'; | ||
import { Text, View } from 'react-native'; | import { Text, View } from 'react-native'; | ||
سطر 188: | سطر 192: | ||
export default Cafe; | export default Cafe; | ||
</syntaxhighlight>يمكن تخصيص معظم مكونات React Native الأساسية باستخدام props أيضًا، كأن تمرر خاصيةً prop تدعى <code>source</code> عند استخدام المكون <code>Image</code> لتحديد الصورة المعروضة على سبيل المثال:<syntaxhighlight lang="javascript"> | </syntaxhighlight>يمكن تخصيص معظم مكونات React Native الأساسية باستخدام الخاصيات props أيضًا، كأن تمرر خاصيةً prop تدعى <code>source</code> عند استخدام المكون <code>Image</code> لتحديد الصورة المعروضة على سبيل المثال ([https://snack.expo.dev/@hsoubwiki/props تجربة حية]):<syntaxhighlight lang="javascript"> | ||
import React from 'react'; | import React from 'react'; | ||
import { Text, View, Image } from 'react-native'; | import { Text, View, Image } from 'react-native'; | ||
سطر 205: | سطر 209: | ||
export default CatApp; | export default CatApp; | ||
</syntaxhighlight>للمكون <code>Image</code> خصائص متعددة مختلفة بما في ذلك <code>style</code> التي يمكن أن تحتوي على كائن تصميم في لغة جافاسكريبت وأزواج قيمة-خاصية (property-value) متعلقة بالتخطيط.<blockquote>لاحظ وجود الأقواس المعقوصة المضاعفة <code><nowiki>{{ }}</nowiki></code> التي تحيط بخاصيات طول وعرض الخاصية <code>style</code>. يُشار إلى قيم JavaScript بقوسين معقوصين <code>{}</code> فقط ضمن JSX، وهذا مفيد عند تمرير شيءٍ آخر غير السلاسل string على أنه خصائص props، كتمرير مصفوفة array أو عدد: < | </syntaxhighlight>للمكون <code>Image</code> خصائص متعددة مختلفة بما في ذلك <code>style</code> التي يمكن أن تحتوي على كائن تصميم في لغة جافاسكريبت وأزواج قيمة-خاصية (property-value) متعلقة بالتخطيط.<blockquote>لاحظ وجود الأقواس المعقوصة المضاعفة <code><nowiki>{{ }}</nowiki></code> التي تحيط بخاصيات طول وعرض الخاصية <code>style</code>. يُشار إلى قيم JavaScript بقوسين معقوصين <code>{}</code> فقط ضمن JSX، وهذا مفيد عند تمرير شيءٍ آخر غير السلاسل string على أنه خصائص props، كتمرير مصفوفة array أو عدد: <syntaxhighlight lang="javascript"> | ||
<Cat food={["fish", "kibble"]} age={2} /> | |||
</syntaxhighlight>يُشار أيضًا إلى الكائنات المكتوبة بلغة جافاسكريبت باستخدام قوسين معقوصين: <code>{width: 200, height: 200}</code>، لذلك يجب تغليف كائن جافاسكريبت بقوسين معقوصين آخرين عند تمريره في JSX كما يلي: <code><nowiki>{{width: 200, height: 200}}</nowiki></code>.</blockquote>يمكنك بناء أشياء متعددة باستخدام الخاصيات props والمكونات الأساسية <code>Text</code> و <code>Image</code> و <code>View</code>، ولكنك ستحتاج الحالة state لبناء شيء تفاعلي. | |||
== الحالة State == | |||
يمكنك عدّ props كوسطاء تستخدمها لضبط كيفية إخراج المكونات، ولكن الحالة state شبيهة بتخزين بيانات المكون الشخصية، وتُعَد مفيدة لمعالجة البيانات التي تتغير بمرور الوقت أو التي تنشأ من تفاعل المستخدم، أي أن الحالة تعطي ذاكرةً لمكوناتك.<blockquote>يمكن بالحالة العامة استخدام props لضبط مكون عند إخراجه، واستخدام الحالة لتتبّع بيانات مكون تتوقّع تغيّرها بمرور الوقت.</blockquote>يحدث المثال التالي في | يمكنك عدّ الخاصيات props كوسطاء تستخدمها لضبط كيفية إخراج المكونات، ولكن الحالة state شبيهة بتخزين بيانات المكون الشخصية، وتُعَد مفيدة لمعالجة البيانات التي تتغير بمرور الوقت أو التي تنشأ من تفاعل المستخدم، أي أن الحالة تعطي ذاكرةً لمكوناتك.<blockquote>يمكن بالحالة العامة استخدام الخاصيات props لضبط مكون عند إخراجه، واستخدام الحالة لتتبّع بيانات مكون تتوقّع تغيّرها بمرور الوقت.</blockquote>يحدث المثال التالي في مقهًى للقطط حيث تنتظر قطتان جائعتان الطعام. نتوقع تغير جوع هاتين القطتين بمرور الوقت بعكس الاسم الذي لن تغير أبدًا، وبالتالي سيُخزَّن هذا الجوع كحالة. يمكنك الضغط على زرَي هاتين القطتين لإطعامهما، وبالتالي تتغير حالتهما. | ||
=== مكون الدالة Function Component === | |||
يمكن إضافة حالة لمكونٍ ما من خلال استدعاء [[React/hooks state|خطّاف React]] يُسمَّى <code>useState</code>. الخطاف [[React/hooks intro|Hook]] هو نوعٌ من الدوال التي تسمح بالربط بميزات مكتبة React مثل الخطاف <code>useState</code> الذي يتيح لك إضافة حالة إلى مكونات الدالة:<syntaxhighlight lang="javascript"> | يمكن إضافة حالة لمكونٍ ما من خلال استدعاء [[React/hooks state|خطّاف React]] يُسمَّى <code>useState</code>. الخطاف [[React/hooks intro|Hook]] هو نوعٌ من الدوال التي تسمح بالربط بميزات مكتبة React مثل الخطاف <code>useState</code> الذي يتيح لك إضافة حالة إلى مكونات الدالة. | ||
إليك المثال ([https://snack.expo.dev/@hsoubwiki/state-function-component تجربة حية]):<syntaxhighlight lang="javascript"> | |||
import React, { useState } from "react"; | import React, { useState } from "react"; | ||
import { Button, Text, View } from "react-native"; | import { Button, Text, View } from "react-native"; | ||
سطر 256: | سطر 264: | ||
* إنشاء دالة لضبط قيمة متغير الحالة، وهذه الدالة في مثالنا هي <code>setIsHungry</code>. | * إنشاء دالة لضبط قيمة متغير الحالة، وهذه الدالة في مثالنا هي <code>setIsHungry</code>. | ||
يمكنك استخدام الأسماء التي تريدها لمتغير الحالة وقيمته الابتدائية والدالة، لكن يُعَد استخدام النمط: <code> | يمكنك استخدام الأسماء التي تريدها لمتغير الحالة وقيمته الابتدائية والدالة، لكن يُعَد استخدام النمط: <code>[<getter>, <setter>] = useState(<initialValue>)</code> أسهل. | ||
ثم تضيف المكون الأساسي <code>Button</code> وأعطه خاصية <code>onPress</code>:<syntaxhighlight lang="javascript"> | ثم تضيف المكون الأساسي <code>Button</code> وأعطه خاصية <code>onPress</code>:<syntaxhighlight lang="javascript"> | ||
سطر 282: | سطر 290: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== مكون الصنف Class Component === | |||
يختلف نهج مكونات الصنف القديمة قليلًا عندما يتعلق الأمر | |||
يختلف نهج مكونات الصنف القديمة قليلًا عندما يتعلق الأمر بالحالة، إليك المثال ([https://snack.expo.dev/@hsoubwiki/state-and-class-components تجربة حية]):<syntaxhighlight lang="javascript"> | |||
import React, { Component } from "react"; | import React, { Component } from "react"; | ||
import { Button, Text, View } from "react-native"; | import { Button, Text, View } from "react-native"; | ||
سطر 330: | سطر 339: | ||
//.. | //.. | ||
} | } | ||
</syntaxhighlight>يمكن الوصول إلى props باستخدام العبارة <code>this.props</code> ، وكذلك يمكن الوصول إلى كائن الحالة ضمن المكون باستخدام العبارة <code>this.state</code>:<syntaxhighlight lang="javascript"> | </syntaxhighlight>يمكن الوصول إلى الخاصيات props باستخدام العبارة <code>this.props</code> ، وكذلك يمكن الوصول إلى كائن الحالة ضمن المكون باستخدام العبارة <code>this.state</code>:<syntaxhighlight lang="javascript"> | ||
<Text> | <Text> | ||
I am {this.props.name}, and I am | I am {this.props.name}, and I am | ||
سطر 342: | سطر 351: | ||
// .. | // .. | ||
/> | /> | ||
</syntaxhighlight><blockquote>لا تغيِّر حالة المكون الخاص بك مباشرةً من خلال إسناد قيمة جديدة إليها باستخدام العبارة <code>this.state.hunger = false</code>. يسمح استدعاء الدالة <code>()this.setState</code> لمكتبة React | </syntaxhighlight><blockquote>لا تغيِّر حالة المكون الخاص بك مباشرةً من خلال إسناد قيمة جديدة إليها باستخدام العبارة <code>this.state.hunger = false</code>. يسمح استدعاء الدالة <code>()this.setState</code> لمكتبة React بتتبّع التغيرات التي أجريت على الحالة التي تنبّه إعادة الإخراج أو التصيير rerendering. يمكن أن يؤدي إعداد الحالة مباشرةً إلى تعطيل تفاعل تطبيقك.</blockquote>تُضبَط قيمة الخاصية <code>disabled</code> الخاصة بالمكون <code>Button</code> وتتغير قيمة الخاصية <code>title</code> أيضًا، عندما تكون <code>this.state.isHungry</code> قيمتها <code>false</code>:<syntaxhighlight lang="javascript"> | ||
<Button | <Button | ||
// .. | // .. | ||
سطر 365: | سطر 374: | ||
export default Cafe; | export default Cafe; | ||
</syntaxhighlight>تُدعَى <code><></code> و <code></></code> بالأجزاء [[React/fragments|fragments]]. يجب أن تُغلَّف عناصر JSX المتجاورة بوسم يحيط بها، إذ تتيح لك هذه الأجزاء فعل ذلك دون | </syntaxhighlight>تُدعَى الرموز <code><></code> و <code></></code> بالأجزاء [[React/fragments|fragments]]. يجب أن تُغلَّف عناصر JSX المتجاورة بوسم يحيط بها، إذ تتيح لك هذه الأجزاء فعل ذلك دون تداخل عنصر تغليف إضافي غير ضروري مثل <code>View</code>. | ||
تعرّفنا على مكونات React و React Native الأساسية، فلنتعمّق أكثر في هذه المكونات من خلال [[ReactNative/handling text input|التعامل مع المدخلات النّصيّة <code><TextInput></code>]]. | تعرّفنا على مكونات [[React]] و React Native الأساسية، فلنتعمّق أكثر في هذه المكونات من خلال [[ReactNative/handling text input|التعامل مع المدخلات النّصيّة <code><TextInput></code>]]. | ||
== مصادر == | == مصادر == | ||
* [https://reactnative.dev/docs/intro-react صفحة React Fundamentals في توثيق React Native الرسمي.] | * [https://reactnative.dev/docs/intro-react صفحة React Fundamentals في توثيق React Native الرسمي.] | ||
[[تصنيف:ReactNative]] | |||
[[تصنيف:React Native Docs]] | |||
[[تصنيف:React]] |
المراجعة الحالية بتاريخ 13:34، 9 أكتوبر 2021
يُشغَّل إطار عمل React Native على مكتبة React، وهي مكتبة شائعة ومفتوحة المصدر تُستخدَم لبناء واجهات المستخدم باستخدام لغة JavaScript. يجب فهم React فهمًا جيدًا لتحقيق أقصى استفادة من React Native. تساعدك هذه الصفحة للبدء أو لاستذكار المفاهيم الأساسية من React والتي هي:
- المكونات components
- JXC
- props
- state
يمكنك الاطلاع على توثيق React، إن أردت التعمق أكثر.
المكون الأول
يستخدم المثال التالي المكون Cat
:
مكون الدالة Function component
إليك المثال التالي (تجربة حية):
import React from 'react';
import { Text } from 'react-native';
const Cat = () => {
return (
<Text>Hello, I am your cat!</Text>
);
}
export default Cat;
استخدم أولًا سطر import
لاستيراد مكون React و React Native الأساسي Text
لتعريف مكونك Cat
:
import React from 'react';
import { Text } from 'react-native';
يبدأ مكونك كدالة:
const Cat = () => {};
يمكن عد هذه المكونات كمخططات أساسية. يُخرَج ما يعيده مكون الدالة كعنصر React مهما كان ذلك الشيء المعاد، إذ تتيح لك عناصر React وصف ما تريد رؤيته على الشاشة.
فيما يلي سيُخرَج المكون Cat
كعنصر <Text>
:
const Cat = () => {
return <Text>Hello, I am your cat!</Text>;
};
يمكنك تصدير export مكون الدالة الخاص بك باستخدام إعداد تصدير JavaScript الافتراضي export default
، لاستخدامه في أي مكان ضمن تطبيقك كما يلي:
const Cat = () => {
return <Text>Hello, I am your cat!</Text>;
};
export default Cat;
مكون الصنف Class component
تميل مكونات الصنف إلى تكون مطوَّلةً أكثر من مكونات الدالة، انظر المثال التالي المماثل تمامًا للمثال السابق ولكن باستعمال مكون صنف (تجربة حية):
import React, { Component } from 'react';
import { Text } from 'react-native';
class Cat extends Component {
render() {
return (
<Text>Hello, I am your cat!</Text>
);
}
}
export default Cat;
يمكنك أيضًا استيراد الصنف Component
من React كما يلي:
import React, { Component } from 'react';
يبدأ المكون كصنفٍ يرث Component
بدلًا من أن يكون كدالة:
class Cat extends Component {}
لمكونات الصنف دالةٌ باسم ()render
، ويُخرَج كل ما تعيده هذه الدالة كعنصر React:
class Cat extends Component {
render() {
return <Text>Hello, I am your cat!</Text>;
}
}
يمكنك تصدير مكون الصنف كما هو الحال مع مكونات الدالة:
class Cat extends Component {
render() {
return <Text>Hello, I am your cat!</Text>;
}
}
export default Cat;
هذه إحدى الطرق العديدة لتصدير المكون الخاص بك، إذ يعمل هذا النوع من التصدير بصورةٍ جيدة مع أداة Snack Player التي تعمل على الإنترنت لتجربة الشيفرة على الفور والتي نضع لك رابط لكل شيفرة لتجربتها مباشرة في كل هذا التوثيق. لكنك قد تحتاج إلى استخدام طريقة مختلفة بناءً على بنية ملف تطبيقك. يمكنك الاطلاع على طرق الاستيراد والتصدير في لغة JavaScript.
لنلقِ نظرة على عبارة return
وهي: <Text>Hello, I am your cat!</Text>
التي تُعَد صياغةً بلغة JavaScript وتجعل كتابة العناصر مريحة، وهذه الصياغة هي JSX.
JSX
تستخدم React و React Native صياغة JSX، وهي صياغة تتيح لك كتابة عناصر داخل شيفرة JavaScript مثل: <Text>Hello, I am your cat!</Text>
. يمكن استخدام المتغيرات ضمن JSX لأنها شيفرة JavaScript. يصرّح المثال التالي عن اسم القطة name
ويضمّنه داخل قوسين معقوصين في الوسم <Text>
.
إليك المثال (تجربة حية):
import React from 'react';
import { Text } from 'react-native';
const Cat = () => {
const name = "Maru";
return (
<Text>Hello, I am {name}!</Text>
);
}
export default Cat;
سيُشغَّل أي تعبير بلغة JavaScript موجود بين القوسين المعقوصين بما في ذلك استدعاءات الدوال كالاستدعاء {getFullName("Rum", "Tum", "Tugger")}
.
إليك المثال (تجربة حية):
import React from 'react';
import { Text } from 'react-native';
const getFullName = (firstName, secondName, thirdName) => {
return firstName + " " + secondName + " " + thirdName;
}
const Cat = () => {
return (
<Text>
Hello, I am {getFullName("Rum", "Tum", "Tugger")}!
</Text>
);
}
export default Cat;
يمكنك عدّ الأقواس المعقوصة كبوابة إلى جافاسكريبت ضمن JSX.
تُضمَّن JSX في مكتبة React، وبالتالي فلن تعمل بصورة صحيحة إن لم تضع الترويسة
'import React from 'react
في أعلى الملف.
المكونات المخصصة Custom Components
تحدثنا سابقًا عن مكونات React Native الأساسية، إذ تتيح مكتبة React أن تتداخل هذه المكونات ضمن بعضها البعض لإنشاء مكونات جديدة، وتُعَد هذه المكونات المتداخلة والقابلة لإعادة الاستخدام صميم نموذج React.
يمكن وضع المكونين Text
و TextInput
داخل المكون View
كما في المثال التالي، وتخرج render مكتبة React Native هذه المكونات معًا (تجربة حية):
import React from 'react';
import { Text, TextInput, View } from 'react-native';
const Cat = () => {
return (
<View>
<Text>Hello, I am...</Text>
<TextInput
style={{
height: 40,
borderColor: 'gray',
borderWidth: 1
}}
defaultValue="Name me!"
/>
</View>
);
}
export default Cat;
ملاحظات المطور
في نظام Android: توضَع العروض views ضمن تخطيط
LinearLayout
أوFrameLayout
أوRelativeLayout
وما إلى ذلك من أجل تحديد طريقة ترتيب أبناء العرض view على الشاشة. يستخدم المكونView
في React Native التخطيط باستخدام Flexbox من أجل ترتيب المكونات الأبناء. أما في في الويب: إن كنت على دراية بتطوير الويب، فقد يذكّرك المكوّنان<View>
و<Text>
بلغة HTML. يمكنك عدّ هذين المكوّنين وسومًا لتطوير التطبيقات مثل الوسمين<div>
و<p>
.
يمكن إخراج المكون المخصَّص عدة مرات وبأماكن متعددة دون الحاجة إلى تكرار الشيفرة باستخدام <Cat>
فقط، انظر المثال التالي (تجربة حية):
import React from 'react';
import { Text, TextInput, View } from 'react-native';
const Cat = () => {
return (
<View>
<Text>I am also a cat!</Text>
</View>
);
}
const Cafe = () => {
return (
<View>
<Text>Welcome!</Text>
<Cat />
<Cat />
<Cat />
</View>
);
}
export default Cafe;
يُدعَى أي مكوّنٍ يخرج renders مكونًا آخر بالمكوّن الأب parent component، فالمكوّن Cafe
هو المكون الأب في مثالنا وكل مكون Cat
هو مكون ابن child component. يمكنك وضع العدد الذي تريده من المكونات Cat
ضمن المكون Cafe
، ويخرج كل مكون <Cat>
عنصرًا مختلفًا عن غيره، إذ يمكنك تخصيص هذا العنصر باستخدام props.
الخاصيات Props
Props هي اختصار للكلمة "properties" أي خصائص، وعملها مساعدتك على تخصيص مكوّنات React. تمرر كل <Cat>
في المثال التالي اسمًا مختلفًا name
للمكون Cat
من أجل إخراجه (تجربة حية للمثال):
import React from 'react';
import { Text, View } from 'react-native';
const Cat = (props) => {
return (
<View>
<Text>Hello, I am {props.name}!</Text>
</View>
);
}
const Cafe = () => {
return (
<View>
<Cat name="Maru" />
<Cat name="Jellylorum" />
<Cat name="Spot" />
</View>
);
}
export default Cafe;
يمكن تخصيص معظم مكونات React Native الأساسية باستخدام الخاصيات props أيضًا، كأن تمرر خاصيةً prop تدعى source
عند استخدام المكون Image
لتحديد الصورة المعروضة على سبيل المثال (تجربة حية):
import React from 'react';
import { Text, View, Image } from 'react-native';
const CatApp = () => {
return (
<View>
<Image
source={{uri: "https://reactnative.dev/docs/assets/p_cat1.png"}}
style={{width: 200, height: 200}}
/>
<Text>Hello, I am your cat!</Text>
</View>
);
}
export default CatApp;
للمكون Image
خصائص متعددة مختلفة بما في ذلك style
التي يمكن أن تحتوي على كائن تصميم في لغة جافاسكريبت وأزواج قيمة-خاصية (property-value) متعلقة بالتخطيط.
لاحظ وجود الأقواس المعقوصة المضاعفة
{{ }}
التي تحيط بخاصيات طول وعرض الخاصيةstyle
. يُشار إلى قيم JavaScript بقوسين معقوصين{}
فقط ضمن JSX، وهذا مفيد عند تمرير شيءٍ آخر غير السلاسل string على أنه خصائص props، كتمرير مصفوفة array أو عدد:<Cat food={["fish", "kibble"]} age={2} />يُشار أيضًا إلى الكائنات المكتوبة بلغة جافاسكريبت باستخدام قوسين معقوصين:
{width: 200, height: 200}
، لذلك يجب تغليف كائن جافاسكريبت بقوسين معقوصين آخرين عند تمريره في JSX كما يلي:{{width: 200, height: 200}}
.
يمكنك بناء أشياء متعددة باستخدام الخاصيات props والمكونات الأساسية Text
و Image
و View
، ولكنك ستحتاج الحالة state لبناء شيء تفاعلي.
الحالة State
يمكنك عدّ الخاصيات props كوسطاء تستخدمها لضبط كيفية إخراج المكونات، ولكن الحالة state شبيهة بتخزين بيانات المكون الشخصية، وتُعَد مفيدة لمعالجة البيانات التي تتغير بمرور الوقت أو التي تنشأ من تفاعل المستخدم، أي أن الحالة تعطي ذاكرةً لمكوناتك.
يمكن بالحالة العامة استخدام الخاصيات props لضبط مكون عند إخراجه، واستخدام الحالة لتتبّع بيانات مكون تتوقّع تغيّرها بمرور الوقت.
يحدث المثال التالي في مقهًى للقطط حيث تنتظر قطتان جائعتان الطعام. نتوقع تغير جوع هاتين القطتين بمرور الوقت بعكس الاسم الذي لن تغير أبدًا، وبالتالي سيُخزَّن هذا الجوع كحالة. يمكنك الضغط على زرَي هاتين القطتين لإطعامهما، وبالتالي تتغير حالتهما.
مكون الدالة Function Component
يمكن إضافة حالة لمكونٍ ما من خلال استدعاء خطّاف React يُسمَّى useState
. الخطاف Hook هو نوعٌ من الدوال التي تسمح بالربط بميزات مكتبة React مثل الخطاف useState
الذي يتيح لك إضافة حالة إلى مكونات الدالة.
إليك المثال (تجربة حية):
import React, { useState } from "react";
import { Button, Text, View } from "react-native";
const Cat = (props) => {
const [isHungry, setIsHungry] = useState(true);
return (
<View>
<Text>
I am {props.name}, and I am {isHungry ? "hungry" : "full"}!
</Text>
<Button
onPress={() => {
setIsHungry(false);
}}
disabled={!isHungry}
title={isHungry ? "Pour me some milk, please!" : "Thank you!"}
/>
</View>
);
}
const Cafe = () => {
return (
<>
<Cat name="Munkustrap" />
<Cat name="Spot" />
</>
);
}
export default Cafe;
يجب أولًا استيراد خطاف الحالة useState
من مكتبة React كما يلي:
import React, { useState } from 'react';
ثم يجب التصريح عن حالة المكون من خلال استدعاء useState
داخل دالة المكون. ينشئ الخطاف useState
متغير الحالة isHungry
:
const Cat = (props) => {
const [isHungry, setIsHungry] = useState(true);
// ...
};
يمكنك استخدام خطاف الحالة
useState
لتتبّع أي نوع بيانات كالسلاسل والأعداد والقيم البوليانية والمصفوفات والكائنات، إذ تستطيع تتبّع عدد مرات مداعبة القطة مثلًا من خلال استخدام العبارة:const [timesPetted, setTimesPetted] = useState(0)
.
يؤدي استدعاء الخطاف useState
إلى شيئين اثنين هما:
- إنشاء متغير حالة مع قيمة ابتدائية، فمتغير الحالة في مثالنا هو
isHungry
وقيمته الابتدائية هيtrue
. - إنشاء دالة لضبط قيمة متغير الحالة، وهذه الدالة في مثالنا هي
setIsHungry
.
يمكنك استخدام الأسماء التي تريدها لمتغير الحالة وقيمته الابتدائية والدالة، لكن يُعَد استخدام النمط: [<getter>, <setter>] = useState(<initialValue>)
أسهل.
ثم تضيف المكون الأساسي Button
وأعطه خاصية onPress
:
<Button
onPress={() => {
setIsHungry(false);
}}
//..
/>
إن ضغط أحدٌ ما الزر، فستُشغَّل الخاصية onPress
التي تستدعي الدالة setIsHungry(false)
، وهذا يضبط قيمة متغير الحالة isHungry
إلى القيمة false
. تُضبَط الخاصية disabled
المتعلقة بالمكون Button
إلى القيمة true
وتتغير الخاصية title
أيضًا، عندما تصبح قيمة متغير الحالة isHungry
:
<Button
//..
disabled={!isHungry}
title={isHungry ? 'Pour me some milk, please!' : 'Thank you!'}
/>
لاحظ أن متغير الحالة
isHungry
ثابتconst
، لكنه يبدو غير قابل لإعادة الإسناد. سيُعاد إخراج مكون دالة ضبط الحالة كالدالةsetIsHungry
عند استدعائها، وبالتالي ستُشغَّل دالة المكونCat
مرة أخرى وسيعطيuseState
متغير الحالةisHungry
القيمة التالية.
أخيرًا، ضع القطط ضمن مكون المقهى Cafe
كما يلي:
const Cafe = () => {
return (
<>
<Cat name="Munkustrap" />
<Cat name="Spot" />
</>
);
};
مكون الصنف Class Component
يختلف نهج مكونات الصنف القديمة قليلًا عندما يتعلق الأمر بالحالة، إليك المثال (تجربة حية):
import React, { Component } from "react";
import { Button, Text, View } from "react-native";
class Cat extends Component {
state = { isHungry: true };
render() {
return (
<View>
<Text>
I am {this.props.name}, and I am
{this.state.isHungry ? " hungry" : " full"}!
</Text>
<Button
onPress={() => {
this.setState({ isHungry: false });
}}
disabled={!this.state.isHungry}
title={
this.state.isHungry ? "Pour me some milk, please!" : "Thank you!"
}
/>
</View>
);
}
}
class Cafe extends Component {
render() {
return (
<>
<Cat name="Munkustrap" />
<Cat name="Spot" />
</>
);
}
}
export default Cafe;
يجب استيراد الصنف Component
من مكتبة React كما هو الحال دائمًا مع مكونات الصنف:
import React, { Component } from 'react';
وتُخزَّن الحالة ضمن كائن حالة في مكونات الصنف:
export class Cat extends Component {
state = { isHungry: true };
//..
}
يمكن الوصول إلى الخاصيات props باستخدام العبارة this.props
، وكذلك يمكن الوصول إلى كائن الحالة ضمن المكون باستخدام العبارة this.state
:
<Text>
I am {this.props.name}, and I am
{this.state.isHungry ? ' hungry' : ' full'}!
</Text>
وتُضبَط القيم الفردية في كائن الحالة من خلال تمرير كائن الزوج المفتاح-القيمة للحالة وتمرير قيمته الجديدة للدالة ()this.setState
:
<Button
onPress={() => {
this.setState({ isHungry: false });
}}
// ..
/>
لا تغيِّر حالة المكون الخاص بك مباشرةً من خلال إسناد قيمة جديدة إليها باستخدام العبارة
this.state.hunger = false
. يسمح استدعاء الدالة()this.setState
لمكتبة React بتتبّع التغيرات التي أجريت على الحالة التي تنبّه إعادة الإخراج أو التصيير rerendering. يمكن أن يؤدي إعداد الحالة مباشرةً إلى تعطيل تفاعل تطبيقك.
تُضبَط قيمة الخاصية disabled
الخاصة بالمكون Button
وتتغير قيمة الخاصية title
أيضًا، عندما تكون this.state.isHungry
قيمتها false
:
<Button
// ..
disabled={!this.state.isHungry}
title={
this.state.isHungry
? 'Pour me some milk, please!'
: 'Thank you!'
}
/>
أخيرًا، ضع القطط ضمن مكون المقهى Cafe
كما يلي:
class Cafe extends Component {
render() {
return (
<>
<Cat name="Munkustrap" />
<Cat name="Spot" />
</>
);
}
}
export default Cafe;
تُدعَى الرموز <>
و </>
بالأجزاء fragments. يجب أن تُغلَّف عناصر JSX المتجاورة بوسم يحيط بها، إذ تتيح لك هذه الأجزاء فعل ذلك دون تداخل عنصر تغليف إضافي غير ضروري مثل View
.
تعرّفنا على مكونات React و React Native الأساسية، فلنتعمّق أكثر في هذه المكونات من خلال التعامل مع المدخلات النّصيّة <TextInput>
.