From 2883455adbe017ab8e1f23c8f33a5919dcd5624a Mon Sep 17 00:00:00 2001 From: tmtm8976 Date: Sun, 13 Aug 2023 01:37:46 +0300 Subject: [PATCH 1/6] translating Keeping components pure --- src/content/learn/keeping-components-pure.md | 229 ++++++++++--------- src/sidebarLearn.json | 2 +- 2 files changed, 118 insertions(+), 113 deletions(-) diff --git a/src/content/learn/keeping-components-pure.md b/src/content/learn/keeping-components-pure.md index 60760edc5..824f33e23 100644 --- a/src/content/learn/keeping-components-pure.md +++ b/src/content/learn/keeping-components-pure.md @@ -1,41 +1,44 @@ --- -title: Keeping Components Pure +title: الحفاظ على نقاء المكوّنات --- -Some JavaScript functions are *pure.* Pure functions only perform a calculation and nothing more. By strictly only writing your components as pure functions, you can avoid an entire class of baffling bugs and unpredictable behavior as your codebase grows. To get these benefits, though, there are a few rules you must follow. +بعض دوال JavaScript *نقية.* الدوال النقية (pure functions) تقوم فقط بإجراء حساب ولا شيء اكثر. من خلال كتابة مكوّناتك (components) بصرامة كدوال نقية، يمكنك تجنب صنف كامل من الأخطاء (bugs) المحيرة والسلوك غير المتوقع مع نمو قاعدة التعليمات البرمجية (codebase) الخاصة بك. للحصول على هذه الفوائد، هناك بعض القواعد التي يجب عليك اتباعها. + -* What purity is and how it helps you avoid bugs -* How to keep components pure by keeping changes out of the render phase -* How to use Strict Mode to find mistakes in your components +* ما هو النقاء وكيف يساعدك على تجنب الأخطاء (bugs) +* كيفية الحفاظ على نقاء المكوّنات عن طريق إبقاء التغييرات خارج مرحلة التصيير (render phase) +* كيفية استخدام الوضع الصارم (Strict Mode) للعثور على الأخطاء في مكوّناتك -## Purity: Components as formulas {/*purity-components-as-formulas*/} +## النقاء: المكوّنات (components) كمعادلات رياضية {/*purity-components-as-formulas*/} + +في علم الحاسب (وخاصة عالم البرمجة الوظيفية (functional programming)), [الدالة النقية](https://wikipedia.org/wiki/Pure_function) هي دالة بالخواص التالية: + +* **تهتم بشؤونها.** لا تغير أي كائنات أو متغيرات كانت موجودة قبل استدعائها. +* **نفس الدخل، نفس الخرج** بإعطاء نفس المدخلات ، يجب أن تُرجع الدالة النقية نفس النتيجة دائمًا. -In computer science (and especially the world of functional programming), [a pure function](https://wikipedia.org/wiki/Pure_function) is a function with the following characteristics: +قد تكون بالفعل على دراية بمثال واحد من الوظائف النقية: المعادلات في الرياضيات. -* **It minds its own business.** It does not change any objects or variables that existed before it was called. -* **Same inputs, same output.** Given the same inputs, a pure function should always return the same result. +انظر معادلة الرياضيات هذه: y = 2x. -You might already be familiar with one example of pure functions: formulas in math. +إذا x = 2 عندها y = 4. دائمًا. -Consider this math formula: y = 2x. +إذا x = 3 عندها y = 6. دائمًا. -If x = 2 then y = 4. Always. +إذا x = 3, y لن تكون احيانًا 9 أو –1 أو 2.5 اعتمادًا على الوقت في اليوم أو حالة البورصة. -If x = 3 then y = 6. Always. +إذا y = 2x و x = 3، y ستكون _دائمًا_ 6. -If x = 3, y won't sometimes be 9 or –1 or 2.5 depending on the time of day or the state of the stock market. +إذا قمنا بتحويل هذا إلى دالة JavaScript، فسيبدو كما يلي: -If y = 2x and x = 3, y will _always_ be 6. -If we made this into a JavaScript function, it would look like this: ```js function double(number) { @@ -43,9 +46,9 @@ function double(number) { } ``` -In the above example, `double` is a **pure function.** If you pass it `3`, it will return `6`. Always. +في المثال أعلاه ، "double" هي **دالة نقية.** إذا مررت بـ "3" ، فستُرجع "6". دائماً. -React is designed around this concept. **React assumes that every component you write is a pure function.** This means that React components you write must always return the same JSX given the same inputs: +تم تصميم React حول هذا المفهوم. **تفترض React أن كل مكّون تكتبه هو دالة نقية.** هذا يعني أن مكوّنات React التي تكتبها يجب أن تُرجع دائمًا نفس JSX مع الأخذ في الاعتبار نفس المدخلات: @@ -53,9 +56,9 @@ React is designed around this concept. **React assumes that every component you function Recipe({ drinkers }) { return (
    -
  1. Boil {drinkers} cups of water.
  2. -
  3. Add {drinkers} spoons of tea and {0.5 * drinkers} spoons of spice.
  4. -
  5. Add {0.5 * drinkers} cups of milk to boil and sugar to taste.
  6. +
  7. أغلي {drinkers} كوب ماء.
  8. +
  9. أضف {drinkers} ملعقة شاي و {0.5 * drinkers} ملعقة توابل.
  10. +
  11. أضف {0.5 * drinkers} كوب حليب للغلي وسكر للتذوق
); } @@ -63,10 +66,10 @@ function Recipe({ drinkers }) { export default function App() { return (
-

Spiced Chai Recipe

-

For two

+

وصفة شاي متبل

+

لاثنين

-

For a gathering

+

لتجمًع

); @@ -75,21 +78,23 @@ export default function App() {
-When you pass `drinkers={2}` to `Recipe`, it will return JSX containing `2 cups of water`. Always. +عند تمرير `drinkers={2}` إلى `Recipe`, ستعيد JSX تحتوي على `2 cups of water`. دائمًا. -If you pass `drinkers={4}`, it will return JSX containing `4 cups of water`. Always. +إذا قمت بتمرير `drinkers={4}`, ستعيد JSX تحتوي على `4 cups of water`. دائمًا. -Just like a math formula. +تمامًا مثل الصيغ الرياضية. -You could think of your components as recipes: if you follow them and don't introduce new ingredients during the cooking process, you will get the same dish every time. That "dish" is the JSX that the component serves to React to [render.](/learn/render-and-commit) +يمكنك التفكير في المكوّنات الخاصة بك كوصفات: إذا اتبعتها ولم تقم بإدخال مكوّنات جديدة أثناء عملية الطهي، ستحصل على نفس الطبق في كل مرة. هذا "الطبق" هو ال JSX الذي يقدمه المكوّن لReact لل[تصيير.](/learn/render-and-commit) -## Side Effects: (un)intended consequences {/*side-effects-unintended-consequences*/} +## الآثار الجانبية: العواقب (غير المقصودة) {/*side-effects-unintended-consequences*/} + +يجب أن تكون عملية التصيير في React دائمًا نقية. يجب أن تقوم المكوّنات فقط بـ*إرجاع* JSX الخاص بهم، وعدم *تغيير* أي كائنات أو متغيرات كانت موجودة قبل عملية التصيير-فأن هذا سيجعلهم غير نقيين! + -React's rendering process must always be pure. Components should only *return* their JSX, and not *change* any objects or variables that existed before rendering—that would make them impure! -Here is a component that breaks this rule: +فيما يلي مكوّن يخالف هذا القاعدة: @@ -97,9 +102,9 @@ Here is a component that breaks this rule: let guest = 0; function Cup() { - // Bad: changing a preexisting variable! + // سيئ: تغيير متغير موجود بالفعل! guest = guest + 1; - return

Tea cup for guest #{guest}

; + return

كوب شاي للضيف رقم {guest}

; } export default function TeaSet() { @@ -115,17 +120,17 @@ export default function TeaSet() {
-This component is reading and writing a `guest` variable declared outside of it. This means that **calling this component multiple times will produce different JSX!** And what's more, if _other_ components read `guest`, they will produce different JSX, too, depending on when they were rendered! That's not predictable. +يقوم هذا المكوّن بقراءة وكتابة متغير `guest` المعلن خارجه. هذا يعني أن **استدعاء هذا المكوّن مرات متعددة سينتج** وما هو أكثر من ذلك ، إذا قرأت المكوّنات الأخرى `guest`, سوف تنتج JSX مختلف , أيضًا ، اعتمادًا على متى تم تصييرها! وهذا لا يمكن توقعه -Going back to our formula y = 2x, now even if x = 2, we cannot trust that y = 4. Our tests could fail, our users would be baffled, planes would fall out of the sky—you can see how this would lead to confusing bugs! +نعود إلى صيغتنا السابقة y = 2x, الآن حتى إذا كان x = 2, لا يمكننا الاعتماد على أن y = 4. قد تفشل اختباراتنا ، وقد يكون, المستخدمون مشوشين, وقد تسقط الطائرات من السماء - يمكنك رؤية كيف يمكن أن يؤدي ذلك إلى خلل مربك! -You can fix this component by [passing `guest` as a prop instead](/learn/passing-props-to-a-component): +يمكنك إصلاح هذا العنصر عن طريق [تمرير `guest` كخاصية](/learn/passing-props-to-a-component): ```js function Cup({ guest }) { - return

Tea cup for guest #{guest}

; + return

كوب شاي للضيف رقم {guest}

; } export default function TeaSet() { @@ -141,37 +146,37 @@ export default function TeaSet() {
-Now your component is pure, as the JSX it returns only depends on the `guest` prop. +الآن يعتبر المكوّن الخاص بك نقيًا، حيث أن JSX الذي يُرجع يعتمد فقط على خاصية `guest`. -In general, you should not expect your components to be rendered in any particular order. It doesn't matter if you call y = 2x before or after y = 5x: both formulas will resolve independently of each other. In the same way, each component should only "think for itself", and not attempt to coordinate with or depend upon others during rendering. Rendering is like a school exam: each component should calculate JSX on their own! +بشكل عام، لا يجب عليك أن تتوقع أن يتم تقديم المكوّنات الخاصة بك بترتيب معين. لا يهم إذا قمت بطلب y = 2x قبل أو بعد y = 5x: ستتم حل كلا الصيغ بشكل مستقل عن بعضهما البعض. بنفس الطريقة، يجب على كل مكوّن "أن يفكر لنفسه" فقط، ولا يحاول التنسيق أو الاعتماد على المكوّنات الأخرى أثناء التصيير. التصيير مثل امتحان مدرسي: يجب على كل مكوّن حساب JSX بمفرده! -#### Detecting impure calculations with StrictMode {/*detecting-impure-calculations-with-strict-mode*/} +#### اكتشاف الحسابات غير النقية باستخدام الوضع الصارم {/*detecting-impure-calculations-with-strict-mode*/} -Although you might not have used them all yet, in React there are three kinds of inputs that you can read while rendering: [props](/learn/passing-props-to-a-component), [state](/learn/state-a-components-memory), and [context.](/learn/passing-data-deeply-with-context) You should always treat these inputs as read-only. +على الرغم من أنه قد لا تكون قد استخدمت جميعها بعد, في React هناك ثلاثة أنواع من المدخلات التي يمكنك قراءتها أثناء التصيير: [الخصائص](/learn/passing-props-to-a-component), [الحالة](/learn/state-a-components-memory), و [السياق.](/learn/passing-data-deeply-with-context) يجب عليك دائمًا معاملة هذه المدخلات على أنها للقراءة فقط. -When you want to *change* something in response to user input, you should [set state](/learn/state-a-components-memory) instead of writing to a variable. You should never change preexisting variables or objects while your component is rendering. +عندما تريد *تغيير* شيء ما استجابة لإدخال المستخدم، يجب عليك [تعيين حالة](/learn/state-a-components-memory) بدلاً من الكتابة في متغير. يجب ألا تقوم بتغيير المتغيرات أو الكائنات الموجودة مسبقًا أثناء تصيير المكوّن الخاص بك. -React offers a "Strict Mode" in which it calls each component's function twice during development. **By calling the component functions twice, Strict Mode helps find components that break these rules.** +React يوفر "وضعًا صارمًا"(Strict Mode) يقوم فيه باستدعاء دالة كل مكوّن مرتين أثناء التطوير. **من خلال استدعاء وظائف المكوّن مرتين، يساعد الوضع الصارم في العثور على المكوّنات التي تخالف هذه القواعد.** -Notice how the original example displayed "Guest #2", "Guest #4", and "Guest #6" instead of "Guest #1", "Guest #2", and "Guest #3". The original function was impure, so calling it twice broke it. But the fixed pure version works even if the function is called twice every time. **Pure functions only calculate, so calling them twice won't change anything**--just like calling `double(2)` twice doesn't change what's returned, and solving y = 2x twice doesn't change what y is. Same inputs, same outputs. Always. +لاحظ كيف عرض المثال الأصلي "Guest #2", "Guest #4", و "Guest #6" بدلاً من "Guest #1", "Guest #2", و "Guest #3". كانت الدالة الأصلية غير نقية، لذا تعطلت عند استدعاؤها مرتين. ولكن الإصدار النقي المُصلح يعمل حتى إذا تم استدعاء الوظيفة مرتين. **الدوال النقية تقوم بالحساب فقط، لذلك لن يتغير أي شيء عند استدعائها مرتين**--تمامًا مثل استدعاء `double(2)` مرتين لن يتغير ما يتم إرجاعه، وحل y = 2x مرتين لن يغير ما هو y. نفس المدخلات، نفس المخرجات. دائمًا. -Strict Mode has no effect in production, so it won't slow down the app for your users. To opt into Strict Mode, you can wrap your root component into ``. Some frameworks do this by default. +الوضع الصارم لا يؤثر في الإنتاج، لذلك لن يبطئ التطبيق لمستخدمينك. يمكنك الانضمام إلى الوضع الصارم, عن طريق تغليف عنصر الجذر(root component) الخاص بك في ``. تفعل بعض الإطارات ذلك افتراضيًا. -### Local mutation: Your component's little secret {/*local-mutation-your-components-little-secret*/} +### التغيير المحلي: سر صغير لمكوّناتك {/*local-mutation-your-components-little-secret*/} -In the above example, the problem was that the component changed a *preexisting* variable while rendering. This is often called a **"mutation"** to make it sound a bit scarier. Pure functions don't mutate variables outside of the function's scope or objects that were created before the call—that makes them impure! +في المثال أعلاه، كان المشكلة في أن المكوّن قام بتغيير متغير *موجود مسبقًا* أثناء التصيير. يُطلق عليها في كثير من الأحيان **"طفرة"** لجعلها تبدو أكثر رعبًا. الدوال النقية لا تغيّر المتغيرات خارج نطاق الدالة أو الكائنات التي تم إنشاؤها قبل الاستدعاء - هذا يجعلها غير نقية! -However, **it's completely fine to change variables and objects that you've *just* created while rendering.** In this example, you create an `[]` array, assign it to a `cups` variable, and then `push` a dozen cups into it: +ومع ذلك, **فمن المسموح تمامًا بتغيير المتغيرات والكائنات التي قمت بإنشائها *فقط* خلال العرض** في هذا المثال, قم بإنشاء `[]` مصفوفة, وعيينها إلى متغير `cups`, ثم `ادفع(push)` اثني عشر كوبًا فيها: ```js function Cup({ guest }) { - return

Tea cup for guest #{guest}

; + return

كوب شاي للضيف رقم {guest}

; } export default function TeaGathering() { @@ -185,43 +190,43 @@ export default function TeaGathering() {
-If the `cups` variable or the `[]` array were created outside the `TeaGathering` function, this would be a huge problem! You would be changing a *preexisting* object by pushing items into that array. +إذا تم إنشاء متغير `cups` او `[]` مصفوفة خارج دالة `TeaGathering` فسيكون هذا مشكلة كبيرة! ستقوم بتغيير كائن *موجود مسبقًا* عن طريق دفع العناصر في تلك المصفوفة. -However, it's fine because you've created them *during the same render*, inside `TeaGathering`. No code outside of `TeaGathering` will ever know that this happened. This is called **"local mutation"**—it's like your component's little secret. +ومع ذلك, فإنه يعد أمرًا صحيحًا لأنك قمت بإنشائهم *خلال نفس العرض*, داخل `TeaGathering`. لن يعرف أي كود خارج `TeaGathering` بدًا أن هذا حدث. يُطلق عليه **"تغيير المحلي"**—هو مثل سر صغير لمكوّناتك. -## Where you _can_ cause side effects {/*where-you-_can_-cause-side-effects*/} +## المكان الذي يمكنك فيه التسبب بآثار جانبية {/*where-you-_can_-cause-side-effects*/} -While functional programming relies heavily on purity, at some point, somewhere, _something_ has to change. That's kind of the point of programming! These changes—updating the screen, starting an animation, changing the data—are called **side effects.** They're things that happen _"on the side"_, not during rendering. +على الرغم من أن البرمجة الوظيفية تعتمد بشدة على النقاء, إلا أنه في نقطة ما، في, مكان ما،يجب أن يتغير _شيء_. هذه هي نقطة البرمجة! هذه التغييرات - تحديث الشاشة، بدء الرسوم المتحركة، تغيير البيانات - تسمى **الآثار الجانبية** إنها أشياء تحدث _"على الجانب"_, وليست خلال التصيير. -In React, **side effects usually belong inside [event handlers.](/learn/responding-to-events)** Event handlers are functions that React runs when you perform some action—for example, when you click a button. Even though event handlers are defined *inside* your component, they don't run *during* rendering! **So event handlers don't need to be pure.** +في React, **تنتمي الآثار الجانبية عادةً داخل [معالجات الأحداث(event handlers).](/learn/responding-to-events)** معالجات الأحداث هي الدوال التي يقوم React بتشغيلها عندما تقوم بإجراء بعض الإجراءات—على سبيل المثال، عند النقر فوق زر. على الرغم من أن معالجات الأحداث تم تعريفها *داخل* المكوّن الخاص بك، إلا أنها لا تعمل *خلال* التصيير! **لذلك، فإن معالجات الأحداث لا تحتاج إلى أن تكون نقية.** -If you've exhausted all other options and can't find the right event handler for your side effect, you can still attach it to your returned JSX with a [`useEffect`](/reference/react/useEffect) call in your component. This tells React to execute it later, after rendering, when side effects are allowed. **However, this approach should be your last resort.** +إذا استنفذت كل الخيارات الأخرى ولم تتمكن من العثور على معالج الأحداث المناسب لآثار جانبية، فيمكنك تثبيتها على JSX المُرجَع الخاص بك باستدعاء[`useEffect`](/reference/react/useEffect) في مكوّنك. يخبر هذا React بتنفيذها لاحقًا، بعد التصيير، عندما يسمح بالآثار الجانبية. **ومع ذلك، يجب أن يكون هذا النهج هو خيارك الأخير.** -When possible, try to express your logic with rendering alone. You'll be surprised how far this can take you! +عندما يكون ذلك ممكنًا، حاول التعبير عن منطقك فقط من خلال التصرير. ستتفاجأ الى اي مدى يمكن لهذاأن يأخذك! -#### Why does React care about purity? {/*why-does-react-care-about-purity*/} +#### لماذا يهتم React بالنقاء؟ {/*why-does-react-care-about-purity*/} -Writing pure functions takes some habit and discipline. But it also unlocks marvelous opportunities: +يتطلب كتابة الدوال النقية بعض العادات والانضباط. ولكنه يفتح أيضًا فرصًا رائعة -* Your components could run in a different environment—for example, on the server! Since they return the same result for the same inputs, one component can serve many user requests. -* You can improve performance by [skipping rendering](/reference/react/memo) components whose inputs have not changed. This is safe because pure functions always return the same results, so they are safe to cache. -* If some data changes in the middle of rendering a deep component tree, React can restart rendering without wasting time to finish the outdated render. Purity makes it safe to stop calculating at any time. +* يمكن لمكوّناتك أن تعمل في بيئة مختلفة - على سبيل المثال، على الخادم! نظرًا لأنها تعيد نفس النتيجة لنفس المدخلات، يمكن لمكوّن واحد أن يخدم العديد من طلبات المستخدم. +* يمكنك تحسين الأداء من خلال [تخطي تصيير](/reference/react/memo) المكوّنات التي لم تتغير مدخلاتها. هذا آمن لأن الدوال النقية تعيد نفس النتائج دائمًا، لذلك فهي آمنة للتخزين المؤقت. +* إذا تغيرت بعض البيانات في منتصف تصيير شجرة مكوّنات عميقة، يمكن لـReact إعادة بدء التصيير دون إضاعة الوقت لإنهاء التصيير القديم. يجعل النقاء من الآمن التوقف عن الحساب في أي وقت. -Every new React feature we're building takes advantage of purity. From data fetching to animations to performance, keeping components pure unlocks the power of the React paradigm. +كل الميزات الجديدة التي نقوم ببنائها في React تستفيد من النقاء. من جلب البيانات إلى الرسوم المتحركة إلى الأداء، يفتح الحفاظ على المكوّنات نقية قوة نمط React. -* A component must be pure, meaning: - * **It minds its own business.** It should not change any objects or variables that existed before rendering. - * **Same inputs, same output.** Given the same inputs, a component should always return the same JSX. -* Rendering can happen at any time, so components should not depend on each others' rendering sequence. -* You should not mutate any of the inputs that your components use for rendering. That includes props, state, and context. To update the screen, ["set" state](/learn/state-a-components-memory) instead of mutating preexisting objects. -* Strive to express your component's logic in the JSX you return. When you need to "change things", you'll usually want to do it in an event handler. As a last resort, you can `useEffect`. -* Writing pure functions takes a bit of practice, but it unlocks the power of React's paradigm. +* يجب أن يكون المكوّن نقيًا، مما يعني: + * **يهتم بأمره الخاص.** لا يجب أن يغير أي كائنات أو متغيرات كانت موجودة قبل التصيير. + * **نفس المدخلات، نفس المخرجات.** باعطاء نفس المدخلات، يجب على المكوّن أن يعيد دائمًا نفس JSX. +* يمكن أن يحدث التصيير في أي وقت ، لذلك لا يجب أن تعتمد المكوّنات على تسلسل التصيير لبعضها البعض. +* لا يجب تغيير أي من المدخلات التي تستخدمها المكوّنات الخاصة بك للتصيير. ويشمل ذلك الخصائص والحالة والسياق. لتحديث الشاشة ، استخدم, ["set" state](/learn/state-a-components-memory) بدلاً من تغيير الكائنات الموجودة مسبقًا. +* يجب السعي للتعبير عن منطق المكوّن في JSX الذي تعيده. عندما تحتاج إلى "تغيير الأشياء" ، عادةً ما تريد القيام بذلك في معالج الحدث(event listener). كخيار أخير ، يمكنك استخدام `useEffect`. +* يتطلب كتابة الدوال النقية بعض الممارسة ، ولكنه يفتح باب قوة نمط React. @@ -229,15 +234,15 @@ Every new React feature we're building takes advantage of purity. From data fetc -#### Fix a broken clock {/*fix-a-broken-clock*/} +#### إصلاح ساعة مكسورة {/*fix-a-broken-clock*/} -This component tries to set the `

`'s CSS class to `"night"` during the time from midnight to six hours in the morning, and `"day"` at all other times. However, it doesn't work. Can you fix this component? +يحاول هذا المكوّن تعيين فئة(class) CSS لـ `

` إلى `"night"` خلال الفترة من منتصف الليل إلى السادسة صباحًا، و `"day"` في جميع الأوقات الأخرى. ومع ذلك ، لا يعمل. هل يمكنك إصلاح هذا المكوّن؟ -You can verify whether your solution works by temporarily changing the computer's timezone. When the current time is between midnight and six in the morning, the clock should have inverted colors! +يمكنك التحقق مما إذا كان حلك يعمل عن طريق تغيير المنطقة الزمنية للحاسوب مؤقتًا. عندما يكون الوقت الحالي بين منتصف الليل والسادسة صباحًا ، يجب أن تكون الساعة قد عكست الوانها! -Rendering is a *calculation*, it shouldn't try to "do" things. Can you express the same idea differently? +التصيير هو *حساب*، لا يجب أن يحاول "القيام" بأشياء. هل يمكنك التعبير عن نفس الفكرة بطريقة مختلفة؟ @@ -301,7 +306,7 @@ body > * { -You can fix this component by calculating the `className` and including it in the render output: +يمكنك إصلاح هذا المكوّن عن طريق حساب ال`className` وتضمينه في المَخْرَج الذي تقوم بإرجاعه @@ -362,19 +367,19 @@ body > * { -In this example, the side effect (modifying the DOM) was not necessary at all. You only needed to return JSX. +في هذا المثال، لم يكن الآثر الجانبي (تعديل DOM) ضروريًا على الإطلاق. كان عليك فقط إرجاع JSX. -#### Fix a broken profile {/*fix-a-broken-profile*/} +#### اصلح الملف الشخصي المكسور {/*fix-a-broken-profile*/} -Two `Profile` components are rendered side by side with different data. Press "Collapse" on the first profile, and then "Expand" it. You'll notice that both profiles now show the same person. This is a bug. +يتم تصيير مكوّنين للملف الشخصي `Profile` جنبًا إلى جنب ببيانات مختلفة. اضغط على "Collapse" في الملف الشخصي الأول ، ثم "مدده". ستلاحظ أن الملف الشخصيين يعرضان الآن نفس الشخص. هذا خطأ. -Find the cause of the bug and fix it. +ابحث عن سبب الخطأ وأصلحه. -The buggy code is in `Profile.js`. Make sure you read it all from top to bottom! +الكود المعطوب في ملف `Profile.js`. تأكد من قراءته بالكامل من الأعلى إلى الأسفل! @@ -437,11 +442,11 @@ export default function App() { <> ) @@ -475,9 +480,9 @@ h1 { margin: 5px; font-size: 18px; } -The problem is that the `Profile` component writes to a preexisting variable called `currentPerson`, and the `Header` and `Avatar` components read from it. This makes *all three of them* impure and difficult to predict. +المشكلة هي أن مكوّن `Profile` يكتب على متغير موجود مسبقًا يسمى `currentPerson`, ويقرأ المكوّنان `Header` و `Avatar` منه. هذا يجعل *الثلاثة منها* غير نقية وصعبة التنبؤ بها. -To fix the bug, remove the `currentPerson` variable. Instead, pass all information from `Profile` to `Header` and `Avatar` via props. You'll need to add a `person` prop to both components and pass it all the way down. +لإصلاح الخطأ ، احذف المتغير `currentPerson`. بدلاً من ذلك ، قم بتمرير جميع المعلومات من `Profile` إلى `Header` و `Avatar` عبر الخصائص. ستحتاج إلى إضافة خاصية شخص `person` لكل من المكوّنين وتمريرها حتى النهاية. @@ -535,11 +540,11 @@ export default function App() { <> ); @@ -571,15 +576,15 @@ h1 { margin: 5px; font-size: 18px; } -Remember that React does not guarantee that component functions will execute in any particular order, so you can't communicate between them by setting variables. All communication must happen through props. +تذكر أن React لا يضمن تنفيذ دوال المكوّنات في أي ترتيب معين ، لذلك لا يمكنك التواصل بينهم عن طريق تعيين المتغيرات. يجب أن يحدث كل التواصل من خلال الخصائص. -#### Fix a broken story tray {/*fix-a-broken-story-tray*/} +#### إصلاح صينية القصص المعطوبة {/*fix-a-broken-story-tray*/} -The CEO of your company is asking you to add "stories" to your online clock app, and you can't say no. You've written a `StoryTray` component that accepts a list of `stories`, followed by a "Create Story" placeholder. +يطلب منك الرئيس التنفيذي لشركتك إضافة "قصص" إلى تطبيق الساعة الخاص بك على الإنترنت ، ولا يمكنك الرفض. لقد كتبت مكوّن `StoryTray` الذي يقبل قائمة من القصص `stories` ، تليها "إنشاء قصة" العنصر النائب. -You implemented the "Create Story" placeholder by pushing one more fake story at the end of the `stories` array that you receive as a prop. But for some reason, "Create Story" appears more than once. Fix the issue. +قمت بتنفيذ "إنشاء قصة" العنصر النائب عن طريق دفع قصة وهمية أخرى في نهاية مصفوفة القصص `stories` التي تتلقاها كخاصية. ولكن لسبب ما ، يظهر "إنشاء قصة" أكثر من مرة. اصلح المشكلة. @@ -587,7 +592,7 @@ You implemented the "Create Story" placeholder by pushing one more fake story at export default function StoryTray({ stories }) { stories.push({ id: 'create', - label: 'Create Story' + label: 'إنشاء قصة' }); return ( @@ -607,16 +612,16 @@ import { useState, useEffect } from 'react'; import StoryTray from './StoryTray.js'; let initialStories = [ - {id: 0, label: "Ankit's Story" }, - {id: 1, label: "Taylor's Story" }, + {id: 0, label: "قصة عنكيت" }, + {id: 1, label: "قصة تايلور" }, ]; export default function App() { let [stories, setStories] = useState([...initialStories]) let time = useTime(); - // HACK: Prevent the memory from growing forever while you read docs. - // We're breaking our own rules here. + // خدعة: منع الذاكرة من النمو إلى الأبد أثناء قراءة الوثائق. + // نحن نكسر قواعدنا الخاصة هنا. if (stories.length > 100) { stories.length = 100; } @@ -675,11 +680,11 @@ li { -Notice how whenever the clock updates, "Create Story" is added *twice*. This serves as a hint that we have a mutation during rendering--Strict Mode calls components twice to make these issues more noticeable. +لاحظ كيف يتم إضافة "إنشاء قصة" *مرتين* في كل مرة يتم فيها تحديث الساعة. هذا يشير إلى أن لدينا تغيير خلال التصصير - يقوم الوضع الصارم (Strict Mode) بنداء المكوّنات مرتين لجعل هذه المشكلات أكثر وضوحًا. -`StoryTray` function is not pure. By calling `push` on the received `stories` array (a prop!), it is mutating an object that was created *before* `StoryTray` started rendering. This makes it buggy and very difficult to predict. +الدالة `StoryTray` ليست نقية. من خلال استدعاء `push` على مصفوفة القصص `stories` التي تم تلقيها (خاصية!), فإنه يتم تغيير كائن تم إنشاؤه *من قبل* بدء `StoryTray` في التصيير. هذا يجعله غير صحيح وصعب جدًا التنبؤ به. -The simplest fix is to not touch the array at all, and render "Create Story" separately: +أبسط إصلاح هو عدم لمس المصفوفة على الإطلاق ، وتصيير "إنشاء قصة" بشكل منفصل: @@ -692,7 +697,7 @@ export default function StoryTray({ stories }) { {story.label} ))} -
  • Create Story
  • +
  • إنشاء قصة
  • ); } @@ -703,16 +708,16 @@ import { useState, useEffect } from 'react'; import StoryTray from './StoryTray.js'; let initialStories = [ - {id: 0, label: "Ankit's Story" }, - {id: 1, label: "Taylor's Story" }, + {id: 0, label: "قصة عنكيت" }, + {id: 1, label: "قصة تايلور" }, ]; export default function App() { let [stories, setStories] = useState([...initialStories]) let time = useTime(); - // HACK: Prevent the memory from growing forever while you read docs. - // We're breaking our own rules here. + // خدعة: منع الذاكرة من النمو إلى الأبد أثناء قراءة الوثائق. + // نحن نكسر قواعدنا الخاصة هنا. if (stories.length > 100) { stories.length = 100; } @@ -763,19 +768,19 @@ li {
    -Alternatively, you could create a _new_ array (by copying the existing one) before you push an item into it: +بديلًا عن ذلك ، يمكنك إنشاء مصفوفة _جديدة_ (عن طريق نسخ الحالية) قبل دفع عنصر فيها: ```js StoryTray.js active export default function StoryTray({ stories }) { - // Copy the array! + // انسخ المصفوفة! let storiesToDisplay = stories.slice(); - // Does not affect the original array: + // لا يؤثر على المصفوفة الأصلية: storiesToDisplay.push({ id: 'create', - label: 'Create Story' + label: 'إنشاء قصة' }); return ( @@ -795,16 +800,16 @@ import { useState, useEffect } from 'react'; import StoryTray from './StoryTray.js'; let initialStories = [ - {id: 0, label: "Ankit's Story" }, - {id: 1, label: "Taylor's Story" }, + {id: 0, label: "قصة عنكيت" }, + {id: 1, label: "قصة تايلور" }, ]; export default function App() { let [stories, setStories] = useState([...initialStories]) let time = useTime(); - // HACK: Prevent the memory from growing forever while you read docs. - // We're breaking our own rules here. + // خدعة: منع الذاكرة من النمو إلى الأبد أثناء قراءة الوثائق. + // نحن نكسر قواعدنا الخاصة هنا. if (stories.length > 100) { stories.length = 100; } @@ -855,9 +860,9 @@ li { -This keeps your mutation local and your rendering function pure. However, you still need to be careful: for example, if you tried to change any of the array's existing items, you'd have to clone those items too. +هذا يحافظ على تغييرك محليًا ويجعل دالة التصيير الخاصة بك نقية. ومع ذلك ، لا يزال عليك أن تكون حذرًا: على سبيل المثال ، إذا حاولت تغيير أي من العناصر الموجودة في المصفوفة ، فسيتعين عليك استنساخ تلك العناصر أيضًا. -It is useful to remember which operations on arrays mutate them, and which don't. For example, `push`, `pop`, `reverse`, and `sort` will mutate the original array, but `slice`, `filter`, and `map` will create a new one. +من المفيد تذكر العمليات التي تؤثر على المصفوفات والتي لا تؤثر عليها. على سبيل المثال ، ستؤثر `push` و `pop` و `reverse` و `sort` على المصفوفة الأصلية ، لكن `slice` و `filter` و `map` ستقوم بإنشاء مصفوفة جديدة.
    diff --git a/src/sidebarLearn.json b/src/sidebarLearn.json index 66db59b5a..eb33c0264 100644 --- a/src/sidebarLearn.json +++ b/src/sidebarLearn.json @@ -80,7 +80,7 @@ "path": "/learn/rendering-lists" }, { - "title": "Keeping Components Pure", + "title": "الحفاظ على نقاء المكونّات", "path": "/learn/keeping-components-pure" } ] From 6b61cd490d87c620533a3a79210c7c0ca96fdf56 Mon Sep 17 00:00:00 2001 From: Ahmed Abdelbaset Date: Wed, 16 Aug 2023 01:24:46 +0300 Subject: [PATCH 2/6] Annex to #6138 (#6226) * fix: wronge styles when applying RTL it was `top-0 left-0 ...` by wrong I made it `inset-x-0`. * fix wrong styles * fix wrong styles * style canary icon with RTL-friendly styles * chore: utilize mx-* instead of me-* & ms-* * utilize relative styles * chore: use mx-* instead of me-* & ms-* * style canary icon with RTL-frindly styles * Update OpenInTypeScriptPlayground.tsx --- src/components/Layout/HomeContent.js | 2 +- src/components/Layout/Sidebar/SidebarButton.tsx | 2 +- src/components/Layout/Sidebar/SidebarLink.tsx | 4 ++-- src/components/MDX/Sandpack/OpenInCodeSandboxButton.tsx | 2 +- src/components/MDX/Sandpack/OpenInTypeScriptPlayground.tsx | 2 +- src/components/MDX/Sandpack/ResetButton.tsx | 2 +- src/components/PageHeading.tsx | 4 ++-- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/components/Layout/HomeContent.js b/src/components/Layout/HomeContent.js index d395ff384..924b66f4c 100644 --- a/src/components/Layout/HomeContent.js +++ b/src/components/Layout/HomeContent.js @@ -849,7 +849,7 @@ function ExampleLayout({ {overlayStyles.map((styles, i) => (
    ))} diff --git a/src/components/Layout/Sidebar/SidebarButton.tsx b/src/components/Layout/Sidebar/SidebarButton.tsx index 7b9f027a8..dc1f29a8d 100644 --- a/src/components/Layout/Sidebar/SidebarButton.tsx +++ b/src/components/Layout/Sidebar/SidebarButton.tsx @@ -31,7 +31,7 @@ export function SidebarButton({ })}>
    diff --git a/src/components/MDX/Sandpack/OpenInCodeSandboxButton.tsx b/src/components/MDX/Sandpack/OpenInCodeSandboxButton.tsx index f943ee6ff..78286aeaf 100644 --- a/src/components/MDX/Sandpack/OpenInCodeSandboxButton.tsx +++ b/src/components/MDX/Sandpack/OpenInCodeSandboxButton.tsx @@ -11,7 +11,7 @@ export const OpenInCodeSandboxButton = () => { className="text-sm text-primary dark:text-primary-dark inline-flex items-center hover:text-link duration-100 ease-in transition mx-1 ms-2 md:ms-1" title="Open in CodeSandbox"> diff --git a/src/components/MDX/Sandpack/OpenInTypeScriptPlayground.tsx b/src/components/MDX/Sandpack/OpenInTypeScriptPlayground.tsx index f4b7ba77d..7284912e3 100644 --- a/src/components/MDX/Sandpack/OpenInTypeScriptPlayground.tsx +++ b/src/components/MDX/Sandpack/OpenInTypeScriptPlayground.tsx @@ -16,7 +16,7 @@ export const OpenInTypeScriptPlaygroundButton = (props: {content: string}) => { target="_blank" rel="noreferrer"> diff --git a/src/components/MDX/Sandpack/ResetButton.tsx b/src/components/MDX/Sandpack/ResetButton.tsx index 243ce2349..0d1e22c80 100644 --- a/src/components/MDX/Sandpack/ResetButton.tsx +++ b/src/components/MDX/Sandpack/ResetButton.tsx @@ -15,7 +15,7 @@ export function ResetButton({onReset}: ResetButtonProps) { onClick={onReset} title="Reset Sandbox" type="button"> - Reset + Reset ); } diff --git a/src/components/PageHeading.tsx b/src/components/PageHeading.tsx index b6437b46b..076a38be9 100644 --- a/src/components/PageHeading.tsx +++ b/src/components/PageHeading.tsx @@ -35,13 +35,13 @@ function PageHeading({ {canary && ( )} {status ? —{status} : ''}

    {description && ( -

    +

    {description}

    )} From 842c24c9aefaa60b7ae9b46b002bd1b3cf4d31f3 Mon Sep 17 00:00:00 2001 From: Thomas Charuel Date: Thu, 17 Aug 2023 04:17:59 +0200 Subject: [PATCH 3/6] Fix broken link for Typescript Discord invite (#6224) --- src/content/learn/typescript.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/learn/typescript.md b/src/content/learn/typescript.md index d437096e1..5695b755f 100644 --- a/src/content/learn/typescript.md +++ b/src/content/learn/typescript.md @@ -460,4 +460,4 @@ We recommend the following resources: - [React TypeScript Cheatsheet](https://react-typescript-cheatsheet.netlify.app/) is a community-maintained cheatsheet for using TypeScript with React, covering a lot of useful edge cases and providing more breadth than this document. - - [TypeScript Community Discord](discord.com/invite/typescript) is a great place to ask questions and get help with TypeScript and React issues. \ No newline at end of file + - [TypeScript Community Discord](https://discord.com/invite/typescript) is a great place to ask questions and get help with TypeScript and React issues. \ No newline at end of file From faed7864c792c612c42bc5bcb138f729bc9ea15c Mon Sep 17 00:00:00 2001 From: tmtm8976 Date: Sun, 20 Aug 2023 08:06:37 +0300 Subject: [PATCH 4/6] fixing typos & rephrasing --- src/content/learn/keeping-components-pure.md | 52 ++++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/src/content/learn/keeping-components-pure.md b/src/content/learn/keeping-components-pure.md index 824f33e23..74774a3bf 100644 --- a/src/content/learn/keeping-components-pure.md +++ b/src/content/learn/keeping-components-pure.md @@ -4,7 +4,7 @@ title: الحفاظ على نقاء المكوّنات -بعض دوال JavaScript *نقية.* الدوال النقية (pure functions) تقوم فقط بإجراء حساب ولا شيء اكثر. من خلال كتابة مكوّناتك (components) بصرامة كدوال نقية، يمكنك تجنب صنف كامل من الأخطاء (bugs) المحيرة والسلوك غير المتوقع مع نمو قاعدة التعليمات البرمجية (codebase) الخاصة بك. للحصول على هذه الفوائد، هناك بعض القواعد التي يجب عليك اتباعها. +بعض دوال JavaScript *نقية.* الدوال النقية تقوم فقط بإجراء حساب ولا شيء اكثر. من خلال كتابة مكوّناتك بصرامة كدوال نقية، يمكنك تجنب صنف كامل من الأخطاء المحيرة والسلوك غير المتوقع مع نمو قاعدة التعليمات البرمجية الخاصة بك. للحصول على هذه الفوائد، هناك بعض القواعد التي يجب عليك اتباعها. @@ -22,7 +22,7 @@ title: الحفاظ على نقاء المكوّنات في علم الحاسب (وخاصة عالم البرمجة الوظيفية (functional programming)), [الدالة النقية](https://wikipedia.org/wiki/Pure_function) هي دالة بالخواص التالية: * **تهتم بشؤونها.** لا تغير أي كائنات أو متغيرات كانت موجودة قبل استدعائها. -* **نفس الدخل، نفس الخرج** بإعطاء نفس المدخلات ، يجب أن تُرجع الدالة النقية نفس النتيجة دائمًا. +* **نفس المدخلات تؤدي لنفس المخرجات** بإعطاء نفس المدخلات ، يجب أن تُرجع الدالة النقية نفس النتيجة دائمًا. قد تكون بالفعل على دراية بمثال واحد من الوظائف النقية: المعادلات في الرياضيات. @@ -69,7 +69,7 @@ export default function App() {

    وصفة شاي متبل

    لاثنين

    -

    لتجمًع

    +

    لتجمّع

    ); @@ -78,13 +78,13 @@ export default function App() { -عند تمرير `drinkers={2}` إلى `Recipe`, ستعيد JSX تحتوي على `2 cups of water`. دائمًا. +عند تمرير `drinkers={2}` إلى `Recipe`, ستعيد JSX تحتوي على `2 اكواب من الماء`. دائمًا. -إذا قمت بتمرير `drinkers={4}`, ستعيد JSX تحتوي على `4 cups of water`. دائمًا. +إذا قمت بتمرير `drinkers={4}`, ستعيد JSX تحتوي على `4 اكواب من الماء`. دائمًا. تمامًا مثل الصيغ الرياضية. -يمكنك التفكير في المكوّنات الخاصة بك كوصفات: إذا اتبعتها ولم تقم بإدخال مكوّنات جديدة أثناء عملية الطهي، ستحصل على نفس الطبق في كل مرة. هذا "الطبق" هو ال JSX الذي يقدمه المكوّن لReact لل[تصيير.](/learn/render-and-commit) +يمكنك التفكير في المكوّنات الخاصة بك كوصفات: إذا اتبعتها ولم تقم بإدخال مكوّنات جديدة أثناء عملية الطهي، ستحصل على نفس الطبق في كل مرة. هذا "الطبق" هو ال JSX الذي يقدمه المكوّن لReact [للتصيير.](/learn/render-and-commit) @@ -94,7 +94,7 @@ export default function App() { -فيما يلي مكوّن يخالف هذا القاعدة: +فيما يلي مكوّن يخالف هذه القاعدة: @@ -120,7 +120,7 @@ export default function TeaSet() { -يقوم هذا المكوّن بقراءة وكتابة متغير `guest` المعلن خارجه. هذا يعني أن **استدعاء هذا المكوّن مرات متعددة سينتج** وما هو أكثر من ذلك ، إذا قرأت المكوّنات الأخرى `guest`, سوف تنتج JSX مختلف , أيضًا ، اعتمادًا على متى تم تصييرها! وهذا لا يمكن توقعه +يقوم هذا المكوّن بقراءة وكتابة متغير `guest` المعلن خارجه. هذا يعني أن **استدعاء هذا المكوّن مرات متعددة سينتج JSX مختلف** بل وأكثر من ذلك ، إذا قرأت المكوّنات الأخرى `guest`, سوف تنتج JSX مختلف , أيضًا ، اعتمادًا على متى تم تصييرها! وهذا لا يمكن توقعه نعود إلى صيغتنا السابقة y = 2x, الآن حتى إذا كان x = 2, لا يمكننا الاعتماد على أن y = 4. قد تفشل اختباراتنا ، وقد يكون, المستخدمون مشوشين, وقد تسقط الطائرات من السماء - يمكنك رؤية كيف يمكن أن يؤدي ذلك إلى خلل مربك! @@ -160,17 +160,17 @@ export default function TeaSet() { React يوفر "وضعًا صارمًا"(Strict Mode) يقوم فيه باستدعاء دالة كل مكوّن مرتين أثناء التطوير. **من خلال استدعاء وظائف المكوّن مرتين، يساعد الوضع الصارم في العثور على المكوّنات التي تخالف هذه القواعد.** -لاحظ كيف عرض المثال الأصلي "Guest #2", "Guest #4", و "Guest #6" بدلاً من "Guest #1", "Guest #2", و "Guest #3". كانت الدالة الأصلية غير نقية، لذا تعطلت عند استدعاؤها مرتين. ولكن الإصدار النقي المُصلح يعمل حتى إذا تم استدعاء الوظيفة مرتين. **الدوال النقية تقوم بالحساب فقط، لذلك لن يتغير أي شيء عند استدعائها مرتين**--تمامًا مثل استدعاء `double(2)` مرتين لن يتغير ما يتم إرجاعه، وحل y = 2x مرتين لن يغير ما هو y. نفس المدخلات، نفس المخرجات. دائمًا. +لاحظ كيف عرض المثال الأصلي "Guest #2", "Guest #4", و "Guest #6" بدلاً من "Guest #1", "Guest #2", و "Guest #3". كانت الدالة الأصلية غير نقية، لذا تعطلت عند استدعاءها مرتين. ولكن الإصدار النقي المُصلح يعمل حتى إذا تم استدعاء الوظيفة مرتين. **الدوال النقية تقوم بالحساب فقط، لذلك لن يتغير أي شيء عند استدعائها مرتين**--تمامًا مثل استدعاء `double(2)` مرتين لن يتغير ما يتم إرجاعه، وحل y = 2x مرتين لن يغير ما هو y. نفس المدخلات، نفس المخرجات. دائمًا. -الوضع الصارم لا يؤثر في الإنتاج، لذلك لن يبطئ التطبيق لمستخدمينك. يمكنك الانضمام إلى الوضع الصارم, عن طريق تغليف عنصر الجذر(root component) الخاص بك في ``. تفعل بعض الإطارات ذلك افتراضيًا. +الوضع الصارم لا يؤثر في الإنتاج، لذلك لن يبطئ التطبيق لمستخدمينك. يمكنك الانضمام إلى الوضع الصارم, عن طريق تغليف المكّون الجذر(root component) الخاص بك في ``. تفعل بعض الإطارات ذلك افتراضيًا. ### التغيير المحلي: سر صغير لمكوّناتك {/*local-mutation-your-components-little-secret*/} -في المثال أعلاه، كان المشكلة في أن المكوّن قام بتغيير متغير *موجود مسبقًا* أثناء التصيير. يُطلق عليها في كثير من الأحيان **"طفرة"** لجعلها تبدو أكثر رعبًا. الدوال النقية لا تغيّر المتغيرات خارج نطاق الدالة أو الكائنات التي تم إنشاؤها قبل الاستدعاء - هذا يجعلها غير نقية! +في المثال أعلاه، كانت المشكلة في أن المكوّن قام بتغيير متغير *موجود مسبقًا* أثناء التصيير. يُطلق عليها في كثير من الأحيان **"طفرة"** لجعلها تبدو أكثر رعبًا. الدوال النقية لا تغيّر المتغيرات خارج نطاق الدالة أو الكائنات التي تم إنشاؤها قبل الاستدعاء - هذا يجعلها غير نقية! -ومع ذلك, **فمن المسموح تمامًا بتغيير المتغيرات والكائنات التي قمت بإنشائها *فقط* خلال العرض** في هذا المثال, قم بإنشاء `[]` مصفوفة, وعيينها إلى متغير `cups`, ثم `ادفع(push)` اثني عشر كوبًا فيها: +ومع ذلك, **فمن المسموح تمامًا بتغيير المتغيرات والكائنات التي قمت بإنشائها *فقط* خلال التصيير** في هذا المثال, قم بإنشاء `[]` مصفوفة, وعيينها إلى متغير `cups`, ثم ادفع `(push)` اثني عشر كوبًا فيها: @@ -190,31 +190,31 @@ export default function TeaGathering() { -إذا تم إنشاء متغير `cups` او `[]` مصفوفة خارج دالة `TeaGathering` فسيكون هذا مشكلة كبيرة! ستقوم بتغيير كائن *موجود مسبقًا* عن طريق دفع العناصر في تلك المصفوفة. +إذا تم إنشاء متغير `cups` او `[]` مصفوفة خارج دالة `TeaGathering` فستكون هذه مشكلة كبيرة! ستقوم بتغيير كائن *موجود مسبقًا* عند دفع العناصر في تلك المصفوفة. -ومع ذلك, فإنه يعد أمرًا صحيحًا لأنك قمت بإنشائهم *خلال نفس العرض*, داخل `TeaGathering`. لن يعرف أي كود خارج `TeaGathering` بدًا أن هذا حدث. يُطلق عليه **"تغيير المحلي"**—هو مثل سر صغير لمكوّناتك. +ومع ذلك, فإنه يعد أمرًا صحيحًا لأنك قمت بإنشائهم *خلال نفس التصيير*, داخل `TeaGathering`. لن يعرف أي كود خارج `TeaGathering` ابدًا أن هذا حدث. يُطلق عليه **"تغيير المحلي"**—هو مثل سر صغير لمكوّناتك. ## المكان الذي يمكنك فيه التسبب بآثار جانبية {/*where-you-_can_-cause-side-effects*/} -على الرغم من أن البرمجة الوظيفية تعتمد بشدة على النقاء, إلا أنه في نقطة ما، في, مكان ما،يجب أن يتغير _شيء_. هذه هي نقطة البرمجة! هذه التغييرات - تحديث الشاشة، بدء الرسوم المتحركة، تغيير البيانات - تسمى **الآثار الجانبية** إنها أشياء تحدث _"على الجانب"_, وليست خلال التصيير. +على الرغم من أن البرمجة الوظيفية تعتمد بشدة على النقاء، إلا أنه في نقطة ما، في مكان ما ،يجب أن يتغير _شيء_. هذه هي النقطة من البرمجة! هذه التغييرات - تحديث الشاشة، بدء الرسوم المتحركة، تغيير البيانات - تسمى **الآثار الجانبية** إنها أشياء تحدث _"على الجانب"_, وليس خلال التصيير. -في React, **تنتمي الآثار الجانبية عادةً داخل [معالجات الأحداث(event handlers).](/learn/responding-to-events)** معالجات الأحداث هي الدوال التي يقوم React بتشغيلها عندما تقوم بإجراء بعض الإجراءات—على سبيل المثال، عند النقر فوق زر. على الرغم من أن معالجات الأحداث تم تعريفها *داخل* المكوّن الخاص بك، إلا أنها لا تعمل *خلال* التصيير! **لذلك، فإن معالجات الأحداث لا تحتاج إلى أن تكون نقية.** +في React, **تنتمي الآثار الجانبية عادةً داخل [معالجات الأحداث(event handlers).](/learn/responding-to-events)** معالجات الأحداث هي الدوال التي يقوم React بتشغيلها عندما تقوم بإجراء بعض الإجراءات—على سبيل المثال، عند النقر فوق زر. على الرغم من أن معالجات الأحداث يتم تعريفها *داخل* المكوّن الخاص بك، إلا أنها لا تعمل *خلال* التصيير! **لذلك، فإن معالجات الأحداث لا يجب أن تكون نقية.** -إذا استنفذت كل الخيارات الأخرى ولم تتمكن من العثور على معالج الأحداث المناسب لآثار جانبية، فيمكنك تثبيتها على JSX المُرجَع الخاص بك باستدعاء[`useEffect`](/reference/react/useEffect) في مكوّنك. يخبر هذا React بتنفيذها لاحقًا، بعد التصيير، عندما يسمح بالآثار الجانبية. **ومع ذلك، يجب أن يكون هذا النهج هو خيارك الأخير.** +إذا استنفذت كل الخيارات الأخرى ولم تتمكن من العثور على معالج أحداث مناسب للآثار الجانبية، فيمكنك ربطها على JSX المُرجَع الخاص بك باستدعاء[`useEffect`](/reference/react/useEffect) في مكوّنك. يخبر هذا React بتنفيذها لاحقًا، بعد التصيير، عندما يسمح بالآثار الجانبية. **ومع ذلك، يجب أن يكون هذا النهج هو خيارك الأخير.** -عندما يكون ذلك ممكنًا، حاول التعبير عن منطقك فقط من خلال التصرير. ستتفاجأ الى اي مدى يمكن لهذاأن يأخذك! +عندما يكون ذلك ممكنًا، حاول التعبير عن منطقك فقط من خلال التصرير. ستتفاجأ الى اي مدى يمكن لهذا أن يأخذك! #### لماذا يهتم React بالنقاء؟ {/*why-does-react-care-about-purity*/} -يتطلب كتابة الدوال النقية بعض العادات والانضباط. ولكنه يفتح أيضًا فرصًا رائعة +يتطلب كتابة الدوال النقية بعض العادات والانضباط. ولكنه يفتح أيضًا فرصًا رائعة: * يمكن لمكوّناتك أن تعمل في بيئة مختلفة - على سبيل المثال، على الخادم! نظرًا لأنها تعيد نفس النتيجة لنفس المدخلات، يمكن لمكوّن واحد أن يخدم العديد من طلبات المستخدم. -* يمكنك تحسين الأداء من خلال [تخطي تصيير](/reference/react/memo) المكوّنات التي لم تتغير مدخلاتها. هذا آمن لأن الدوال النقية تعيد نفس النتائج دائمًا، لذلك فهي آمنة للتخزين المؤقت. +* يمكنك تحسين الأداء من خلال [تخطي تصيير](/reference/react/memo) المكوّنات التي لم تتغير مدخلاتها. هذا آمن لأن الدوال النقية تعيد نفس النتائج دائمًا، لذلك فهي آمنة للتخزين المؤقت (cashe). * إذا تغيرت بعض البيانات في منتصف تصيير شجرة مكوّنات عميقة، يمكن لـReact إعادة بدء التصيير دون إضاعة الوقت لإنهاء التصيير القديم. يجعل النقاء من الآمن التوقف عن الحساب في أي وقت. -كل الميزات الجديدة التي نقوم ببنائها في React تستفيد من النقاء. من جلب البيانات إلى الرسوم المتحركة إلى الأداء، يفتح الحفاظ على المكوّنات نقية قوة نمط React. +كل الميزات الجديدة التي نقوم ببنائها في React تستفيد من النقاء. من جلب البيانات إلى الرسوم المتحركة إلى الأداء، الحفاظ على المكوّنات نقية يطلق العنان لقوة نموذج React. @@ -222,11 +222,11 @@ export default function TeaGathering() { * يجب أن يكون المكوّن نقيًا، مما يعني: * **يهتم بأمره الخاص.** لا يجب أن يغير أي كائنات أو متغيرات كانت موجودة قبل التصيير. - * **نفس المدخلات، نفس المخرجات.** باعطاء نفس المدخلات، يجب على المكوّن أن يعيد دائمًا نفس JSX. + * **نفس المدخلات تؤدي لنفس المخرجات.** باعطاء نفس المدخلات، يجب على المكوّن أن يعيد دائمًا نفس JSX. * يمكن أن يحدث التصيير في أي وقت ، لذلك لا يجب أن تعتمد المكوّنات على تسلسل التصيير لبعضها البعض. * لا يجب تغيير أي من المدخلات التي تستخدمها المكوّنات الخاصة بك للتصيير. ويشمل ذلك الخصائص والحالة والسياق. لتحديث الشاشة ، استخدم, ["set" state](/learn/state-a-components-memory) بدلاً من تغيير الكائنات الموجودة مسبقًا. -* يجب السعي للتعبير عن منطق المكوّن في JSX الذي تعيده. عندما تحتاج إلى "تغيير الأشياء" ، عادةً ما تريد القيام بذلك في معالج الحدث(event listener). كخيار أخير ، يمكنك استخدام `useEffect`. -* يتطلب كتابة الدوال النقية بعض الممارسة ، ولكنه يفتح باب قوة نمط React. +* يجب ان تسعى للتعبير عن منطق المكوّن في الJSX الذي تعيده. عندما تحتاج إلى "تغيير الأشياء" ، عادةً ما تريد القيام بذلك في معالج الحدث(event listener). كخيار أخير ، يمكنك استخدام `useEffect`. +* يتطلب كتابة الدوال النقية بعض الممارسة ، ولكنه يطلق العنان لقوة نموذج React. @@ -580,7 +580,7 @@ h1 { margin: 5px; font-size: 18px; } -#### إصلاح صينية القصص المعطوبة {/*fix-a-broken-story-tray*/} +#### أصلح علبة قصة مكسورة {/*fix-a-broken-story-tray*/} يطلب منك الرئيس التنفيذي لشركتك إضافة "قصص" إلى تطبيق الساعة الخاص بك على الإنترنت ، ولا يمكنك الرفض. لقد كتبت مكوّن `StoryTray` الذي يقبل قائمة من القصص `stories` ، تليها "إنشاء قصة" العنصر النائب. @@ -768,7 +768,7 @@ li { -بديلًا عن ذلك ، يمكنك إنشاء مصفوفة _جديدة_ (عن طريق نسخ الحالية) قبل دفع عنصر فيها: +بدلًا عن ذلك ، يمكنك إنشاء مصفوفة _جديدة_ (عن طريق نسخ الحالية) قبل دفع عنصر فيها: From bb788d13536fb8e5090edf640cd8efec3b978a2a Mon Sep 17 00:00:00 2001 From: tmtm8976 Date: Sun, 20 Aug 2023 08:41:46 +0300 Subject: [PATCH 5/6] fixing typos & rephrasing --- src/content/learn/keeping-components-pure.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/content/learn/keeping-components-pure.md b/src/content/learn/keeping-components-pure.md index 74774a3bf..d0764fe8d 100644 --- a/src/content/learn/keeping-components-pure.md +++ b/src/content/learn/keeping-components-pure.md @@ -122,7 +122,7 @@ export default function TeaSet() { يقوم هذا المكوّن بقراءة وكتابة متغير `guest` المعلن خارجه. هذا يعني أن **استدعاء هذا المكوّن مرات متعددة سينتج JSX مختلف** بل وأكثر من ذلك ، إذا قرأت المكوّنات الأخرى `guest`, سوف تنتج JSX مختلف , أيضًا ، اعتمادًا على متى تم تصييرها! وهذا لا يمكن توقعه -نعود إلى صيغتنا السابقة y = 2x, الآن حتى إذا كان x = 2, لا يمكننا الاعتماد على أن y = 4. قد تفشل اختباراتنا ، وقد يكون, المستخدمون مشوشين, وقد تسقط الطائرات من السماء - يمكنك رؤية كيف يمكن أن يؤدي ذلك إلى خلل مربك! +نعود إلى صيغتنا السابقة y = 2x, الآن حتى إذا كان x = 2, لا يمكننا الاعتماد على أن y = 4. قد تفشل اختباراتنا ، وقد يصبح المستخدمون مشوشين, وقد تسقط الطائرات من السماء - يمكنك رؤية كيف يمكن أن يؤدي ذلك إلى خلل مربك! يمكنك إصلاح هذا العنصر عن طريق [تمرير `guest` كخاصية](/learn/passing-props-to-a-component): @@ -146,9 +146,9 @@ export default function TeaSet() { -الآن يعتبر المكوّن الخاص بك نقيًا، حيث أن JSX الذي يُرجع يعتمد فقط على خاصية `guest`. +الآن يعتبر المكوّن الخاص بك نقيًا، حيث أن JSX الذي يُرجعه يعتمد فقط على خاصية `guest`. -بشكل عام، لا يجب عليك أن تتوقع أن يتم تقديم المكوّنات الخاصة بك بترتيب معين. لا يهم إذا قمت بطلب y = 2x قبل أو بعد y = 5x: ستتم حل كلا الصيغ بشكل مستقل عن بعضهما البعض. بنفس الطريقة، يجب على كل مكوّن "أن يفكر لنفسه" فقط، ولا يحاول التنسيق أو الاعتماد على المكوّنات الأخرى أثناء التصيير. التصيير مثل امتحان مدرسي: يجب على كل مكوّن حساب JSX بمفرده! +بشكل عام، لا يجب عليك أن تتوقع أن يتم تصيير المكوّنات الخاصة بك بترتيب معين. لا يهم إذا قمت بطلب y = 2x قبل أو بعد y = 5x: ستتم حل كلا الصيغ بشكل مستقل عن بعضهما البعض. بنفس الطريقة، يجب على كل مكوّن "أن يفكر لنفسه" فقط، ولا يحاول التنسيق أو الاعتماد على المكوّنات الأخرى أثناء التصيير. التصيير مثل امتحان مدرسي: يجب على كل مكوّن حساب JSX بمفرده! @@ -192,15 +192,15 @@ export default function TeaGathering() { إذا تم إنشاء متغير `cups` او `[]` مصفوفة خارج دالة `TeaGathering` فستكون هذه مشكلة كبيرة! ستقوم بتغيير كائن *موجود مسبقًا* عند دفع العناصر في تلك المصفوفة. -ومع ذلك, فإنه يعد أمرًا صحيحًا لأنك قمت بإنشائهم *خلال نفس التصيير*, داخل `TeaGathering`. لن يعرف أي كود خارج `TeaGathering` ابدًا أن هذا حدث. يُطلق عليه **"تغيير المحلي"**—هو مثل سر صغير لمكوّناتك. +ومع ذلك, فإنه يعد أمرًا صحيحًا لأنك قمت بإنشائهم *خلال نفس التصيير*, داخل `TeaGathering`. لن يعرف أي كود خارج `TeaGathering` ابدًا أن هذا حدث. يُطلق على هذا **"التغيير المحلي"**—هو مثل سر صغير لمكوّناتك. -## المكان الذي يمكنك فيه التسبب بآثار جانبية {/*where-you-_can_-cause-side-effects*/} +## اين يمكنك التسبب بآثار جانبية {/*where-you-_can_-cause-side-effects*/} على الرغم من أن البرمجة الوظيفية تعتمد بشدة على النقاء، إلا أنه في نقطة ما، في مكان ما ،يجب أن يتغير _شيء_. هذه هي النقطة من البرمجة! هذه التغييرات - تحديث الشاشة، بدء الرسوم المتحركة، تغيير البيانات - تسمى **الآثار الجانبية** إنها أشياء تحدث _"على الجانب"_, وليس خلال التصيير. في React, **تنتمي الآثار الجانبية عادةً داخل [معالجات الأحداث(event handlers).](/learn/responding-to-events)** معالجات الأحداث هي الدوال التي يقوم React بتشغيلها عندما تقوم بإجراء بعض الإجراءات—على سبيل المثال، عند النقر فوق زر. على الرغم من أن معالجات الأحداث يتم تعريفها *داخل* المكوّن الخاص بك، إلا أنها لا تعمل *خلال* التصيير! **لذلك، فإن معالجات الأحداث لا يجب أن تكون نقية.** -إذا استنفذت كل الخيارات الأخرى ولم تتمكن من العثور على معالج أحداث مناسب للآثار الجانبية، فيمكنك ربطها على JSX المُرجَع الخاص بك باستدعاء[`useEffect`](/reference/react/useEffect) في مكوّنك. يخبر هذا React بتنفيذها لاحقًا، بعد التصيير، عندما يسمح بالآثار الجانبية. **ومع ذلك، يجب أن يكون هذا النهج هو خيارك الأخير.** +إذا استنفذت كل الخيارات الأخرى ولم تتمكن من العثور على معالج أحداث مناسب للآثار الجانبية، فيمكنك ربطها على الJSX المُرجَع الخاص بك باستدعاء[`useEffect`](/reference/react/useEffect) في مكوّنك. يخبر هذا React بتنفيذها لاحقًا، بعد التصيير، عندما يسمح بالآثار الجانبية. **ومع ذلك، يجب أن يكون هذا النهج هو خيارك الأخير.** عندما يكون ذلك ممكنًا، حاول التعبير عن منطقك فقط من خلال التصرير. ستتفاجأ الى اي مدى يمكن لهذا أن يأخذك! @@ -211,7 +211,7 @@ export default function TeaGathering() { يتطلب كتابة الدوال النقية بعض العادات والانضباط. ولكنه يفتح أيضًا فرصًا رائعة: * يمكن لمكوّناتك أن تعمل في بيئة مختلفة - على سبيل المثال، على الخادم! نظرًا لأنها تعيد نفس النتيجة لنفس المدخلات، يمكن لمكوّن واحد أن يخدم العديد من طلبات المستخدم. -* يمكنك تحسين الأداء من خلال [تخطي تصيير](/reference/react/memo) المكوّنات التي لم تتغير مدخلاتها. هذا آمن لأن الدوال النقية تعيد نفس النتائج دائمًا، لذلك فهي آمنة للتخزين المؤقت (cashe). +* يمكنك تحسين الأداء من خلال [تخطي تصيير](/reference/react/memo) المكوّنات التي لم تتغير مدخلاتها. هذا آمن لأن الدوال النقية تعيد نفس النتائج دائمًا، لذلك فهي آمنة للتخزين المؤقت (cache). * إذا تغيرت بعض البيانات في منتصف تصيير شجرة مكوّنات عميقة، يمكن لـReact إعادة بدء التصيير دون إضاعة الوقت لإنهاء التصيير القديم. يجعل النقاء من الآمن التوقف عن الحساب في أي وقت. كل الميزات الجديدة التي نقوم ببنائها في React تستفيد من النقاء. من جلب البيانات إلى الرسوم المتحركة إلى الأداء، الحفاظ على المكوّنات نقية يطلق العنان لقوة نموذج React. From d9c87e9f37938d8183e2bbd7a4fa861bdfafde76 Mon Sep 17 00:00:00 2001 From: Ahmed Abdelbaset Date: Mon, 21 Aug 2023 00:55:14 +0300 Subject: [PATCH 6/6] fix small typo --- src/content/learn/keeping-components-pure.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/learn/keeping-components-pure.md b/src/content/learn/keeping-components-pure.md index d0764fe8d..d17aeecf6 100644 --- a/src/content/learn/keeping-components-pure.md +++ b/src/content/learn/keeping-components-pure.md @@ -202,7 +202,7 @@ export default function TeaGathering() { إذا استنفذت كل الخيارات الأخرى ولم تتمكن من العثور على معالج أحداث مناسب للآثار الجانبية، فيمكنك ربطها على الJSX المُرجَع الخاص بك باستدعاء[`useEffect`](/reference/react/useEffect) في مكوّنك. يخبر هذا React بتنفيذها لاحقًا، بعد التصيير، عندما يسمح بالآثار الجانبية. **ومع ذلك، يجب أن يكون هذا النهج هو خيارك الأخير.** -عندما يكون ذلك ممكنًا، حاول التعبير عن منطقك فقط من خلال التصرير. ستتفاجأ الى اي مدى يمكن لهذا أن يأخذك! +عندما يكون ذلك ممكنًا، حاول التعبير عن منطقك فقط من خلال التصيير. ستتفاجأ الى اي مدى يمكن لهذا أن يأخذك!