Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Done Translating-hooks-custom.md #63

Merged
merged 2 commits into from
Jun 25, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
70 changes: 35 additions & 35 deletions content/docs/hooks-custom.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
---
id: hooks-custom
title: Building Your Own Hooks
title: بناء خطافات خاصة بك في React
permalink: docs/hooks-custom.html
next: hooks-reference.html
prev: hooks-rules.html
---

*Hooks* are a new addition in React 16.8. They let you use state and other React features without writing a class.
*الخطافات* هي إضافة جديدة إلى الإصدار 16.8 في React، إذ تسمح لك باستعمال ميزة الحالة وميزات React الأخرى دون كتابة أي صنف.

Building your own Hooks lets you extract component logic into reusable functions.
بناء خطافات خاصة بك تمكِّنك من استخراج شيفرة من مكون ما إلى دوال قابلة لإعادة الاستعمال.

When we were learning about [using the Effect Hook](/docs/hooks-effect.html#example-using-hooks-1), we saw this component from a chat application that displays a message indicating whether a friend is online or offline:
عندما تعلمنا كيفية [استعمال خطاف التأثير](/docs/hooks-effect.html#example-using-hooks-1), رأينا المكون الآتي من تطبيق محادثة يعرض رسالة تشير إلى حالة اتصال صديق أي إن كان متصلًا أم غير متصل:

```js{4-15}
import React, { useState, useEffect } from 'react';
Expand All @@ -36,7 +36,7 @@ function FriendStatus(props) {
}
```

Now let's say that our chat application also has a contact list, and we want to render names of online users with a green color. We could copy and paste similar logic above into our `FriendListItem` component but it wouldn't be ideal:
الآن، لنقل أنَّ تطبيق الدردشة هذا يملك قائمة اتصال (contact list)، وأردنا تصيير أسماء المستخدمين المتصلين بلون أخضر. يمكننا نسخ ولصق شيفرة مشابهة إلى المكون `FriendListItem` ولكن لن يكون ذلك جيدًا من الناحية المثالية:

```js{4-15}
import React, { useState, useEffect } from 'react';
Expand All @@ -63,15 +63,15 @@ function FriendListItem(props) {
}
```

Instead, we'd like to share this logic between `FriendStatus` and `FriendListItem`.
عوضًا عن ذلك، نريد أن نشارك هذه الشيفرة بين `FriendStatus` و `FriendListItem`.

Traditionally in React, we've had two popular ways to share stateful logic between components: [render props](/docs/render-props.html) and [higher-order components](/docs/higher-order-components.html). We will now look at how Hooks solve many of the same problems without forcing you to add more components to the tree.
تقليديًّا في React، يمكننا مشاركة شيفرة ذات حالة بين المكونات عبر طريقتين مشهورتين هما: [خاصيَّات التصيير](/docs/render-props.html) و [المكونات ذات الترتيب الأعلى](/docs/higher-order-components.html). سنتعلَّم الآن كيف يمكن للخطافات أن تحل العديد من هذه المشكلات الشبيهة دون إجبارك على إضافة المزيد من المكونات إلى الشجرة.

## Extracting a Custom Hook {#extracting-a-custom-hook}
## استخراج خطاف مخصص {#extracting-a-custom-hook}

When we want to share logic between two JavaScript functions, we extract it to a third function. Both components and Hooks are functions, so this works for them too!
عندما نريد مشاركة شيفرة بين دالتين من دوال JavaScript، نستخرج هذه الشيفرة إلى دالة ثالثة. ولمَّا كانت المكونات والخطافات هي دوال، فهذا ينطبق عليها أيضًا.

**A custom Hook is a JavaScript function whose name starts with "`use`" and that may call other Hooks.** For example, `useFriendStatus` below is our first custom Hook:
**الخطاف المخصص هو دالة JavaScript يبدأ اسمها بالكلمة "`use`" وقد تستدعي خطافات أخرى ضمنه.** على سبيل المثال، الدالة `useFriendStatus` في الشيفرة التالية هي أول خطاف مخصص ننشئه:

```js{3}
import React, { useState, useEffect } from 'react';
Expand All @@ -94,11 +94,11 @@ function useFriendStatus(friendID) {
}
```

There's nothing new inside of it -- the logic is copied from the components above. Just like in a component, make sure to only call other Hooks unconditionally at the top level of your custom Hook.
لا يوجد أي شيء جديد في هذه الشيفرة، إذ نُسِخَ معظمها من مكونات الشيفرة السابقة. بشكل مشابه لمكون، احرص على استدعاء الخطافات الأخرى في أعلى مستوى في الخطاف المخصص، دون وضعها ضمن عبارات شرطية مثلًا.

Unlike a React component, a custom Hook doesn't need to have a specific signature. We can decide what it takes as arguments, and what, if anything, it should return. In other words, it's just like a normal function. Its name should always start with `use` so that you can tell at a glance that the [rules of Hooks](/docs/hooks-rules.html) apply to it.
وبشكل مخالف لمكونات React، لا يحتاج الخطاف المخصص إلى توقيع محدَّد. يمكننا تحديد الوسائط التي سيأخذها والقيم التي سيعيدها (إن وجدت). بعبارة أخرى، الخطافات المخصصة تشبه أية دالة عادية باستثناء أنَّ اسمها يجب أن يبدأ بالكلمة `use` دومًا، لذا يمكنك من خلال النظر إلى الشيفرة معرفة إن كانت [قواعد الخطافات](/docs/hooks-rules.html) تنطبق عليها بشكل صحيح أم لا.

The purpose of our `useFriendStatus` Hook is to subscribe us to a friend's status. This is why it takes `friendID` as an argument, and returns whether this friend is online:
الغرض من الخطاف `useFriendStatus` هو الاشتراك في حالة صديق، وهذا هو سبب تمرير `friendID` سيطًا له وإعادة حالة اتصال ذلك الصديق منه (فيما إذا كان متصلًا أم غير متصل):

```js
function useFriendStatus(friendID) {
Expand All @@ -110,13 +110,13 @@ function useFriendStatus(friendID) {
}
```

Now let's see how we can use our custom Hook.
الآن، دعنا نرى كيف يمكننا استعمال هذا الخطاف المخصص.

## Using a Custom Hook {#using-a-custom-hook}
## استعمال خطاف مخصص {#using-a-custom-hook}

In the beginning, our stated goal was to remove the duplicated logic from the `FriendStatus` and `FriendListItem` components. Both of them want to know whether a friend is online.
في البداية، كان هدفنا الواضح هو إزالة الشيفرة المكررة من المكونين `FriendStatus` و `FriendListItem` لأنَّ كلاهما يريد معرفة حالة اتصال صديق.

Now that we've extracted this logic to a `useFriendStatus` hook, we can *just use it:*
الآن وبعد أن استخرجنا هذه الشيفرة إلى الخطاف `useFriendStatus` ، يمكننا استعماله ببساطة بالشكل التالي:

```js{2}
function FriendStatus(props) {
Expand All @@ -141,19 +141,19 @@ function FriendListItem(props) {
}
```

**Is this code equivalent to the original examples?** Yes, it works in exactly the same way. If you look closely, you'll notice we didn't make any changes to the behavior. All we did was to extract some common code between two functions into a separate function. **Custom Hooks are a convention that naturally follows from the design of Hooks, rather than a React feature.**
**هل تكافئ هذه الشيفرة الأمثلة الأصلية؟** نعم، تكافئها وتعمل بالطريقة نفسها. إن أمعنت النظر، فستلاحظ أنَّنا لم نجرِ أية تغييرات متعلقة بالسلوك. فكل ما فعلنا هو استخراج الشيفرة المتشابهة بين دالتين إلى دالة منفصلة. **الخطافات المخصَّصة هي عُرفٌ يتَّبِع تصميم الخطافات نفسها وليس ذلك من ميزات React.**

**Do I have to name my custom Hooks starting with “`use`”?** Please do. This convention is very important. Without it, we wouldn't be able to automatically check for violations of [rules of Hooks](/docs/hooks-rules.html) because we couldn't tell if a certain function contains calls to Hooks inside of it.
**هل يتوجَّب عليَّ استعمال السابقة “`use`” عند تسمية الخطافات المخصصة؟** ليس ذلك إجباريًا، وإنما اختياري، لكن من الضروري فعل ذلك لجعلها أسهل لبقية المطورين. هذا العرف مهم جدًا، إذ لن نتمكن بدونه من التحقق من تطبيق [قواعد الخطافات](/docs/hooks-rules.html) تلقائيًّا لأنَّه لا يمكننا التفريق بين الدوال التي تحوي استدعاءات لخطافات داخلها وتلك التي لا تحوي عليها.

**Do two components using the same Hook share state?** No. Custom Hooks are a mechanism to reuse *stateful logic* (such as setting up a subscription and remembering the current value), but every time you use a custom Hook, all state and effects inside of it are fully isolated.
**هل يتشارك مكونان اثنان يستعملان نفس الخطاف الحالة؟** لا. الخطافات المخصَّصة هي آلية لإعادة استعمال شيفرة ذات حالة (مثل ضبط اشتراك وحفظ القيمة الحالية)، ولكن تبقى جميع الحالات والتأثيرات داخل خطاف مخصَّص معزولةً تمامًا في كل مرة تستعمل هذا الخطاف فيها.

**How does a custom Hook get isolated state?** Each *call* to a Hook gets isolated state. Because we call `useFriendStatus` directly, from React's point of view our component just calls `useState` and `useEffect`. And as we [learned](/docs/hooks-state.html#tip-using-multiple-state-variables) [earlier](/docs/hooks-effect.html#tip-use-multiple-effects-to-separate-concerns), we can call `useState` and `useEffect` many times in one component, and they will be completely independent.
**كيف يحصل خطاف مخصَّص على حالة معزولة؟** يحصل كل خطاف عند استدعائه على حالة معزولة. ولمَّا كنا استدعينا الخطاف `useFriendStatus` مباشرةً، فإن المكون من وجهة نظر React يستدعي `useState` و `useEffect` فقط. وكما [تعلمنا](/docs/hooks-state.html#tip-using-multiple-state-variables) [سابقًا](/docs/hooks-effect.html#tip-use-multiple-effects-to-separate-concerns), يمكننا استدعاء `useState` و `useEffect` عدَّة مرات في مكون واحد، وسيكون كل منها مستقلًا كليًّا.

### Tip: Pass Information Between Hooks {#tip-pass-information-between-hooks}
### تمرير معلومات بين الخطافاتلمَّا كانت الخطافات دوالًا، يمكننا تمرير معلومات بينها. {#tip-pass-information-between-hooks}

Since Hooks are functions, we can pass information between them.
لمَّا كانت الخطافات دوالًا، يمكننا تمرير معلومات بينها.

To illustrate this, we'll use another component from our hypothetical chat example. This is a chat message recipient picker that displays whether the currently selected friend is online:
لتوضيح ذلك عمليًّا، سنستعمل مكونًا آخر من مثال تطبيق الدردشة الافتراضي. الشيفرة التالية هي منتقي مستلم رسالة الدردشة والتي تظهر فيما إذا كان الصديق المحدَّد حاليًا متصلًا:

```js{8-9,13}
const friendList = [
Expand Down Expand Up @@ -184,24 +184,24 @@ function ChatRecipientPicker() {
}
```

We keep the currently chosen friend ID in the `recipientID` state variable, and update it if the user chooses a different friend in the `<select>` picker.
نُبقِي معرِّف الصديق المختار حاليًا في متغير الحالة `recipientID` ونحدِّثه إن اختار المستخدم صديقًا آخر من المنتقي `<select>`.

Because the `useState` Hook call gives us the latest value of the `recipientID` state variable, we can pass it to our custom `useFriendStatus` Hook as an argument:
لمَّا كان استدعاء الخطاف `useState` يعطينا القيمة الأحدث لمتغير الحالة `recipientID` فيمكننا تمريرها إلى خطافنا المخصَّص `useFriendStatus` كوسيط بالشكل التالي:

```js
const [recipientID, setRecipientID] = useState(1);
const isRecipientOnline = useFriendStatus(recipientID);
```

This lets us know whether the *currently selected* friend is online. If we pick a different friend and update the `recipientID` state variable, our `useFriendStatus` Hook will unsubscribe from the previously selected friend, and subscribe to the status of the newly selected one.
هذا يمكِّننا من معرفة إذا كان الصديق المحدَّد حاليًا متصلًا أم لا. إن اخترنا صديقًا آخر وحدَّثنا متغير الحالة `recipientID`, فسيلغي الخطاف `useFriendStatus` الاشتراك من الصديق المحدَّد سابقًا، ويشترك في حالة الصديق الذي جرى تحديده للتو.

## `useYourImagination()` {#useyourimagination}
## `استعمل-مخيلتك()` {#useyourimagination}

Custom Hooks offer the flexibility of sharing logic that wasn't possible in React components before. You can write custom Hooks that cover a wide range of use cases like form handling, animation, declarative subscriptions, timers, and probably many more we haven't considered. What's more, you can build Hooks that are just as easy to use as React's built-in features.
توفر الخطافات المخصَّصة مرونةً لتشارك الشيفرة لم تكن متوافرة مع مكونات React من قبل. تستطيع أن تكتب خطافات مخصَّصة تغطي مجالًا واسعًا من حالات الاستعمال مثل المعالجة (handling)، والتحريك، والاشتراكات التصريحية (declarative subscriptions)، والمؤقتات، وغيرها الكثير من الأمور التي لم نتطرق لها. أضف إلى ذلك أنَّه يمكنك بناء خطافات يمكن استعمالها بسهولة كما يمكن استعمال ميزات React الضمنية.

Try to resist adding abstraction too early. Now that function components can do more, it's likely that the average function component in your codebase will become longer. This is normal -- don't feel like you *have to* immediately split it into Hooks. But we also encourage you to start spotting cases where a custom Hook could hide complex logic behind a simple interface, or help untangle a messy component.
حاول مثلًا منع إضافة تجريد (abstraction) في وقت سابق جدًا لأوانه. بذلك، يمكن لمكونات الدالة تلك فعل ذلك بإضافةً إلى المزيد من الأمور، إذ من المحتمل أن متوسط مكون الدالة في شيفرتك المصدرية سيزداد طولًا. هذا الأمر طبيعي، فلا تشعر بسرعة أنَّك بحاجة إلى تقسيم الشيفرة إلى خطافات. على أي حال، نشجعك على البدء بتسليط الضوء على الحالات التي يمكن لاستعمال خطاف مخصص فيها أن يخفي تعقيد الشيفرة خلف واجهة بسيطة، أو يساعد على ترتيب مكوِّن فوضوي.

For example, maybe you have a complex component that contains a lot of local state that is managed in an ad-hoc way. `useState` doesn't make centralizing the update logic any easier so you might prefer to write it as a [Redux](https://redux.js.org/) reducer:
على سبيل المثال، ربما تملك مكونًا معقدًا يحوي الكثير من الحالات المحلية التي تدار بطريقة مخصصة. ولكن الخطاف `useState` لا يجعل مركزية تحديث الشيفرة أسهل، لذا قد تفضِّل كتابتها عل شكل مخفِّض (reducer) باستعمال المكتبة [Redux](https://redux.js.org/) reducer:

```js
function todosReducer(state, action) {
Expand All @@ -218,9 +218,9 @@ function todosReducer(state, action) {
}
```

Reducers are very convenient to test in isolation, and scale to express complex update logic. You can further break them apart into smaller reducers if necessary. However, you might also enjoy the benefits of using React local state, or might not want to install another library.
المخفضات مناسبة جدًا للاختبار في بيئة منعزلة، ويمكنها أن تعبِّر عن شيفرة معقدة للتحديث. يمكنك أيضًا تقسيمها إلى أجزاء تمثِّل مخفضات أصغر إن كان ذلك ضروريًا. على أي حال، قد تجد في فوائد استعمال حالة React المحلية (أي React local state) أمرًا ممتعًا، أو قد لا ترغب في تثبيت مكتبة أخرى.

So what if we could write a `useReducer` Hook that lets us manage the *local* state of our component with a reducer? A simplified version of it might look like this:
ذًا، ماذا لو استطعنا كتابة الخطاف `useReducer` بشكل يمكِّننا من إدارة الحالة المحلية للمكون الخاص بنا مع مخفِّض؟ نسخةٌ مبسَّطةٌ من ذلك قد تبدو بالشكل:

```js
function useReducer(reducer, initialState) {
Expand All @@ -235,7 +235,7 @@ function useReducer(reducer, initialState) {
}
```

Now we could use it in our component, and let the reducer drive its state management:
يمكننا الآن استعماله في مكوِّننا لنترك المخفض (reducer) يتولى مهمة إدارة حالته:

```js{2}
function Todos() {
Expand All @@ -249,4 +249,4 @@ function Todos() {
}
```

The need to manage local state with a reducer in a complex component is common enough that we've built the `useReducer` Hook right into React. You'll find it together with other built-in Hooks in the [Hooks API reference](/docs/hooks-reference.html).
الحاجة لإدارة حالة محلية مع مخفِّض في مكون معقد هو أمرٌ شائعٌ، لذا بنينا الخطاف `useReducer` ضمنيًا في React. ستجد هذا الخطاف مع بقية الخطافات المضمَّنة الأخرى في قسم [مرجع إلى الواجهة البرمجية للخطافات](/docs/hooks-reference.html).