Merhabalar.

Bu yazımda dinamik url’ler için nasıl Router oluştururuz buna bakacağız.

Projemizde bir Product sayfamızda bulunan ürünler için productname’leri üzerinde bir query parameters oluşturacağız. Bu bilgiye göre detay sayfasına gidip ilgili ürünü göstereceğiz.

Güncel kodlarımız aşağıdaki gibi.

ProjectRouter.jsx

import {Routes, Route} from 'react-router-dom';

import HomePage from '../Pages/Home/HomePage';
import AboutPage from '../Pages/About/AboutPage';
import ContactPage from '../Pages/Contact/ContactPage';
import ProductPage from '../Pages/Product/ProductPage';
import ErrorPage from '../Pages/Error/ErrorPage';
import ProductDetail from '../Pages/Product/ProductDetail';


const ProjectRouter = () => {
  return (
    <Routes>
       <Route path="/" element={<HomePage />} />
       <Route path="/about" element={<AboutPage />} />
       <Route path="/contact" element={<ContactPage />} />
       <Route path="/product" element={<ProductPage />} />
       <Route path="/product/:id" element={<ProductDetail />} />
       <Route path="/productdetail" element={<ProductDetail />} />
       <Route path="*" element={<ErrorPage />} />
     </Routes>
  )
}

export default ProjectRouter

Url oluştururken Query Params’ları bu Route üzerinden vereceğiz. Burada yakalanan params’lar bizi ProductDetail sayfasında ilgili ürüne götürecek.

<Route path="/productdetail" element={<ProductDetail />} />

App.css

.App {
  text-align: center;
}

.App-logo {
  height: 40vmin;
  pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
  .App-logo {
    animation: App-logo-spin infinite 20s linear;
  }
}

.App-header {
  background-color: #282c34;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: calc(10px + 2vmin);
  color: white;
}

.App-link {
  color: #61dafb;
}

@keyframes App-logo-spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

.page {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  row-gap: 0px;
  height: 95vh;
  font-size: 100px;
  background-color: #282c34;
  color: #61dafb;
  
}

.btn{

  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: row;
  gap: 10px;  
}


button{

  background-color: #4c6369;
  color: #61dafb;
  border: none;
  border-radius: 5px;
  padding: 10px;
  font-size: 20px;
  cursor: pointer;
}


.product-page  {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  flex-wrap: wrap;
  padding: 20px;
  background-color: #596170;
  height: 100vh;

}

.card {
  
  margin: 10px;
  padding: 20px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
  border-radius: 10px;
  background-color: white;
  height: 150px;
  width: 200px;
  
}

.card h2 {
  margin: 0 0 10px 0;
}

.card a {
  display: inline-block;
  margin-top: 10px;
  padding: 10px 20px;
  background-color: #007bff;
  color: #fff;
  text-decoration: none;
  border-radius: 5px;
}

.card a:hover {
  background-color: #0056b3;
}

ProductPage.jsx

import React from 'react';
import { Link } from 'react-router-dom';

const ProductPage = () => {

  const products = [
    { id: 1, name: 'Product 1' },
    { id: 2, name: 'Product 2' },
    { id: 3, name: 'Product 3' },
    { id: 4, name: 'Product 3' },
  ];
  
  return (

    <>
      <div className='product-page'>
      {products.map((product) => (
        <div key={product.id} className='card'>
          <h2>{product.name}</h2>
          <Link to={`/product/${product.id}`}>Id Detail</Link>
          <Link to={`/productdetail?name=${product.name}`}>Name Detail</Link>
          
        </div>
      ))}
    </div>
    </>
    
  )
}

export default ProductPage

Query Paramslar Link’lerde aşağıdaki gibi oluşturulur.

<Link to={`/productdetail?name=${product.name}`}>Name Detail</Link>

?name=${product.name} birden fazla filter yazacaksak her bir sorgulama ifadesi & ile ayrılır.

Yukarıdaki kodları yazdığımızda aşağıdaki gibi bir görüntü elde edeceğiz.

ProductDetail.jsx

import React, {useState, useEffect} from 'react';
import { useParams, useLocation } from 'react-router-dom';

function useQuery() {
    return new URLSearchParams(useLocation().search);
  }

const ProductDetail = () => {
    const {id} = useParams()
    const [isParams, setIsParams] = useState(false)

    let query = useQuery();
    let name = query.get("name");

    useEffect(() => {
        setIsParams(!!name);
    }, [name]);

    const products = [
        { id: 1, name: 'Product 1' },
        { id: 2, name: 'Product 2' },
        { id: 3, name: 'Product 3' },
        { id: 4, name: 'Product 3' },
      ];

      const getProduct = () => {
        const product = products.find((product) => product.id === parseInt(id));
        return product ? product.name : 'Product not found';
    }

    const getProductName = () => {

        const product = products.find((product) => product.name === name)
        return product.name
    }

  return (
    <div className='page'>
        <h5>Product Detail</h5>
        <h4>{!isParams && id && getProduct()}</h4>
        <h4>{isParams && name && getProductName()}</h4>
    </div>
  )
}

export default ProductDetail

useLocation Hook’u Kullanımı

Url’de gönderdiğimiz paramsları useLocation hook’u sayesinde yakalayacağız.

useParams Hook’unu import ediyoruz.

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

useLocation hook’u, React Router kütüphanesindeki bir hook’tur ve mevcut tarayıcı konumu hakkında bilgi sağlar. Bu hook, tarayıcı URL’sini incelemenize ve üzerinde işlemler yapmanıza olanak tanır.

Özellikle, tarayıcı URL’sindeki sorgu parametreleri, pathname ve diğer bilgileri almanıza yardımcı olur. Bu sayede dinamik bir sayfa yapılandırması veya sayfa içeriğini URL’ye bağlı olarak değiştirme gibi senaryoları kolayca gerçekleştirebilirsiniz.

Sonra kullanıyoruz.

useQuery Fonksiyonu

function useQuery() {
    return new URLSearchParams(useLocation().search);
  }

Bu fonksiyon gönderilen paramsları yakar ve geri döner.

Sonra bu useQuery’den bir query objesi oluşturacağız. Sonrasında query üzerinde get ile filtername ile değerleri alabilir. Biz burada linkte name olarak gönderdiğimiz için product name’i, name olarak yakalıyoruz.

let query = useQuery();
let name = query.get("name");

Aşağıdaki fonksiyon sayesinde ilgili product bilgisini çekiyoruz.

const getProductName = () => {

        const product = products.find((product) => product.name === name)
        return product.name
    }

Gerisi bildiğimiz işlemler. Kod okumalarını bugüne kadar öğrendiklerimize göre yapabilirsiniz.

Uygulama Test

Detay sayfasına ürünle alakalı bilgilerimizi yazdırmayı başardık.

Bir sonraki yazımda görüşmek üzere.


Murat Bilginer
21 Şubat 1992'de doğdum. Endüstri Mühendisi olarak lisansımı 2016 yılında tamamladım. Industryolog Akademi - NGenius oluşumlarının kurucusuyum. Şu anda kendi şirketim Brainy Tech ile Web ve Mobil Geliştirme, AWS, Google Cloud Platform Sistemleri için DevOps, Big Data Analiz ve Görselleştirme hizmetleri sunmakta ve Online Eğitimler vermekteyiz.