A’dan Z’ye React — Türkçe kaynak

State’den korkmam Virtual DOM’dan korktuğum kadar.

Yavuz AKINCI
KoçSistem
16 min readNov 22, 2018

--

Merhaba,

React’i öğrenirken kendi kendime “En iyisi notlar alayım ileride takılırsam dönüp notlarıma bakarım” diye düşüp notlar almaya başladım. Ancak bu not alma işini o kadar abartmışım ki günün sonunda dönüp baktığımda “N’aptım ben yahu üniversite sınavına mı hazırlanıyorum ?” diye sordum. Bu yazı 45 sayfalık bir not öbeğinden derlenerek oluşmuştur. React ve Redux’ta öğrendiğim her konuya değineceğim. Componentler, state’ler, lifecycle’lar, store’lar, middleware’ler… Kısacası ne ararsanız var. Başlamadan uyarayım çoook uzun bir yazı olacak. :)

Hikaye kısımları hep beni sıkmıştır; bu nedenle Facebook hikayesini kim bulmuş ne yapmış anlatmayacağım. Yalnız önemli birkaç nokta var;

  1. Öğrenmeden önce Javascript bilgisine sahip olmalısınız.
  2. React sadece view(görüntü) katmanıyla ilgilenir. Diğer mimari katmanlarla alakası yoktur.
  3. Component tabanıyla sanal DOM mimarisi kullanan bir UI kütüphanesidir.
  4. React clint-side (istemci taraflı) rendering yapar.

Burada bir şey belirtmek istiyorum. React proje geliştirirken siz de fark edeceksiniz, ayağa kaldırdığınız projenizin tarayıcıdaki kaynak koduna baktığınızda uygulamanızda bulunan yazıların html elemanlarının olmadığını sadece tertemiz bir html iskeleti, ortada bir div ve altta bir bundle.js nin olduğunu göreceksiniz.

Bunun sebebi React’in clint-side çalışmasından kaynaklıdır. Projeniz ilk yüklenme esnasında bembeyaz, boş bir sayfadır. Yüklenme sırasında bundle.js sayfaya dahil edildiği andan itibaren html üzerindeki gerekli parse (ayrıştırma) işlemleri başlar ve uygulamanız sizin tasarladığınız şekilde görünür. Bu işlem o kadar kısa bir sürede gerçekleşir ki biz farkedemeyiz. Kısacası arama motorları sayfanızda bir şey bulamadığı için projeniz indexlenmez.

Bu noktada “O zaman React’i neden öğreneyim ki?” demeyin. Dediğim gibi kütüphane olmasından dolayı server-side rendering yapan bir framework’e kurarak bu sorundan kurtulabiliyorsunuz. Sonraki makalelerde bu işlemin nasıl yapıldığından da bahsedeceğim.

Artık gelişmeye geçelim.

Component (Bileşen) Nedir?

Bir konuyu en iyi anlatmanın ve anlamanın yolu gerçek hayatla bütünleştirmektir.

Bir odanın içine koltuk, televizyon, sehpa ve halı gibi elemanları yerleştirdiğinizi düşünün. Bu elemanların her biri kendi başlarında bir görevi yerine getiren componentlerdir. Bu componentlerin bulunduğu oda muhtemelen oturma odası componentidir. Bu şekilde örnekleri çoğalttığımızda kendi içerisinde mini görevleri yerine getiren componentlerin oluşturduğu oda componentleri (mutfak, yatak odası vb.) olacaktır. Sonuç olarak bunların hepsi bir araya geldiğinde ev meydana gelecektir.
Birde buna teknik anlamda bakalım. Madem React’i Facebook yaratmış bunu sitesinden bir görsel üzerinden anlatayım.

Örneğin 2 numaralı alanı sağdaki gri alanda veya başka bir sayfada kullanmak istiyoruz. Bunu eski yöntemle yapmaya kalksak 2 numaralı alanın html kodlarını alıp, kullanacağımız yere aynı kodları kopyalamamız gerekir. Ancak bu durum, sonradan 2 numaralı alanda bir geliştirme yapmaya kalktığımızda kullandığımız her yerde o değişikliği tek tek üzerine kopyalarak değiştirmemiz gerekir. Componentler işte bizi bu iş yükünden kurtulmamızı sağlar. 2 numaralı alanı “FindFriendsComponent” adında bir componentin içinde bir kere geliştirme yaparak, ilgili yerlerde sadece

<FindFriendsComponent/>

şeklinde çağırarak kullanabiliriz.

import React, { Component } from 'react';
import News from '../component/News';
class Home extends Component {
render() {
return (
<div>
<News />
</div>
);
}
}
export default Home; Örnek 1: Component kullanımı

Yukarıdaki örnekte Home adında bir componentin içinde News adında başka bir component çağılıyor.

DOM & Virtual DOM

DOM (Document Object Model) web sayfalarının bize görünmelerini sağlayan html elemanlarının hiyerarşik biçimde bir arada bulunmasıdır. Virtual(sanal) DOM ise React tarafından render edilen DOM’un bir kopyasının tutulmuş halidir. Kısaca aralarındaki fark şudur; normalde sayfa içerisinde bir değişiklik talep ettiğinizde DOM bütün html’i tarar ilgili yerdeki değişikliği yapar. İyi güzel de; talebiniz aynı olsa bile bu baştan yükleme işlemi her seferinde tekrar gerçekleşir. Bu da gereksiz bir iş yüküdür.

Ancak, React devreye girdiğinde bir state (durum) değişikliğinde tüm sayfayı baştan yüklemek yerine DOM’daki değişikliği Virtual DOM a yansıtır ve render (derlemek) edilen DOM ile farklılıklarına bakar ve sadece farklılık olan alanı render eder. Bunun güzel tarafı yapılan değişiklik bir öncekiyle aynıysa render işlemi gerçekleşmez. Taa ki gönderdiğiniz değişiklik farklı olana dek.

Her projede React kullanmak mantıklı değildir. Sürekli ekranda veri değişiminin olduğu alanlarda kullanılması daha mantıklıdır.

JSX

JavaScript için bir syntax uzantısıdır. Kısaca aklınızda javascriptin içine html yazabilmenizi ve React elementleri üretmemizi sağlayan bir yazım şeklidir.

JSX olmayan yazım şekli;
const element = React.createElement(
'h1',{className: 'greeting'}, 'Hello, world!'
);
JSX ile yazım şekli;
const element = (<h1 className="greeting">Hello, world! </h1>);

Örnek 2: JSX kullanımı

React yazmak için JSX’i kullanmak zorunda değilsiniz. Fakat kod yazarken okunabilirlik önemli bir faktördür. JSX in yazım şekli HTML i andırdığı için hem okunabilirlik hem de hızlı kod yazma anlamında daha kullanışlıdır. JSX yazmadan https://reactjs.org/docs/dom-elements.html isimli sayfayı incelemenizde yarar var. Bazı html taglarının property kısımlarında farklı yazım şekilleri vardır. Ör: class yerine className veya labellarda yazılan for yerine htmlFor yazmak gibi.

JSX’in çalışabilmesi bir javascript compilera(derleyici) ihtiyacınız var. Bu işlem için en popüler kullanılanı Babeldir.

Props

İnsanı component olarak düşünürseniz, insanlara verdiğiniz kartvizitler veya insanların birbirlerine verdikleri kartvizitler olarak düşünebilirsiniz. Tanım olarak; sabit verileri bir componentden başka bir componente veri aktarılmasını sağlayan verilerdir.

Propslar sabit veriler oldukları için sadece sayfa ilk yüklenişinde render edilirler. Sonrasında React bunların props olduğunu bildiği için render etmeyecek ve bu alana hiç dokunmayacaktır.

import React, { Component } from 'react';
import News from '../component/News';
const news = [
{
id: 1,
title: "React Öğreniyoruz",
description: "bu örnek props için yapılmıştır."
},{
id: 2,
title: "Props",
description: "Componentler arası veri aktarır."
},
];
class Home extends Component {
render() {
return (
<div>
<News news={news} />
</div>
);
}
}
export default Home;
Örnek 3: Props kullanımı. Home componentinden News componentine array objesi gönderimi.

Key

Döngülerde oluşan listelerde benzersiz bir key(anahtar) verilmesi gerekir. Key in sözlük anlamı aslında anahtar olsa da React’te tam olarak o anlamda kullanılmamaktadır. React; oluşan liste içerisindeki her bir elemanı benzersiz(unique) bir key ile işaretleyerek, listenin değişmesi durumunda içerisindeki elemanların hepsini tekrardan render etmiyor, bildiği ve değişen kısımları render ediyor.

import { Component } from "react";
class News extends Component {
render() {
return (
<div>
{this.props.news.map(news =>
<div key={news.id}>
{news.title}
<br />
{news.description}
</div>
)}
</div>
)
}
}
export default News;
Örnek 4: örnek 3 de props gönderdiğimiz News componentinde key kullanımı.

propTypes

Gönderdiğiniz propsların tipini tanımlamanızı sağlayan yapılardır. Oluşturduğunuz componentlerin Stateful ve Stateless olarak farklı çeşitleri olabilir. Yazının ilerleyen kısımlarında Stateful ve Stateless farklarını anlatacağım ama şuan için PropTypes oluşturmanın iki yöntemi olduğunu bilmenizi isterim.

import { Component } from "react";
import propTypes from "prop-types";
class News extends Component {
static propTypes = {
news : propTypes.array
}

render() {
return (
<div>
{this.props.news.map(news =>
<div key={news.id}>
{news.title}
<br />
{news.description}
</div>
)}
</div>
)
}
}
export default News;
Örnek 5: Stateful componentte propTypes kullanımıimport React from "react";
import propTypes from "prop-types";
const News = (props) => {
return (
<div>
{props.news.map(news =>
<div key={news.id}>
{news.title}
<br />
{news.description}
</div>
)}
</div>
)
}
News.propTypes = {
news: propTypes.array
}
export default News;
Örnek 6: Stateless componentte propTypes kullanımı

propTypes : isRequired

Tipini belirlerken eğer belirttiğiniz tipte zorunluluk olacaksa; isRequired kullanıyoruz. Aşağıdaki örnekte news in proptypesı mutlaka array olmalı dedik.

News.propTypes = {
news: propTypes.array.isRequired
}
export default News;
Örnek 7: örnek 6 da bulunan propTypesda isRequired kullanımı.

propTypes : onOfType

Propsunuzun tipini çeşitlendirmek isterseniz onOfType kullanmanız gerekmektedir. Aşağıdaki örnekte news array objesinin propTypeslarını hem array hem de string olarak belirledik ve isRequired ile zorunlu kıldık.

News.propTypes = {
news: propTypes.oneOfType([
propTypes.array,
propTypes.string
]).isRequired
}
Örnek 8: örnek 6 da bulunan propTypesı oneOfType ile çeşitlendirilmesi.

propTypes : shape

Eğer size props ile bir obje gelecekse bu objenin yapısını belirleyebiliyorsunuz. Aşağıdaki örnekte news objesinin altında bulunan title ve description fieldlerinin(alan) tanımını yaptık.

News.propTypes = {
news: propTypes.shape({
title : propTypes.string,
description : propTypes.string
})
}
Örnek 9: örnek 6 da bulunan propTypesı shape ile alt alanlarını çeşitlendirilmesi.

Constructor

class NewsItem extends Component {
constructor(props){
super(props);

this.state = {
news : this.props
}
}
...
Örnek 10: constructor kullanım şekli

Class oluşturulup hazır hale geldiğinde ilk çalışan fonksiyondur. Bir classta constructor ismiyle yalnızca bir tane özel fonskiyon olabilir ve constructor componentde yüklendiğinde sadece bir kere çalışır ve parametre olarak props döner. Kısacası ana amacı ilk çalışma anında propslara erişim sağlamasıdır. Ancak, farklı amaçlar için de kullanabilirsiniz; ilk anda state’i başlatmak isterseniz içerisinde state de tanımlayabilirsiniz veya componentler üzerinden fonksiyonların bind işlemleri için de kullanabilirsiniz.

constructor(){
super();
this.addButton = this.addButton.bind(this)
}
addButton(){
this.props.addNews();
}

<button onClick={this.addButton}>Add</button>
Örnek 11: constructor içinde bind işlemi kullanım şekli

Kullanırken mutlaka içine super() yazmanız gerekir.” Super de ne ola ki? İlk çalışıyor diye kendini mi övüyor? ” demeyin. super(props) metodunu kullanarak üst-sınıfın bir nesnesini yaratabilir ve onun değişkenlerine değer atayabilirsiniz.

Gerçek hayattan kesitle sonuca bağlayayım;
Yine ev örneğinden yola çıkalım. Oturma odanızda diyelim ki halı yok. Hani evde sokacak yer bulamayınca yatak odanızdaki kocaman elbise dolabının üstünde hurçların arasına sokulan halılar var ya o geliyor aklınıza. constructor(props) getirecek kişi diyelim. “aslansın kaplansın taşı buraya” diye o halıyı çağırıyorsunuz. super(props) ile teslim alıyor ve kullanıma hazır hale getiriyorsunuz. Artık stateler sayesinde istediğiniz yere serebilirsiniz. (state konusunu birazdan anlatacağım.)

Hani hep zorunu anlatıp anlatıp kafanızı karıştırıp sonunda bak buda kolay yolu diye gösterip sinir ederler ya aynısını ben de yapacağım. React 16 ile bu şeklide constructor tanımlayıp hemen state ile kullanılır hale getirebiliyorsunuz.

class NewsItem extends Component {
state = {
news : this.props
}
...
Örnek 12: ES6 ile constructoru state e hızlıca bağlama yöntemi.

Function Bind

Constructor konusunda fonksiyon bind etmek için constructordan yararlanabileceğinizi yazmıştım. React yazarken 4 farklı fonksiyon bind etme yönteminden söz etmek istiyorum.

  1. Constructor içerisinde bind işlemi
constructor(){
super();
this.addButton = this.addButton.bind(this)
}
addButton(){
this.props.addNews();
}

<button onClick={this.addButton}>Add</button>
Örnek 13

2. onClick Event içerisinde bind işlemi

addButton(){
this.props.addNews();
}
<button onClick={this.addButton.bind(this)}>Add</button>
Örnek 14

3. Bind edeceğiniz fonksiyonu arrow function olarak yazmak.

addButton = () =>{
this.props.addNews();
}
<button onClick={this.addButton}>Add</button>
Örnek 15

4. JSX içerisine arrow function yazmak.

addButton(){
this.props.addNews();
}
<button onClick={() => this.addButton()}>Add</button>
Örnek 16

Facebook 1 numaralı yöntemi, yani bind işlemlerini constructor içerisnde yapılmasını öneriyor ama 3 numaralı yöntem benim daha daha kolayıma geliyor. Tercih sizin.

state

Sayfa üzerinde değişen, durumu hiçbir zaman belli olmayan ve her an değişebilme potansiyeli olan bir javascript objesidir. En tepede bir state oluştuysa onu proplar aracılığı ile taşırsınız. Bir state’de değişiklik olduğunda React o alanı tekrardan render edecektir.

constructor(props){
super(props);
this.state = {
name : "ali"
}
}
...
Örnek 17 :state örneği

setState

Normalde yukarıdaki örnekte bulunan name’i değiştirme için aşağıdaki gibi yazmamız yeterli.

...
this.state.name = "veli"
...
Örnek 18 : setState örneği

Ancak React, one way binding (tek yönlü bağlama) yapan bir kütüphanedir. Yani React’te Angular’da olduğu gibi sürekli dinleyen bir watcher (izleyici) sistemi yoktur. Bu nedenle yapılan değişikliği React’e bildirmemiz gerekiyor. Bu özellik aslında React’in güçlü yönlerinden biridir. Birden fazla state üzerinde değişikliği yapıp bunu istenilen bir anda ekrana yansıtılmasını isteyebilirsiniz. Kısacası React’te işlemleri topluca yaptırma imkânınız olur.

Stateful ve Stateless Component

Yukarıda propTypes konusunda sözü geçmişti şimdi biraz derinine inelim. Stateful component bir state’e sahip component demektir. (proptypes konusunda örnek 5). Bir componenti stateful olarak yazdığınızda React bu componentinizi diff (farkı) algoritmasına dahil eder.

React diff algroitması : React render işlemi sırasında sayfada oluşan ilgili stateful componentleri gezmesi ve bu componentlerin statelerinde değişiklik olup olmadığına bakmasıdır.

Bundan kaçınmak ve daha temiz kod yazmak için; eğer componentinizde hiç bir değişiklik olmayacaksa en mantıklısı stateLess componenttir.(Ör:Footer)

React Lifecycle (Yaşam döngüsü)

Bir React uygulamasının yaşamı 4 sütuna ayrılmıştır.
1. Componentin oluşturulması (Initialization).
2. Oluşturulan componentin DOM a bağlanması (Mounting).
3. DOM üzerinden güncellenmesi (Updation).
4. DOM’dan kaldırılması (Unmounting)

1. Componentin oluşturulması (Initialization)

Bu alan aslında Consturctorda classın ilk ayağa kalktığı anı ifade ediyor. Üst bir componentten parametre olarak verilen propsun constructor tarafından ya da initial statelerin değerlerini aldığı veya varsa fonksiyonların bind işlemlerinin yapıldığı zamanı temsil ediyor.

2. Oluşturulan componentin DOM’a bağlanması (Mounting)

Bütün mounting’i anlattıktan sonra hepsini içeren tek bir örnek göstereceğim. Şimdi hepsinin tanımını ve ne işe yaradığına bakalım.

2–1. componentWillMount()

Bu Virtual DOM’da işlemler yapılıp, gerekli diff algoritmaları çalışıp bu componentin Real DOM’a aktarılmasından yani render işleminden hemen önceki evettir. Burada genelde hızlıca çalışmasını istediğiniz işlemler için kullanırsınız. Sayfa daha render fonksiyonunu çalıştırmadığından setState işlemleri işe yaramayacaktır. Bu nedenle bu alanda state işlemleri yapamazsınız.

2–2. componentDidMount()

Component DOM’a mount edildikten, yani render işleminden sonra çalışan evettir. Bu alanda genelde componente gelen ve sonradan yüklenmesi gereken servis çağrıları yapılır. Component mount edildiğinde apar topar çağrılan metodumuz. DOM’a etki eden bir şeyin tanımlanması gereken yer burasıdır.

Eğer componentDidMountu çalıştırdığınız componentin child componentinde de componentDidMount çalıştırdıysanız önce child sonra ana componentiniz çalışır.

3. DOM’a bağlanması sonrası yaşam süreci (Updation)

3–1. componentWillReceiveProps()

Örneğin bir anne componentetten çocuk componente props geçtiniz;

...
state={
name : "ali"
}
changeName = () => {
this.setState({
name : "veli"
});
}
<Child name={this.state.name}/>
<button onClick={this.changeName}>Change Name</button>
...
Örnek 19 : Anne componentden çocuk componentine props geçiyoruz.

Ardından çocuk componentte componentWillReceiveProps() ile yeni props değerini yakalıyoruz.

...
componentWillReceiveProps(nextProps){
console.log("çocuk componentWillReceiveProps :",nextProps)
}
...
Output
------------------
Anne component render çalıştı
çocuk componentWillReceiveProps : {name: "veli"}
çocuk component render çalıştı
Örnek 20: props un yeni değerinin çıktısını gösteriyor.

3–2.shouldComponentUpdate()

Componentin render edilip edilmeyeceğini kontrol ettiğimiz metottur.

...
shouldComponentUpdate(nextProps, nextState){
return true;
return false;
}
...
Örnek 21: shouldComponentUpdate yazım şekli.

nextProps ve nextState adında iki tane değişken alır. İçerisinde True veya False olarak Boolean değer return etmelisiniz. Bu return ettiğiniz değere göre component render edilir ya da edilmez.

3–3.componentWillUpdate()

ShouldComponentUpdatein True dönmesinden sonra çalışan fonksiyondur. nextProps, nextState adında iki adet parametre alır.

3–4.ComponentDidUpdate(prevProps, prevState)

Render işleminden sonra shouldComponentUpdatein True dönmesine bağlı bir fonksiyondur. prevProps, prevState adında iki adet parametre alır. State’in ve propsun bir önceki değerini yazdırır.

Tüm React Lifecycle’ı bir örnekte toparlayacak olursak;
Buton koymamın sebebi SetState işlemi yaparak shouldComponentUpdate gibi metotları gösterebilmek için. Butona basmadan önce bu şekilde.

Butona bastıktan sonrada önce bu şekilde.

4. DOM’da Ortadan Kaldırma Süreci (UnMount)

4–1.ComponentWillUnmount()

Daha önce hiç kullanma fırsatımın olmadığı ama “vay be iyimiş” dediğim fonksiyondur. Bu metodu kısaca aklınızda sıfırlama metodu olarak tutabilirsiniz. Componentinizin içerisindeki ilişkili yerleri DOM’dan kaldırdığınızda devreye girer. Örneğin componentinizin içerisinde bir network requesti yaptınız ve onu iptal ediyorsunuz ya da bir listenerınız var onu kaldıracaksınız bu fonksiyon çalışıyor.

Fetch()

Javascript’in native bir fonksiyonudur. Herhangi bir servise bağlanıp o servisten veri çekmeye yarar. Fetch ile bir servise bağlandığımızda servisten bize bir promise döner. then() changeler ile ilgili datada istediğimiz alana ulaşırız. Catch ile hataları yakalarız. Redux’ı anlatırken detaylı olarak inceleyeceğiz.

...
fetch("https://jsonplaceholder.typicode.com/users")
.then(data => data.json())
.then(users => {
this.setState({
users : users
})
})
.catch(error => {
console.log(error)
})
...
Örnek 22: Fetch kullanımı.

Axios()

Bir sürü fetching kütüphanesinden aralarında en iyi olanıdır. Datalar üzerinde get,post,delete veya asenkron işlemler yapmamızı sağlar. Daha detaylı incelemek isterseniz bu git reposuna göz atabilirsiniz. https://github.com/axios/axios

import axios from "axios";
...
axios.get("https://jsonplaceholder.typicode.com/users")
.then(data => data.users)
.then(users => {
this.setState({
users : users
})
})
.catch(error => {
console.log(error)
})
...
Örnek 23: Axios kullanımı.

Routing

BrowserRouter, As, Route, path, exact

React’de react-router-dom adında bir modül var. Adından da anlaşılacağı gibi yönlendirmeler yapmanızı sağlıyor (Ana sayfa,Hakkımızda,İletişim..vb). Başlangıç olarak npm install — save react-router-dom diyerek projemize dahil ediyoruz. BrowserRouter olarak bir nesneniz var. Bu nesneyi uygulamanızın en dışına koymanız lazım ki rooting işlemlerini yapalım. Bu noktadan itibaren daha iyi anlamanız için adım adım kod parçacıkları paylaşacağım;

import React, { Component } from 'react';
import { BrowserRouter as Router, Route } from "react-router-dom";
class App extends Component {
render() {
return (
<div>
<Router>
<div>
<Route path="/" exact render={
() => {
return (<h1>Home page</h1>)
}
} />
<Route path="/contact" exact render={
() => {
return (<h1>Contact Page</h1>)
}
} />
</div>
</Router>
</div>
);
}
}
export default App; Örnek 24: BrowserRouter iskeleti kurulumu.

Yukarıdaki 24. örneği biraz açıklayalım. App.js şaun benim projemin en üst componenti bu nedenle routing işlemlerini burada başlatıyorum. Dikkat etmeniz gereken bir durum var; Tagları <Router> olarak açmamın sebebi <BrowserRouter> kelime olarak çok uzun bu nedenle “As” diyerek kısalttık. <Route> react-router-dom un altında bulunan ayrı bir nesnedir. Bir konumun link ile eşleşerek componentlerinizi çağırmak istiyorsanız Route kullanmalısınız. Yukarıdaki örnekte iki adet path ataması yapıldı. Birincisi “/” şeklinde ana sayfaya, ikinci “/contact” a yönlendiriyoruz. Route render adında bir property alıyor. Bunun içerisinde bir call-back fonksiyonu tanımlayarak bir render işlemi yapıyoruz. Dikkat ettiyseniz exact adında bir property kullandık. Çünkü;

URL’de contact sayfasını çağırdığımızda bir Regular expression çalışıyor. Bu ne demek? localhost:3000/’e kadar olan kısım ana sayfam bu nedenle “Home page” i çağır, /contact/ olan kısım benim iletişim sayfam ve sayfayı çağır şeklinde olduğundan bunları ayrıştırmamız gerekiyor. Bu nedenle exact kullanıyoruz.

strict

Url kısmına “contact” ya da “contact/” yazsanız da sayfa render edilecektir. Bunun sebebi bir strict ile path alanınızı bir yapıya zorlamamanızdan kaynaklı. 24. örnekte contact routeuma strict tanımlarsam bundan sonra browser sadece “/contact” yazdığımda render edilecektir.

<Route path="/contact" scrict exact render={
() => {
return (<h1>Contact Page</h1>)
}
} />
Örnek 25: Route tanımlama örneği.

Router da stateless component

Her zaman Route’unuzun içinde sayfayı render etmek kolay olmayabilir. Route’unuzu aşağıdaki gibi de tanımlayabilirsiniz.

import React, { Component } from 'react';
import { BrowserRouter as Router, Route } from "react-router-dom";
const Contact = () => {
return (<h1>Contact Page</h1>)
}
class App extends Component {
render() {
return (
<div>
<Router>
<div>
<Route path="/" exact render={
() => {
return (<h1>Home page</h1>)
}
} />
<Route path="/contact" exact component={Contact} />
</div>
</Router>
</div>
);
}
}
export default App; Örnek 26: Route içinde stateless component çağırmak.

Router’a parametre göndermek

const Contact = ({ match }) => {
return (<h1>Contact Page: { match.params.id }</h1>)
}
...
<Route path="/contact/:id" exact component={Contact} />
...
Örnek 27: Route içinde stateless component çağırmak.

Gönderdiğimiz stateless componentin içine bir parametre gönderip console.log a yazdırdığımızda, bizim Route alanında gönderdiğimiz “:id” nin match altında ki param’ın altında olduğunu bulduk. Ardından tek yapmamız gereken stateless componentimizin içerisinde bu “id” yi çağırmak oldu. Sonuç olarak “contact/*”ın altında hangi id’yi çağırsanız, sayfanızda artık o id ile sayfayı yazdırıyor olacaksınız.

Link

Bir router nesnesidir. HTML deki <a href=””> mantığında çalışır. Sayfa içerisinde oluşturduğumuz Routelara link ile yönlendirme yapmak için kullanılır. “to:” parametresinde hangi Route’un path ini yazarsanız o sayfayı render edecektir.

import { BrowserRouter as Router, Route, Link } from "react-router-dom";
<Router>
<div>
<Link to="/">Homepage</Link>
<Link to="/contact">Contact</Link>
...
Örnek 28: Link örneği.

NavLink

Link ile aynı görev bilincindedir. Sadece render edilmiş sayfadaki linklere css eklemek isterseniz kullanacağınız bir özelliktir. Sayfa render edildikten sonra linkinize class atamak isterseniz “activeClass”, style atamak isterseniz “activeStyle” yazmanız yeterli olacaktır.

import { BrowserRouter as Router, Route, Link, NavLink } from "react-router-dom";
<Router>
<div>
<NavLink activeClassName="" activeStyle={{}} to="/">Homepage</Link>
<NavLink to="/contact">Contact</NavLink>
...
Örnek 29: NavLink örneği.

Redirect

Önceden de denk gelmişsinizdir. Bir web sitesinde ya da uygulamada gezinirken üye girişi yapmışken çıkışa bastığınızda sizi ana sayfaya yönlendirirler. İşte tam olarak redirect’in yaptığı budur. Sizi bir koşul anında başka bir yere yönlendirmesidir.

import { BrowserRouter as Router, Route, Link, NavLink, Redirect } from "react-router-dom";...
<Route path="/profile" exact strict render={
() => (
this.state.loggedIn ? (<Profile/>) : (<Redirect to="/"/>)
)} />
...
Örnek 30: Redirect örneği.

Yukarıdaki örnekte şunu demiş olduk; Route’unun path i profil. Yanlız bu sayfaya giderken login olup olmadığını kontrol et. Eğer login olmuşsa Profil sayfasını yükle eğer logout olduysa kullanıcıyı ana sayfaya gönder.

Switch

Bunun normal yazılım dillerindeki switch-case ile hiçbir farkı yoktur, aynı çalışma mantığında çalışır.

import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Link, NavLink, Redirect, Switch } from "react-router-dom";
class App extends Component {
render() {
return (
<div>
<Router>
<div>
<NavLink to="...">...</NavLink>
<NavLink to="...">...</NavLink>
<Switch>
<Route path="..." exact component={...} />
<Route path="/profile" exact strict render={
() => (
this.state.loggedIn ? (<Profile />) : (<Redirect to="/" />)
)} />
<Route component={Error}></Route>
</Switch>
</div>
</Router>
</div>
);
}
}
export default App; Örnek 31: Switch örneği.

Yukarıdaki örnekte Routelarımızı Switch özelliğinin içerisine alıyoruz ve en alta default bir Route atıyoruz. Url kısmına Routelarımızda bulunmayan bir şey yazarsak otomatik olarak kullanıcıyı Error sayfasına yönlendiriyoruz.

Kapanış

Evet arkadaşlar, React ile ilgili yazımın sonuna geldik. Başta Redux’tan da bahsedeceğimi yazmıştım ama gerçekten uzun oldu Redux’ı ayrı makalede yazacağım. Yoksa bu yazı el kitabından çok romana dönecek. Bu makaleyi yazma amacım React öğrenen herkese “bu neydi ne için kullanıyorduk” diye takıldıkları noktada dönüp bakmak için bir el kitabı oluşturmaktı. Umarım sizin için bu yazı bir el kitabı olur ve faydasını görürsünüz. Bu makaleyi yazarken de bi kaç not çıkarttım. Özetin özeti gibi düşünün :)
Yarın bir gün belli olmaz bir iş görüşmesine girersiniz ve işten anlamayan biri sırf soru sormak için ya da işten anladığını düşünmenizi istediği için size şaçma sapan tanım sorarsa bunlardan yararlanırsınız. İnsanların ne soracağı belli olmuyor bir görüşmede bana HTTP ne demek diye sormuşlardı… Redux makalesinde görüşürüz.

Kavramlar

Component :
En ufak işi yerine getiren görünümdeki elemanların bir araya gelmesiyle oluşan bir yapıdır.

Virtual DOM :
React’in oluşturduğu sanal DOM dur. Sayfa içinde sadece değişiklik olan kısmının render olmasına yardımcı olur.

JSX :
Javascriptin içine HTML yazmak için bir syntax’dır.

props :
Componentler arası veri aktarılmasını sağlayan sabit değişmeyen verilerdir. Sadece bir kere render edilirler.

key :
Döngülerde benzersiz bir anahtar belirmek için kullanılır. Döngülerde zorunludur.

propTypes :
Gönderdiğiniz propsların tipini tanımlamanızı sağlayan yapılardır.

isRequired :
Propslarınızın tipini belirlerken istediğiniz tipte gelmesini zorunlu kılmak içindir.

onOfType :
Propsların tiplerini çeşitlendirmek için kullanılır. Ör: Bir propsa hem array olsun hem de string olsun diyebilmek için kullanılır.

shape :
Gelen propsun tipi objeyse altında bulunan alanların tanımını yapmaya yarar.

constructor :
Class oluşturulduğunda çalışan ilk fonksiyondur. Super(props) ile kullanılır. Constructor propsu alır super e paslar sizde state sayesinde kullanırsınız.

state :
Sayfa üzerinde değişen, durumu her an belli olmayan ve her an değişebilme potansiyeli olan verilerdir. En tepede bir state oluştuysa onu proplar aracılığı ile taşırsınız.

setState :
state de bir değişiklik olduğunu React’e bildirme fonksiyonudur.

stateful :
Bir state’e sahip olan componenttir.

stateless :
Bir state’e sahip olmayan sabit componentlerdir (Ör: footer).

React Lifecycle :
Reactin işleyiş biçimidir. 4 bölümden oluşur: Initialization, mounting, updation ve unmounting.

componentWillMount() :
Render işleminden hemen önce çalışan fonksiyondur; burada state işlemi yapılamaz.

componentDidMount() :
Render işleminden sonra çalışan fonksiyondur.(genelde servis çağrılarının yapıldığı alandır).

shouldComponentUpdate(nextProps, nextState) :
True ve False şeklinde booleen değer return edilmelidir. Render işleminin koşula bağlamak içindir.

ComponentWillUpdate(nextProps, nextState) :
Render işleminden hemen önce ancak shouldComponentUpdatein True dönmesine göre çalışan metottur.

ComponentDidUpdate(prevProps, prevState) :
Render işleminden sonra ancak shouldComponentUpdatein True dönmesine göre çalışan metottur.

Fetch() :
Herhangi bir servise bağlanıp data çekmemize yarar.

Axios() :
Bir fetching kütüphanesidir. Get,post,delete ve asenkron işlemler yapmamızı sağlar.(bir sürü yardımcı fetch kütüphanesi var ama aralarında en iyisi olduğu söyleniyor).

BrowserRouter :
UI’ınızı URL ile senkronize etmeniz içindir. Projenizin en dış componentinde kapsayıcı olarak bulunmalıdır.

Route :
Bir konumun link ile eşleştiğinde bazı componentleri arayüzde oluşturmaktadır.

Exact :
Route’a property olarak geçilerek uygulanır. Amacı sayfaları ayrıştırmaktır. Bunu yazmazsanız sayfalar üst üste görünür.

Strict :
Belli bir yapıya zorlamak demektir. Path=”..” kısmında ne çağırdıysan Url’den aynı o şekilde çağrılması gerekir.

Link :
Bir Router nesnesidir. “to” parametresine verdiğimiz Url’de istediğimiz Route’a yönlendirme yapmamızı sağlar.

NavLink :
Link yerine kullanabileceğimiz alternatif bir özelliktir. (tıkladığımızın rengini css ini değiştirmek için kullanıyoruz)

Redirect :
Bir koşul anında başka bir yere yönlendirmek. (Ör: Logout olduğunda ana sayfaya yönlendirmesi)

PART : 2 Redux yazısının linki

--

--