4- ReactJS Sayfalar Arası Yönlendirme İşlemi (React Router Dom)

Bir önceki dersimizde React ile state yönetimi konusuna detaylı bir şekilde değinmiştik.

Serimizin dördüncüsü ile devam ediyoruz.

Eğitim Künyesi

  • Sayfalar arasında gezinme (React Router)

ReactJS Dünyasında Routing (Yönlendirme)

SSR (Server Side Rendering) yönetimi ile yapılan uygulamarda kullanıcının gördüğü ekranı fiziksel dosyalar ya da MVC projelerde return ettiğimiz actionlarla sağlıyoruz (Serimizin ilk yazısında bu konuya değinmiştik).

Bu yapılar içinde yapılan bağlantılar ile birlikte hedef olarak belirttiğimiz sayfalara yönlendirme gerçekleşiyor ve history yönetimi browser tarafından sağlanıyor.

React tarzı yapılarda (Flutter için de geçerli) sayfa olarak kullanıcıya sunduğumuz yapılar arka planda birer component. Biz hangi componenti sayfa olarak göstermek istiyorsak routing işlemini yapan mekanizmaya bununla ilgili direktifler veriyoruz.

Örneğin; adres çubuğunda kullanıcı tarafından bir abc.com/users-page şeklinde bir input geldiğine user-page‘in hangi componente karşılık geldiğini projemizde belirtmemiz gerekecek.

ReactJS dünyasında bu işlemi yapabilmek yapabilmek için biz react-router-dom kütüphanesini kullanıyor olacağız.

Bir önceki dersimizde kullanıcı seçim ve detay işlemlerini aynı sayfada gerçekleştirmiştik. Şimdi ise seçim ve detay ekranlarını ayrı birer sayfa olarak konumlandırıp birbirleri arasında yönlendirme işlemlerini yapacağız.

İlk olarak kütüphaneyi projemize ekleyelim.

npm i react-router-dom

Gelen herhangi bir url’in ilgili componentine yönlendirilme işlemini sağlamak için elimizde tüm sayfaların tanımının yapılması gerekir.

Bunun için App.js‘i aşağıdaki gibi değiştirelim.

import React from 'react';
import './app.scss';

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

import UserList from './pages/UserList';
import UserDetail from './pages/UserDetail';


function App() {

  return (
    <div className="App">
      <Router>
        <Switch>
          
          <Route path="/" exact>
            <UserList />
          </Route>

          <Route path="/user-detail/:name" exact>
            <UserDetail />
          </Route>

        </Switch>
      </Router>
    </div>
  );
}

export default App;

App.js’in bir önceki versiyonda list ve detail componentleri arasındaki yönlendirme ilişkisini state ile yönetiyorduk. Artık bu ilişkiyi react-router-dom ile yapıyoruz. Dolayısıyla artık state ile ilgili kodlarımızı çıkarmış olduk. (State ile ilgili örneklerimize sonraki derslerde devam edeceğiz)

Yeni kodlarımızın arasında react-router-dom kütüphanesinden import edilen üç adet component yer alıyor.

  • Router
  • Route
  • Switch

Üç komponentin ne işe yaradığını tek tek açıklayalım

Router: Tüm routing işlemleri bu component içerisinde gerçekleşir. Component hiyerarşisinin En üstünde olması beklenir. Route metodu import edilme şekline göre değişebilir. Yani, kütüphaneden BrowserRouter as Router, HashRouter as Router olarak import edilseydi browserın linkleri işleyiş şekli #(diyez) ile birlikte olacaktı. Kolay erişim için kendi history objemizi oluştursaydık oluşturduğumuz objenin tanımını bu component üzerinden yapıyor olacaktık.

Route: Erişilmek istenen componentin tanımı burada yapılır. Path propu ile hangi url üzerinden erişileceği belirtilir.

Switch: İçerisine bir dizi Route componenti alır. Adres çubuğunda yer alan url ile içerisinde bulunan Route’lardan birinin path’i eşleştiğinde, eşleşen Route içerisinde yer alan componenti ekrana switch eder ve o component render edilerek ekranda görünür.

Kullanılan componentlerin açıklamarını da yaptığımıza göre listeden seçilen anahtar değerin nasıl detay ekranda görüntüleneceğine bakalım.

App.js içerisinde Route tanımı yaparken user-detail route için şöyle bir path belirtmiştik.

/user-detail/:name

Bu pathi incelediğimizde sonunda :name olduğunu görüyoruz. react-router-dom kütüphanesi bize, bu şekilde path üzerinde bize dinamik alanlar kullanmamıza olanak sağlıyor.

Biz, liste ekranımızdan önceki gibi tüm objeyi detay componentine aktarmak yerine, anahtar bir alanı (örneğimizde name alanı ancak normalde id tarzı benzersiz bir değer göndermekte fayda var) göndererek datanın detayına ulaşmaya çalışacağız.

Bunun için de UserList componentinde aşağıdaki gibi değişiklik yapalım

import React from 'react';
import Header from '../../components/Header';
import { users } from '../../data';
import { useHistory } from 'react-router-dom'


const UserList = () => {

    let history = useHistory();

    return (
        <>
            <Header title="First Screen Application - Users" />
            <aside>
                <ul>
                    {
                        users.map(i =>
                            <li>
                                <button 
                                    onClick={() => history.push(`user-detail/${i.name}`)}
                                >
                                    {i.name} {i.surname}
                                </button>
                            </li>)
                    }
                </ul>
            </aside>
        </>
    );
}

export default UserList;

Burada daha önceden click eventini seçilen data ile birlikte bir üst componente gönderiyorduk. Bu sefer history.push fonksiyonunda detay componentinin pathi ile birlikte seçilen kaydın name alanını da göndermiş oluyoruz. Bu aşamada biraz history‘den bahsedelim.

History: Stack veri yapısıdır. Kutu örneği üzerinden açıklayacak olursak. Bir kutuya bazı üst üste birbirini örtecek şekilde objeler yerleştiririz. Kutuya üstten baktığımızda görebildiğimiz kutuya en son eklenen objedir. Browserda history objesini bu şekilde kullanır. Biz push ile en son hangi adresi eklediysek o adresi göstermeye çalışır.

UserList componentinden sonra bir ufak değişikliği de UserDetail componentinde yapmalıyız.

import React from 'react';
import Header from '../../components/Header';
import { users } from '../../data';
import { useParams } from 'react-router-dom';

const UserDetail = () => {

    const { name } = useParams();
    const user = users.filter(f => f.name === name)[0];

    return(
        <>
        <Header title="User Detail" />
        <div className="user-detail">
            <b>Name: </b> {user.name} {user.surname} <br/>
            <b>Title: </b> {user.title} <br/>
            <b>City: </b> {user.city} <br/>
        </div>
        </>
    );
}

export default UserDetail;

Bu componentte değişikliğe uğrayan kısım iki satır aslında

const { name } = useParams();    
const user = users.filter(f => f.name === name)[0];

Önceden user nesnesini props vasıtasıyla alıyorduk. Şimdi ise urlden name parametresi ile gelen değeri .filter metodu ile users array içinden filtre ediyoruz.

Burada, const { name } = useParams() ifadesi, UserList metodu içerisinde history.push(`user-detail/${i.name}`) ile gönderilen dinamik name değerini yakalamak için kullanılıyor.

Bu değeri aldıktan sonra ise daha önceden data.js içerisine aldığımız users arrayini buraya import edip içerisinden, gönderilen name parametresine göre ilgili satırı filtrelemiş oluyoruz.

Bu arada UserDetail componenti içerisinde de Header componentini farklı bir metin içeriği ile kullanmış olduk 🙂

Bu işlem ile birlikte dersimizi sonlandırıyoruz. Derste yazdığımız kodların son haline buradan erişebilir, dilerseniz aşağıdan çalıştırılabilir haline gözlemleyebilirsiniz.

Bir sonraki dersimizde React Router ile birlikte layout yönetimi konusuna değindik.

Sağlıkla kalın 🙂

One Comment

  1. Harika 🙂 gelişim ve yaşam kalite seviyenizi ilgi ile takip ediyoruz . Daha görünür sisteme arzınızı ivedilikle talep ediyoruz .

    25 August 2020
    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.