diff --git a/content/docs/nav.yml b/content/docs/nav.yml index 49f7c2ef2..21f238099 100644 --- a/content/docs/nav.yml +++ b/content/docs/nav.yml @@ -68,7 +68,7 @@ - id: refs-and-the-dom title: Refs and the DOM - id: render-props - title: Render Props + title: خاصيات التصيير - id: static-type-checking title: Static Type Checking - id: strict-mode diff --git a/content/docs/render-props.md b/content/docs/render-props.md index e1482f491..4152071e0 100644 --- a/content/docs/render-props.md +++ b/content/docs/render-props.md @@ -1,28 +1,28 @@ --- id: render-props -title: Render Props +title: خاصيات التصيير permalink: docs/render-props.html --- -The term ["render prop"](https://cdb.reacttraining.com/use-a-render-prop-50de598f11ce) refers to a technique for sharing code between React components using a prop whose value is a function. +يُشير مصطلح [خاصيّة التصيير (render prop)](https://cdb.reacttraining.com/use-a-render-prop-50de598f11ce) إلى تقنية بسيطة لمشاركة الشيفرة بين مكوّنات React باستخدام خاصية والتي قيمتها هي عبارة عن دالة. -A component with a render prop takes a function that returns a React element and calls it instead of implementing its own render logic. +يأخذ المكوّن الذي يمتلك خاصيّة تصيير دالة تُعيد عنصر React ويستدعيها بدلًا من تنفيذ منطق التصيير الخاص به. ```jsx ( -

Hello {data.target}

+

أهلا {data.target}

)}/> ``` -Libraries that use render props include [React Router](https://reacttraining.com/react-router/web/api/Route/render-func) and [Downshift](https://github.com/paypal/downshift). +تتضمّن المكتبات التي تستخدم خاصيّات التصيير [React Router](https://reacttraining.com/react-router/web/api/Route/render-func) و [Downshift](https://github.com/paypal/downshift). -In this document, we’ll discuss why render props are useful, and how to write your own. +سنناقش في هذه الصفحة فائدة خاصيّات التصيير وكيفية كتابة خاصيّات التصيير الخاصّة بك. -## Use Render Props for Cross-Cutting Concerns {#use-render-props-for-cross-cutting-concerns} +## استخدام خاصيّات التصيير للاهتمامات المشتركة{#use-render-props-for-cross-cutting-concerns} -Components are the primary unit of code reuse in React, but it's not always obvious how to share the state or behavior that one component encapsulates to other components that need that same state. +تُعد المكوّنات الوحدة الأساسية من الشيفرة القابلة لإعادة الاستخدام في React، ولكن ليس من الواضح كيفيّة مشاركة الحالة أو السلوك من مكوّن إلى مكوّن آخر يحتاج نفس الحالة. -For example, the following component tracks the mouse position in a web app: +على سبيل المثال يتتبع المكوّن التالي موقع الفأرة في تطبيق الويب: ```js class MouseTracker extends React.Component { @@ -42,22 +42,22 @@ class MouseTracker extends React.Component { render() { return (
-

Move the mouse around!

-

The current mouse position is ({this.state.x}, {this.state.y})

+

حرك الفأرة!

+

موقع الفأرة الحالي هو ({this.state.x}, {this.state.y})

); } } ``` -As the cursor moves around the screen, the component displays its (x, y) coordinates in a `

`. +بينما يتحرك المؤشر على الشاشة، يعرض المكوّن إحداثياته (x, y) ضمن العنصر `

`. -Now the question is: How can we reuse this behavior in another component? In other words, if another component needs to know about the cursor position, can we encapsulate that behavior so that we can easily share it with that component? +السؤال الآن هو كيفيّة إعادة استخدام هذا السلوك في مكوّن آخر؟ أي بمعنى آخر إن احتاج مكوّن آخر إلى معرفة مكان المؤشر، فهل نستطيع تغليف هذا السلوك لمشاركته بسهولة مع ذلك المكوّن؟ -Since components are the basic unit of code reuse in React, let's try refactoring the code a bit to use a `` component that encapsulates the behavior we need to reuse elsewhere. +بما أن المكوّنات هي الوحدة الأساسية في React لإعادة استخدام الشيفرة، فلنجرّب إعادة ترتيب الشيفرة قليلًا لتستخدم المكوّن `‎`‎ والذي يُغلِّف السلوك الذي نريد إعادة استخدامه في مكان ما: ```js -// The component encapsulates the behavior we need... +// يغلف المكون السلوك الذي نحتاجه class Mouse extends React.Component { constructor(props) { super(props); @@ -76,8 +76,8 @@ class Mouse extends React.Component { return (

- {/* ...but how do we render something other than a

? */} -

The current mouse position is ({this.state.x}, {this.state.y})

+ {/* ؟

ولكن كيف نصيّر شيء آخر غير العنصر... */} +

موقع الفأرة الحالي هو ({this.state.x}, {this.state.y})

); } @@ -87,7 +87,7 @@ class MouseTracker extends React.Component { render() { return (
-

Move the mouse around!

+

حرك الفأرة!

); @@ -95,11 +95,11 @@ class MouseTracker extends React.Component { } ``` -Now the `` component encapsulates all behavior associated with listening for `mousemove` events and storing the (x, y) position of the cursor, but it's not yet truly reusable. +يُغلِّف المكوّن `‎‎` الآن السلوك المرتبط بالاستماع إلى أحداث تحريك الفأرة `mousemove` وتخزين إحداثيات (x, y) لموقع المؤشر، ولكنّه ليس قابلًا لإعادة الاستخدام حتى الآن. -For example, let's say we have a `` component that renders the image of a cat chasing the mouse around the screen. We might use a `` prop to tell the component the coordinates of the mouse so it knows where to position the image on the screen. +فلنفترض أننا نمتلك المكوّن `‎`‎ والذي يُصيِّر صورة لقطة تُطارِد الفأرة ضمن الشاشة. بإمكاننا استخدام الخاصيّة ‎``‎ لإخبار المكوّن بإحداثيات الفأرة بحيث تعلم أي تضع الصورة في الشاشة. -As a first pass, you might try rendering the `` *inside ``'s `render` method*, like this: +كمحاولة أولى جرّب تصيير المكوّن ‎``‎ *بداخل تابع التصيير للمكوّن ‎``‎* كما يلي: ```js class Cat extends React.Component { @@ -130,10 +130,9 @@ class MouseWithCat extends React.Component {
{/* - We could just swap out the

for a here ... but then - we would need to create a separate - component every time we need to use it, so - isn't really reusable yet. + كان بإمكاننا فقط تبديل العنصر p بالمكون هنا + ولكن سيتوجب علينا إنشاء مكون منفصل + في كل مرة نحتاج لاستخدامه. لذا لن يكون قابلًا لإعادة الاستخدام حتى الآن */}

@@ -145,7 +144,7 @@ class MouseTracker extends React.Component { render() { return (
-

Move the mouse around!

+

حرك الفأرة!

); @@ -153,9 +152,10 @@ class MouseTracker extends React.Component { } ``` -This approach will work for our specific use case, but we haven't achieved the objective of truly encapsulating the behavior in a reusable way. Now, every time we want the mouse position for a different use case, we have to create a new component (i.e. essentially another ``) that renders something specifically for that use case. +ستعمل هذه الطريقة لحالتنا، لكننا لم نحقق حتى الآن هدفنا الحقيقي من تغليف هذا السلوك بطريقة قابلة لإعادة الاستخدام، ففي كل مرة نريد فيها الحصول على موقع الفأرة لحالة استخدام مختلفة يجب علينا إنشاء مكوّن جديد (وهو `‎‎`) والذي يُصيِّر شيء ما مُخصَّص لتلك الحالة. + +هنا تأتي فائدة خاصيّات التصيير، فبدلًا من كتابة المكوّن `‎‎` بشكل حرفي في المكوّن `‎‎` وتغيير ناتجه، بإمكاننا تزويد المكوّن `‎‎` بخاصيّة على شكل دالة تستخدمها لتحدد بشكل ديناميكي ما هي خاصيّة التصيير. -Here's where the render prop comes in: Instead of hard-coding a `` inside a `` component, and effectively changing its rendered output, we can provide `` with a function prop that it uses to dynamically determine what to render–a render prop. ```js class Cat extends React.Component { @@ -186,8 +186,8 @@ class Mouse extends React.Component {
{/* - Instead of providing a static representation of what renders, - use the `render` prop to dynamically determine what to render. + بدلًا من تزويد تمثيل ثابت لما يصيره المكون + استخدم خاصية التصيير لتحدد بشكل دينامكي ما الذي ينبغي تصييره */} {this.props.render(this.state)}
@@ -199,7 +199,7 @@ class MouseTracker extends React.Component { render() { return (
-

Move the mouse around!

+

حرك الفأرة!

( )}/> @@ -209,17 +209,17 @@ class MouseTracker extends React.Component { } ``` -Now, instead of effectively cloning the `` component and hard-coding something else in its `render` method to solve for a specific use case, we provide a `render` prop that `` can use to dynamically determine what it renders. +والآن بدلًا من نسخ المكوّن `` وكتابة شيفرة حرفية بداخل التابع `render` الخاص به لحل المشكلة لحالة محددة، فسنُزوِّد خاصيّة `render` والتي يستخدمها` ` ليحدد بشكل ديناميكي ما الذي ينبغي تصييره. -More concretely, **a render prop is a function prop that a component uses to know what to render.** +بشكل أصح، **خاصية التصيير هي دالة يستخدمها المكوّن ليعلم ما يجب تصييره**. -This technique makes the behavior that we need to share extremely portable. To get that behavior, render a `` with a `render` prop that tells it what to render with the current (x, y) of the cursor. +تجعل هذه التقنية من السلوك الذي نحتاجه للمشاركة قابلًا للنقل بسهولة. للحصول على هذا السلوك صيِّر المكوّن `` مع خاصيّة `render` والتي تخبره ما يجب عليه تصييره مع الإحداثيات الحالية للمؤشر. -One interesting thing to note about render props is that you can implement most [higher-order components](/docs/higher-order-components.html) (HOC) using a regular component with a render prop. For example, if you would prefer to have a `withMouse` HOC instead of a `` component, you could easily create one using a regular `` with a render prop: +من الأشياء المثيرة للاهتمام التي تميّز خاصيّات التصيير هي أنّه بإمكانك تطبيقه على [المكوّنات ذات الترتيب الأعلى (higher-order components)](/docs/higher-order-components.html) باستخدام مكوّن اعتيادي مع خاصيّة تصيير. على سبيل المثال إن كنت تفضل أن يكون لديك المكوّن ذو الترتيب الأعلى `withMouse` بدلًا من المكوّن ‎``‎ فبإمكانك بسهولة إنشاء واحد باستخدام المكوّن `‎`‎ مع خاصيّة تصيير: ```js -// If you really want a HOC for some reason, you can easily -// create one using a regular component with a render prop! +// إن أردت حقا مكون ذو ترتيب أعلى فبإمكانك بسهولة +// إنشاء واحد باستخدام مكوّن عادي مع خاصية تصيير function withMouse(Component) { return class extends React.Component { render() { @@ -233,33 +233,33 @@ function withMouse(Component) { } ``` -So using a render prop makes it possible to use either pattern. +لذا من الممكن باستخدام خاصية التصيير الانتقال إلى نمط آخر. -## Using Props Other Than `render` {#using-props-other-than-render} +## استخدام خاصيات أخرى غير `render` {#using-props-other-than-render} -It's important to remember that just because the pattern is called "render props" you don't *have to use a prop named `render` to use this pattern*. In fact, [*any* prop that is a function that a component uses to know what to render is technically a "render prop"](https://cdb.reacttraining.com/use-a-render-prop-50de598f11ce). +من الهام معرفة أنّه ليس بالضرورة إذا كان اسم هذا النمط خاصيّات التصيير (render props) أن تستخدم الخاصيّة التي اسمها `render`. ففي الحقيقة [أي دالة يستخدمها المكوّن ليعرف ما الذي ينبغي تصييره هي عمليًّا خاصيّة تصيير](https://cdb.reacttraining.com/use-a-render-prop-50de598f11ce). -Although the examples above use `render`, we could just as easily use the `children` prop! +على الرغم من استخدام المثال السابق للاسم `render` فبإمكاننا استخدام أي اسم مثل الخاصيّة `children`: ```js ( -

The mouse position is {mouse.x}, {mouse.y}

+

موقع الفأرة هو {mouse.x}, {mouse.y}

)}/> ``` -And remember, the `children` prop doesn't actually need to be named in the list of "attributes" in your JSX element. Instead, you can put it directly *inside* the element! +ليس من الضروري أن تكون الخاصيّة `children` موجودة في قائمة الخاصيّات في عنصر JSX لديك، فبإمكانك وضعها بشكل مباشر *بداخل* العنصر: ```js {mouse => ( -

The mouse position is {mouse.x}, {mouse.y}

+

موقع الفأرة هو {mouse.x}, {mouse.y}

)}
``` -You'll see this technique used in the [react-motion](https://github.com/chenglou/react-motion) API. +سترى أن هذه الطريقة مستخدمة في [react-motion](https://github.com/chenglou/react-motion) API. -Since this technique is a little unusual, you'll probably want to explicitly state that `children` should be a function in your `propTypes` when designing an API like this. +بما أنّ هذه الطريقة غير معتادة قليلًا فقد ترغب بالإعلان عن أنّ `children` يجب أن تكون دالة من خلال `propTypes`: ```js Mouse.propTypes = { @@ -267,28 +267,28 @@ Mouse.propTypes = { }; ``` -## Caveats {#caveats} +## محاذير {#caveats} -### Be careful when using Render Props with React.PureComponent {#be-careful-when-using-render-props-with-reactpurecomponent} +### انتبه عند استخدام خاصية التصيير مع `React.PureComponent` {#be-careful-when-using-render-props-with-reactpurecomponent} -Using a render prop can negate the advantage that comes from using [`React.PureComponent`](/docs/react-api.html#reactpurecomponent) if you create the function inside a `render` method. This is because the shallow prop comparison will always return `false` for new props, and each `render` in this case will generate a new value for the render prop. +قد يُلغي استخدام خاصية التصيير الفائدة المرجوة من استخدام [`React.PureComponent`](/docs/react-api.html#reactpurecomponent) إن أنشأت الدالة بداخل التابع `render`، وذلك لأنّ المقارنة بين الخاصيّات ستعيد دومًا `false` للخاصيّات الجديدة، وسيُولِّد كل تابع `render` في هذه الحالة قيمة جديدة للخاصيّة `render`. -For example, continuing with our `` component from above, if `Mouse` were to extend `React.PureComponent` instead of `React.Component`, our example would look like this: +فمثلًا بالمتابعة مع المكوّن السابق ‎``‎، إن كان هذا المكوّن يمتد إلى `React.PureComponent` بدلًا من `React.Component`، فسيبدو مثالنا كما يلي: ```js class Mouse extends React.PureComponent { - // Same implementation as above... + // نفس التنفيذ السابق... } class MouseTracker extends React.Component { render() { return (
-

Move the mouse around!

+

حرّك الفأرة!

{/* - This is bad! The value of the `render` prop will - be different on each render. + `render` هذا سيّء! حيث ستكون قيمة خاصية التصيير + مختلفة عند كل تصيير */} ( @@ -299,14 +299,14 @@ class MouseTracker extends React.Component { } ``` -In this example, each time `` renders, it generates a new function as the value of the `` prop, thus negating the effect of `` extending `React.PureComponent` in the first place! +في هذا المثال عند كل تصيير للمكوّن `‎`‎ فسيُولِّد دالة جديدة كقيمة للخاصية ‎``‎، وبذلك يلغي تأثير المكوّن ‎``‎ الذي يمتد إلى `React.PureComponent` في المقام الأول. -To get around this problem, you can sometimes define the prop as an instance method, like so: +لحل هذه المشكلة تستطيع تعريف الخاصيّة كنسخة من تابع كما يلي: ```js class MouseTracker extends React.Component { - // Defined as an instance method, `this.renderTheCat` always - // refers to *same* function when we use it in render + // معرف كنسخة تابع + // يشير this.renderTheCat دومًا إلى *نفس* الدالة عند استخدامها للتصيير renderTheCat(mouse) { return ; } @@ -314,7 +314,7 @@ class MouseTracker extends React.Component { render() { return (
-

Move the mouse around!

+

حرك الفأرة!

); @@ -322,4 +322,4 @@ class MouseTracker extends React.Component { } ``` -In cases where you cannot define the prop statically (e.g. because you need to close over the component's props and/or state) `` should extend `React.Component` instead. +في الحالات التي لا تستطيع فيها تعريف الخاصيّة بشكل ثابت (مثلًا إذا كنت تحتاج إلى تغيير خاصية أو حالة المكوّن) فيجب أن يمتد المكوّن ‎`‎` إلى `React.Component` بدلًا من ذلك. \ No newline at end of file