اذهب إلى المحتوى

السؤال

Recommended Posts

  • 0
نشر

أثناء تطويرك لأي تطبيق يستخدم React Router ستحتاج في بعض الأوقات معرفة المسار الحالي الذي يكون به المستخدم هنا يأتي دور الخطاف ()useLocation هو الذي يقوم بهذه المهمة ويوفر لنا كافة البيانات من العنوان.

مثلا في حالة كان العنوان الحالى في المتصفح كالتالي

http://localhost:3000/products/23?ref=google#reviews

عند استخدام ()useLocation في المكون كالتالي

import { useLocation } from "react-router";

const MyComponent = () => {
  const location = useLocation();
  console.log(location);

 return <p>what is the useLocation hook</p>
};

هنا ()useLocation يعيد لنا الكائن location وعند طباعة هذا الكائن يكون بداخله التالي

{
  pathname: "/products/23",
  search: "?ref=google",
  hash: "#reviews",
  state: null,
  key: "xyz123"
}
  • pathname: المسار الحالي داخل التطبيق مثل: products/23/
  • search: كود الاستعلام (Query string) الموجود بعد ? مثل: ref=google?
  • hash: الجزء الموجود بعد # ويستخدم غالبا للتمرير داخل الصفحة مثل: reviews#
  • state: بيانات اختيارية يمكن إرسالها عند التنقل بين الصفحات.
  • key: قيمة فريدة تلقائية يضعها React Router لكل عملية تنقل.

وبالإضافة إلى استخدام ()useLocation من مكتبة React Router يمكنك أيضا الاعتماد على window.location وهو كائن مدمج من المتصفح (Browser API)  للحصول على نفس المعلومات المتعلقة بالعنوان (URL) الحالي عندما تحتاج إلى معلومات وبيانات أوسع مثل اسم الدومين والبروتوكول والمنفذ.
إذا كنت داخل أي مكون React أو حتى خارج React أي تستخدم دالة جافاسكربت فقط وليس بداخل مكون.
في حالة كان العنوان الحالى في المتصفح كالتالي

http://localhost:3000/products/23?ref=google#reviews

يمكنك كتابة:

console.log(window.location);

وسيطبع لك كائن يحتوي على معلومات شبيهة جدا بما يعيده ()useLocation مثل:

{
  href: "http://localhost:3000/products/23?ref=google#reviews",
  origin: "http://localhost:3000",
  protocol: "http:",
  host: "localhost:3000",
  hostname: "localhost",
  port: "3000",
  pathname: "/products/23",
  search: "?ref=google",
  hash: "#reviews"
}
  • href: الرابط الكامل الحالي وهو http://localhost:3000/products/23?ref=google#reviews
  • origin: البروتوكول + الدومين + البورت وهو http://localhost:3000
  • protocol: نوع البروتوكول المستخدم وهو :http
  • host: اسم المضيف + البورت وهو localhost:3000
  • hostname: اسم المضيف فقط (بدون بورت) وهو localhost
  • port: رقم البورت المستخدم3000
  • pathname: المسار داخل الموقع products/23/
  • search: كود الاستعلام (Query string) وهو ref=google?
  • hash: الجزء بعد علامة # في الرابط وهو reviews#
  • 0
نشر

هناك أمر هام بجانب ما تم تفصيله وهو، عندما يتغير عنوان URL بسبب نقر المستخدم على <Link> أو استخدام useNavigate، فخطاف useLocation يتسبب في إعادة تصيير أي re-render للمكون الذي يستخدمه، لذا واجهة المستخدم سيتم تحديثها تلقائيًا لتعكس المسار الجديد.

بمعنى لو يوجد Sidebar وتريد تظليل الرابط النشط حاليًا، فاستخدام useLocation().pathname سيضمن تحديث التظليل فورًا عند التنقل بين الصفحات.

كذلك تستطيع استخدام كائن location.search لتحليل متغيرات البحث لاستخراج قيمة معينة، كالتالي:

import { useLocation } from "react-router-dom";

const ProductPage = () => {
  const location = useLocation(); 

  const queryParams = new URLSearchParams(location.search);
  const refValue = queryParams.get('ref');

  if (refValue === 'google') {
    console.log("User came from Google!");
  }

  return <div>Product Details</div>;
};

أو في صفحة البحث عند النقر على المنتج:


<Link 
  to={`/products/${product.id}`} 
  state={{ from: '/search?q=laptops' }} 
>
  View Product
</Link>

وفي صفحة المنتج:

import { useLocation, Link } from "react-router-dom";

const ProductDetails = () => {
  const location = useLocation();
  const fromPath = location.state?.from; 

  return (
    <div>
      <h1>Product Details</h1>
      {fromPath && <Link to={fromPath}>← Back to search results</Link>}
    </div>
  );
};

 

بالتالي لو المستخدم قادم من صفحة البحث، سيتم إظهار رابط العودة إلى البحث.

  • 0
نشر
import React, { useEffect, useState } from 'react'
import { AiOutlineMenu } from "react-icons/ai";
import { IoMdArrowDropdown } from "react-icons/io";
import { Link, useLocation } from 'react-router-dom';
import { PiSignInBold } from "react-icons/pi";
import { ImUserPlus } from "react-icons/im";

const NavLinks = [
  {title:"Home" , link:"/"},
  {title:"About" , link:"/about"},
  {title:"Accessories" , link:"/accessories"},
  {title:"Blog" , link:"/blog"},
  {title:"Contact" , link:"/contact"},
]


const BottomHeader = () => {
    const location = useLocation();
    const [categories , setCategories] = useState([]);
    const [isCategoryOpen , setIsCategoryOpen] = useState(false);
  useEffect(() => {
    fetch('https://dummyjson.com/products/categories')
    .then((res) => res.json())
    .then((data) => setCategories(data))
  },[])

  console.log(isCategoryOpen)
  return (
    <section className='bottom-header'>
        <div className="container">
          <nav className="nav">
            <div className="category-nav">
              <div className="category-btn" onClick={() => setIsCategoryOpen(!isCategoryOpen)}>
              <AiOutlineMenu />
              <p>Browse Category</p>
              <IoMdArrowDropdown />
              </div>

              <div className={`category-navList ${isCategoryOpen ? 'active' : ''}`}>
                 {categories.map((category) => (
                  <Link  key={category.slug} to={category.slug}>{category.name}</Link>
                 ))}
              </div>
            </div>

            <div className="nav-links">
              {NavLinks.map((item) =>(
              <li key={item.link} className={location.pathname === item.link ? 'active' : ''}><Link to={item.link}>{item.title}</Link></li>
              ))}
            </div>
          </nav>

          <div className="sign-regs-icon">
            <Link to="/"><PiSignInBold /></Link>
            <Link to="/"><ImUserPlus /></Link>
          </div>
        </div>
    </section>
  )
}

export default BottomHeader;

لقد استخدمت الخطاف useLocation بهذا الشكل 

هل يمكن توضيح ما الذي سيقوم به 

تبين لي انه سيظهر كلاس active 

  • 0
نشر
بتاريخ 42 دقائق مضت قال Hxfhf Ucicic:
import React, { useEffect, useState } from 'react'
import { AiOutlineMenu } from "react-icons/ai";
import { IoMdArrowDropdown } from "react-icons/io";
import { Link, useLocation } from 'react-router-dom';
import { PiSignInBold } from "react-icons/pi";
import { ImUserPlus } from "react-icons/im";

const NavLinks = [
  {title:"Home" , link:"/"},
  {title:"About" , link:"/about"},
  {title:"Accessories" , link:"/accessories"},
  {title:"Blog" , link:"/blog"},
  {title:"Contact" , link:"/contact"},
]


const BottomHeader = () => {
    const location = useLocation();
    const [categories , setCategories] = useState([]);
    const [isCategoryOpen , setIsCategoryOpen] = useState(false);
  useEffect(() => {
    fetch('https://dummyjson.com/products/categories')
    .then((res) => res.json())
    .then((data) => setCategories(data))
  },[])

  console.log(isCategoryOpen)
  return (
    <section className='bottom-header'>
        <div className="container">
          <nav className="nav">
            <div className="category-nav">
              <div className="category-btn" onClick={() => setIsCategoryOpen(!isCategoryOpen)}>
              <AiOutlineMenu />
              <p>Browse Category</p>
              <IoMdArrowDropdown />
              </div>

              <div className={`category-navList ${isCategoryOpen ? 'active' : ''}`}>
                 {categories.map((category) => (
                  <Link  key={category.slug} to={category.slug}>{category.name}</Link>
                 ))}
              </div>
            </div>

            <div className="nav-links">
              {NavLinks.map((item) =>(
              <li key={item.link} className={location.pathname === item.link ? 'active' : ''}><Link to={item.link}>{item.title}</Link></li>
              ))}
            </div>
          </nav>

          <div className="sign-regs-icon">
            <Link to="/"><PiSignInBold /></Link>
            <Link to="/"><ImUserPlus /></Link>
          </div>
        </div>
    </section>
  )
}

export default BottomHeader;

لقد استخدمت الخطاف useLocation بهذا الشكل 

هل يمكن توضيح ما الذي سيقوم به 

تبين لي انه سيظهر كلاس active 

بالضبط لتحديد الصفحة النشطة حاليًا وإضافة كلاس active إليها، حيث NavLinks.map() تقوم بالمرور على كل عنصر في مصفوفة NavLinks لإنشاء قائمة <li> لكل رابط.

و className={ } لكل عنصر <li> في القائمة، لتحديد قيمة الكلاس className بشكل ديناميكي.

والشرط location.pathname === item.link ? 'active' : '' هو الجزء الأهم هنا، فهو تعبير شرطي ثلاثي  يقوم بالآتي:

  • location.pathname === item.link تعني هل مسار URL الحالي الذي حصلت عليه من useLocation يطابق تمامًا رابط ذلك العنصر item.link الذي يتم عرضه حاليًا في الحلقة؟
  • ? 'active' ولو الإجابة نعم أي True فالمساران متطابقان، ويتم إعطاء العنصر <li> الكلاس active.

وهنا ' '  تعني كانت لو الإجابة لا False فالمساران غير متطابقين، ولن يتم إضافة أي كلاس بل سلسلة نصية فارغة.

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...