كيفية الترقية إلى React Router 4

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

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

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

كانت إحدى أكبر المفاجآت بالنسبة إلينا هي إهمال react-router-redux. كنا نستخدم react-router-reduxبالاقتران مع جهاز التوجيه التفاعلي v3. قادنا هذا إلى التفكير بشكل نقدي في سبب reduxاستخدامنا لجهاز التوجيه الخاص بنا في المقام الأول.

بمجرد أن بدأنا في النظر في رد فعل جهاز التوجيه v4 ، أدركنا أن الميزات الجديدة ستقضي إلى حد كبير على أي سبب لنا لاستخدام مكتبة إضافية لتوصيل جهاز التوجيه الخاص بنا و redux. لذلك ، تركنا ذلك في وضع يسمح لنا بالترقية من جهاز التوجيه 3 إلى 4 ، والإزالة   react-router-reduxمن تطبيقنا.

لذلك ، تم تكليفي بترقية جهاز التوجيه الخاص بنا إلى الإصدار 4 بعد أن كنت في المنصب فقط وأعمل مع React لمدة شهرين تقريبًا. كان هذا لأن الترقية من React Router 3 إلى React Router 4 بدت وكأنها مهمة تافهة. ولكن ، كما اكتشفت بسرعة ، كان الأمر أكثر انخراطًا قليلاً مما توقعت.

بالنظر إلى الوثائق ، و GitHub repo ، والعديد والعديد من إجابات Stack Overflow ، قمت أخيرًا بتجميع خطوات الترقية وأردت مشاركة النتائج التي توصلت إليها - خاصة لشرح كيفية إجراء تغييرات معينة ولماذا.

التغيير الأكبر الذي يجب ملاحظته ، من مبتكري React Router ، هو أن الترقية من React Router 3 إلى React Router 4 هي أكثر من مجرد تحديث بعض المكتبات والميزات - فهي تتيح لك تغيير طريقة عمل جهاز التوجيه بشكل أساسي. أراد منشئو React Router العودة إلى جهاز توجيه بسيط ، مما يسمح للمطور بتخصيصه كما يشاء.

لقد قسمت هذا الدليل إلى 5 أجزاء مختلفة:

  1. صفقة
  2. التاريخ
  3. طريق
  4. الدعائم
  5. تكامل الإحياء

صفقة

تم تغيير بنية حزمة React Router v4 بحيث لم يعد من الضروري تثبيت جهاز التوجيه التفاعلي - يجب عليك التثبيت react-router-dom(وإلغاء التثبيت react-router) ، لكنك لن تفقد أي شيء لأنه يعيد تصدير جميع react-routerصادرات. هذا يعني أنه يجب عليك أيضًا تحديث أي   react-routerبيانات استيراد إلى react-router-dom.

التاريخ

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

طريق

سمح لنا React Router v3 بوضع جميع مسارات التطبيق في ملف واحد ، والذي سنسميه router.js. ومع ذلك ، يتيح لك React Router v4 وضع المسارات في المكونات التي يعرضونها. تكمن الفكرة هنا في توجيه التطبيق ديناميكيًا - بمعنى آخر ، يحدث التوجيه أثناء عرض التطبيق.

ومع ذلك ، إذا كان لديك قاعدة رموز قديمة ذات حجم مناسب تعمل معها ، فمن المحتمل أنك لن تقوم بإجراء تغيير بهذا الحجم. لحسن الحظ ، لا يزال برنامج React Router v4 يسمح لك بوضع جميع المسارات في ملف مركزي ، وهو ما سأقوم بإنشاء جميع الأمثلة لدينا. ومع ذلك ، هناك عدد قليل من المكونات والميزات القديمة التي ستحتاج إلى استبدال.

IndexRoute

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

لتوفير واجهة المستخدم الافتراضية ، ستتيح المسارات المتعددة التي لها نفس المسار عرض جميع المكونات المرتبطة:

import { BrowserRouter as Router, Route } from 'react-router-dom';  // example of our route components    

لذلك، كل من مكونات - Home، Aboutو Contact- سيجعل. لهذا السبب ، لم يعد بإمكانك تداخل المسارات أيضًا.

بالإضافة إلى ذلك ، للسماح بمطابقة أفضل دون استخدام IndexRoute، يمكنك استخدام الكلمة الأساسية بالضبط.

import { BrowserRouter as Router, Route } from 'react-router-dom';  // example of our route components   

التوجيه الحصري

بعد إضافة الكلمة الأساسية بالضبط ، “something.com/about”سيتم توجيهها إلى عندما يرى جهاز التوجيه المسار “/about”. ولكن الآن ماذا لو كان لديك طريق آخر “/about/team”؟ كما ذكرت من قبل ، سيعرض جهاز التوجيه أي شيء يطابق. لذا، فإن المكونات المرتبطة مع كل من “/about”و   “/about/team”سوف تجعل. إذا كان هذا ما قصدته ، فهذا رائع! ومع ذلك ، إذا لم يكن هذا ما تريده ، فقد تضطر إلى وضع مفتاح تبديل حول هذه المجموعة من المسارات. سيسمح هذا للمسار الأول الذي يطابق عنوان URL بالعرض.

import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';       

لاحظ أن الكلمة الرئيسية يجب أن تظهر بالضبط لمكوِّن الصفحة الرئيسية - وإلا فستتطابق مع المسارات التالية. لاحظ أيضًا أنه يتعين علينا أن نسرد من “/about/team”قبل “/about”حتى ينتقل المسار إلى Teamالمكون بدلاً من Aboutالمكون عندما يرى   “something.com/about/team”. إذا رأيته “/about”أولاً ، فسيتوقف عند هذا الحد ويعرض Aboutالمكون لأن Switch يعرض المكون الأول فقط الذي يطابق.

المسار الافتراضي

المسار الافتراضي ، أو مسار "التقاط الكل" ، الذي يشيع استخدامه لصفحات 404 ، هو المسار الذي تستخدمه عندما لا تتطابق أي من المسارات.

في React Router v3 ، Routeكان الإعداد الافتراضي هو:

في React Router v4 ، Routeتم تغيير الإعداد الافتراضي إلى:

import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';       // this is our default route  

عندما لا تقوم بتضمين مسار في a Route، فسيتم عرض المكون دائمًا. لذلك ، كما ناقشنا أعلاه ، يمكننا استخدام Switchعنصر واحد فقط لتقديمه ، ثم وضع مسار "catch all" في النهاية (بحيث لا يستخدم ذلك قبل أن Routerيحصل على فرصة للتحقق من بقية المسارات ) ، لذلك سيتم عرض شيء ما دائمًا حتى إذا كانت المسارات الأخرى غير متطابقة.

onEnter

في السابق ، كان من الممكن أن تستخدم onEnterللتأكد من أن مكون المكون Routeيحتوي على جميع المعلومات التي يحتاجها أو للتحقق (مثل التأكد من مصادقة المستخدم) قبل تقديم المكون.

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

في React Router v3:

يصبح:

import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';        
... componentDidMount() { this.props.fetchInfo(); } ...

الدعائم

In  React Router v4, the props passed through the router have changed, as  did the way they are accessed. The Route now passes three props:

  • history
  • location
  • match

history

history contains a lot of other properties and methods, so I won’t list all of  them, but here is a selection that might be most commonly used:

  • length: number of entries in the history stack
  • location: contains the same information as below
  • push(path, [state]): pushes new entry on history stack
  • goBack(): allows you to move the pointer on the history stack back 1 entry

It’s  important to note that history is mutable, and while it contains a location property, this instance of location shouldn’t be used since it  could have been changed. Instead, you want to use the actual location prop discussed below.

location

The location has properties:

  • pathname
  • search
  • hash
  • state

location.search is used to replace location.query and it must be parsed. I used  URLSearchParams to parse it. So a URL such as  “//something.com/about?string=’hello’” would be parsed as such:

... const query = new URLSearchParams(this.props.location.search) const string = query.get('string') // string = 'hello' ...

Additionally,  the state property can be used to pass the location-specific state of components through props. So, if you wanted to pass some information  from one component to another, you could use it like this:

... // To link to another component, we could do this:  // However, if we wanted to add state to the location, we could do this: const location = { pathname: '/path/', state: { fromDashboard: true }, }  ...

So, once we get to the component rendered by that path, we’ll have access to fromDashboard from location.state.fromDashboard.

match

match has the following properties:

  • params:  gets the dynamic segments of the path from the URL — for example if the  path is “/about/:id”, in the component, accessing  this.props.match.params will give you the id in the URL
  • isExact: true if the entire URL was matched
  • path: the path in the routes that was matched
  • url: the matched portion of the URL

Redux Integration

As  I addressed earlier, we found that in our case, we didn’t need to have an additional library to connect redux with our router, especially since our main use case for this — Blocked Updates — was covered by react  router.

Blocked Updates

In  some cases, the app doesn’t update when the location changes. This is called a “Blocked Update”. This can happen if both of these conditions  are met:

  1. The component is connected to Redux via connect()(Component).
  2. The component isn’t rendered by a

In these cases, I wrapped the component’s connect with withRouter.

This  allowed the router information to follow the component when it gets linked to, so the app still updates when the Redux state changes.

And that’s it!

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

من فضلك لا تتردد في التعليق / طرح الأسئلة!