كيفية إجراء عمليات بحث المستخدم على GitHub بدون React + RxJS 6 + Recompose

هذه المقالة هي رد على مقالة الترجمة "كيفية البحث عن المستخدمين على GitHub باستخدام React + RxJS 6 + Recompose" ، التي علمتنا بالأمس فقط كيفية استخدام React و RxJS و Recompose معًا. حسنًا ، أقترح الآن أن أرى كيف يمكن تنفيذ ذلك بدون هذه الأدوات.




تنويه
قد يبدو للكثيرين أن هذه المقالة تحتوي على عناصر التصيد ، وقد كتب على عجل وعلى مروحة ... لذلك ، هذا صحيح.


نظرًا لأن هذه مقالة عودة ، فقد قررت إنشاؤها بنفس التنسيق خطوة بخطوة مثل الأصل. بالإضافة إلى ذلك ، تهدف المقالة أيضًا إلى مقارنة التنفيذ الأصلي مع ذلك الموصوف هنا. لذلك ، يحتوي على وفرة من المراجع والاقتباسات من الأصل. دعنا نبدأ.

هذه المقالة للأشخاص الذين لديهم خبرة في React و RxJS. أقوم فقط بمشاركة القوالب التي وجدتها مفيدة لإنشاء مثل واجهة المستخدم هذه.

هذه المقالة مخصصة للأشخاص الذين لديهم خبرة في استخدام جافا سكريبت (ES6) و HTML و CSS. بالإضافة إلى ذلك ، في تنفيذي ، سأستخدم إطار عمل SvelteJS "المختفي" ، ولكنه بسيط للغاية بحيث لا تحتاج إلى خبرة في استخدامه لفهم الكود.

نحن نفعل الشيء نفسه:



بدون دروس ، العمل مع دورة حياة أو setState.

نعم ، بدون فصول ، العمل مع دورة حياة أو setState. وأيضًا بدون تفاعل ، ReactDOM ، RxJS ، أعد التركيب. بالإضافة إلى ذلك ، بدون مكون FromStream ، قم بإنشاءEventHandler ، combineLatest ، الخريطة ، startWith ، setObservableConfig ، BehaviorSubject ، دمج ، من ، catchError ، تأخير ، تصفية ، خريطة ، نتف ، سويتش ماب ، اضغط ، {آخر هراء} ... باختصار ، أنت تفهم.

تحضير


كل ما تحتاجه في مثال REPL الخاص بي على موقع SvelteJS. يمكنك الشم هناك ، إما محليًا ، تنزيل المصدر من هناك (زر به رمز مميز).

أولاً ، قم بإنشاء ملف بسيط App.html ، والذي سيكون المكون الأساسي لعنصر واجهة المستخدم الخاص بنا ، مع المحتويات التالية:

<input placeholder="GitHub username"> <style> input { font-size: 20px; border: 1px solid black; border-radius: 3px; margin-bottom: 10px; padding: 10px; } </style> 


فيما يلي ، أستخدم الأنماط من المقالة الأصلية. يرجى ملاحظة أنها الآن في النطاق ، أي تنطبق فقط على هذا المكون ويمكنك استخدام أسماء العلامات بأمان عند الاقتضاء.

سأكتب الأنماط مباشرة في المكونات ، لأن SFC ، وأيضًا لأن REPL لا يدعم تصدير CSS / JS / HTML إلى ملفات مختلفة ، على الرغم من أن ذلك يتم بسهولة باستخدام معالجات Svelte .

أعد تشكيل


يستريح ...

مكون مضمن


... حمامات الشمس ...

التكوين


... شرب القهوة ...

أعد تركيب + RxJS


... بينما الآخرين ...

الخريطة


... العمل.

أضف معالج حدث


ليس حقا معالج بالطبع ، مجرد ملزم:

 <input bind:value=username placeholder="GitHub username"> 


حسنًا ، نحدد قيمة اسم المستخدم الافتراضية:

 <script> export default { data() { return { username: '' }; } }; </script> 


الآن ، إذا بدأت في كتابة شيء ما في حقل الإدخال ، فستتغير قيمة اسم المستخدم.


مشكلة البيض والدجاج


لا دجاج ولا بيض ولا مشاكل مع حيوانات أخرى ، نحن لا نستخدم RxJS.

متماسكة معا


كل شيء متفاعل ومتصل بالفعل. ثم نشرب القهوة.

مكون المستخدم


سيكون هذا المكون مسؤولاً عن عرض المستخدم الذي سننقل اسمه إليه. ستحصل على قيمة من مكون التطبيق وترجمته إلى طلب AJAX.

"واو واو واو ، خذها بسهولة" ©

معنا ، سيكون هذا المكون غبيًا وسيعرض فقط بطاقة مستخدم جميلة وفقًا لنموذج معروف سابقًا. لا يهم من أين يمكن أن تأتي البيانات و / أو في أي مكان من الواجهة نريد أن نعرض هذه البطاقة.

سيبدو مكوّن User.html كالتالي:

 <div class="github-card user-card"> <div class="header User" /> <a class="avatar" href="https://github.com/{login}"> <img src="{avatar_url}&s=80" alt={name}> </a> <div class="content"> <h1>{name || login}</h1> <ul class="status"> <li> <a href="https://github.com/{login}?tab=repositories"> <strong>{public_repos}</strong>Repos </a> </li> <li> <a href="https://gist.github.com/{login}"> <strong>{public_gists}</strong>Gists </a> </li> <li> <a href="https://github.com/{login}/followers"> <strong>{followers}</strong>Followers </a> </li> </ul> </div> </div> <style> /*  */ </style> 


Jsx / css


تمت إضافة CSS للتو إلى المكون. بدلاً من JSX ، لدينا HTMLx مضمن في Svelte.

الحاوية


الحاوية هي أي مكون أصل لمكون المستخدم. في هذه الحالة ، هو أحد مكونات التطبيق.

debounceTime


تصحيح إدخال النص لا معنى له إذا كانت العملية تستبدل القيمة في نموذج البيانات فقط. لذلك في التجليد نفسه لا نحتاج إلى ذلك.

نتف


مرشح


الخريطة


ربط


دعنا نعود إلى App.html ونستورد مكون المستخدم:

 import User from './User.html'; 


طلب بيانات


يوفر GitHub واجهة برمجة تطبيقات لاسترداد معلومات المستخدم:

للتوضيح ، نكتب فقط ملف api.js صغيرًا يجرد استلام البيانات ويصدر الوظيفة المقابلة:

 import axios from 'axios'; export function getUserCard(username) { return axios.get(`https://api.github.com/users/${username}`) .then(res => res.data); } 


وبهذه الطريقة ، نستورد هذه الوظيفة إلى App.html.

الآن نقوم بصياغة المشكلة بلغة أكثر تحديدًا: نحتاج إلى تغيير قيمة أخرى عند تغيير قيمة واحدة في نموذج البيانات (اسم المستخدم). سوف نسميها المستخدم ، على التوالي - بيانات المستخدم التي نحصل عليها من API. التفاعلية في كل مجدها.

للقيام بذلك ، اكتب خاصية Svelte المحسوبة باستخدام البناء التالي في App.html:

 <script> import { getUserCard } from './api.js'; ... export default { ... computed: { user: ({ username }) => username && getUserCard(username) } }; </script> 


هذا كل شيء ، الآن عند تغيير اسم المستخدم ، سيتم إرسال طلب لتلقي البيانات على هذه القيمة. ومع ذلك ، نظرًا لأن المجلدات تستجيب لكل تغيير ، أي الإدخال في حقل نصي ، فسيكون هناك العديد من الطلبات وسوف نتجاوز بسرعة جميع الحدود المتاحة.

في المقالة الأصلية ، تم حل هذه المشكلة بواسطة وظيفة debounceTime المضمنة في RxJS ، والتي تمنعنا من طلب البيانات كثيرًا. لتنفيذنا ، يمكنك استخدام الحل المستقل ، مثل الوعد بالتبرع أو أي حل مناسب آخر ، حيث يوجد الكثير للاختيار من بينها.

 <script> import debounce from 'debounce-promise'; import { getUserCard } from './api.js'; ... const getUser = debounce(getUserCard, 1000); ... export default { ... computed: { user: ({ username }) => username && getUser(username) } }; </script> 


لذلك ، يخلق هذا lib نسخة debounce للدالة التي تم تمريرها إليها ، والتي نستخدمها بعد ذلك في الخاصية المحسوبة.

سويتش ماب


اجاكس


توفر RxJS تطبيق أجاكس الخاص بها والذي يعمل بشكل رائع مع سويتش ماب!

نظرًا لأننا لا نستخدم RxJS وخاصة switchMap ، يمكننا استخدام أي مكتبة للعمل مع ajax.

أستخدم المحاور لأنها مناسبة لي ، ولكن يمكنك استخدام أي شيء ولا يغير جوهر المسألة.

جرب


أولاً ، نحتاج إلى تسجيل مكوِّن المستخدم لاستخدامه كعلامة قالب ، نظرًا لأن الاستيراد نفسه لا يضيف المكوِّن إلى سياق القالب:

 <script> import User from './User.html'; ... export default { components: { User } ... }; </script> 

على الرغم من الخربشة التي تبدو مفرطة ، فإن هذا يسمح ، من بين أمور أخرى ، بإعطاء أسماء علامات مختلفة لمثيلات نفس المكون ، مما يجعل القوالب الخاصة بك مفهومة بشكل أكثر دلالة.

علاوة على ذلك ، فإن قيمة المستخدم ليست البيانات نفسها ، بل هي وعد بهذه البيانات. نظرًا لأننا عمال تحميل مستقلون ولا نريد القيام بأي عمل على الإطلاق ، فما عليك سوى شرب القهوة باستخدام ملفات تعريف الارتباط.

من أجل نقل البيانات الحقيقية إلى مكون المستخدم ، يمكننا استخدام تصميم خاص للعمل مع الوعود:

 {#await user} <!--     --> {:then user} <!--      .    . --> {#if user} <User {...user} /> {/if} {/await} 

من المنطقي التحقق من وجود كائن البيانات قبل تمريره إلى مكون المستخدم. يتيح لك عامل التشغيل Spread هنا "تقسيم" كائن إلى دعائم منفصلة عند إنشاء مثيل لمكون المستخدم.



عمل أقصر.

معالجة الخطأ


حاول إدخال اسم مستخدم غير موجود.
...
طلبنا مكسور.

تفضلوا بقبول نعم ، ولكن بالتأكيد ليس لدينا))) لن يحدث شيء ، على الرغم من أن هذا ليس هو الحال بالتأكيد.

قبض على الخطأ


أضف كتلة إضافية لمعالجة الوعد المرفوض:

 {#await user} {:then user} {#if user} <User {...user} /> {/if} {:catch error} <Error {...error} /> {/await} 


خطأ في المكون


 <div class="error"> <h2>Oops!</h2> <b>{response.status}: {response.data.message}</b> <p>Please try searching again.</p> </div> 

الآن تبدو واجهة المستخدم لدينا أفضل بكثير:

ولا تقل ، والأهم من ذلك أي جهد.



مؤشر التحميل


باختصار ، بدأت المزيد من البدعة هناك ، مع جميع أنواع BehaviorSubjects وغيرها مثلهم. نضيف فقط مؤشر تحميل ولن نحلب الفيل:

 {#await user} <h3>Loading...</h3> {:then user} {#if user} <User {...user} /> {/if} {:catch error} <Error {...error} /> {/await} 

النتيجة؟

مكونان صغيران بدون منطق (المستخدم والخطأ) ومكون تحكم واحد (التطبيق) ، حيث يتم وصف منطق الأعمال الأكثر تعقيدًا في سطر واحد - إنشاء خاصية محسوبة. لا تنظف الأشياء التي يمكن ملاحظتها من الرأس إلى أخمص القدمين والوصلات +100500 أدوات لا تحتاجها.

عرض تفاعلي

اكتب كود بسيط وواضح. اكتب كودًا أقل ، مما يعني عمل أقل ووقت أطول مع عائلتك. مباشر!

كل السعادة والصحة!

الكل :)


لمعلوماتك


إذا نظرت بالفعل إلى المثال في REPL ، فمن المحتمل أنك لاحظت النخب مع تحذير من أسفل اليسار:
تم جمعها ، ولكن مع تحذير واحد - تحقق من وحدة التحكم للحصول على التفاصيل

إذا لم تكن كسولًا جدًا لفتح وحدة التحكم ، فسترى هذه الرسالة:
محدد CSS غير مستخدم
.user-card .Organization {
موضع الخلفية: أعلى اليمين ؛
}}

يخبرنا Svelte Static Analyzer بأنه لا يتم استخدام بعض أنماط المكونات. بالإضافة إلى ذلك ، بناءً على طلبك أو أمر إعدادات المترجم الافتراضية ، ستتم إزالة الأنماط غير المستخدمة من حزمة css النهائية بدون مشاركتك.

ف / ق


اقرأ مقالات أخرى حول Svelte ، وكذلك اطلع على قناة Telegram باللغة الروسية SvelteJS . سنكون سعداء لرؤيتك!

Source: https://habr.com/ru/post/ar419653/


All Articles