├── images
├── jsx.png
├── axios.png
├── hooks.png
├── props.png
├── react.png
├── redux.png
├── state.png
├── uikit.png
├── bilesen.png
├── giris.jpeg
├── guvercin.png
├── nextjs.png
├── props2.png
├── webpack.jpg
├── sayfakaynagi.png
├── yasamdongusu.png
└── kofi.svg
├── React.js Türkçe Kaynak.pdf
├── .github
└── FUNDING.yml
├── kaynaklar.txt
└── README.md
/images/jsx.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orcuntuna/react-turkce-kaynak/HEAD/images/jsx.png
--------------------------------------------------------------------------------
/images/axios.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orcuntuna/react-turkce-kaynak/HEAD/images/axios.png
--------------------------------------------------------------------------------
/images/hooks.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orcuntuna/react-turkce-kaynak/HEAD/images/hooks.png
--------------------------------------------------------------------------------
/images/props.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orcuntuna/react-turkce-kaynak/HEAD/images/props.png
--------------------------------------------------------------------------------
/images/react.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orcuntuna/react-turkce-kaynak/HEAD/images/react.png
--------------------------------------------------------------------------------
/images/redux.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orcuntuna/react-turkce-kaynak/HEAD/images/redux.png
--------------------------------------------------------------------------------
/images/state.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orcuntuna/react-turkce-kaynak/HEAD/images/state.png
--------------------------------------------------------------------------------
/images/uikit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orcuntuna/react-turkce-kaynak/HEAD/images/uikit.png
--------------------------------------------------------------------------------
/images/bilesen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orcuntuna/react-turkce-kaynak/HEAD/images/bilesen.png
--------------------------------------------------------------------------------
/images/giris.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orcuntuna/react-turkce-kaynak/HEAD/images/giris.jpeg
--------------------------------------------------------------------------------
/images/guvercin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orcuntuna/react-turkce-kaynak/HEAD/images/guvercin.png
--------------------------------------------------------------------------------
/images/nextjs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orcuntuna/react-turkce-kaynak/HEAD/images/nextjs.png
--------------------------------------------------------------------------------
/images/props2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orcuntuna/react-turkce-kaynak/HEAD/images/props2.png
--------------------------------------------------------------------------------
/images/webpack.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orcuntuna/react-turkce-kaynak/HEAD/images/webpack.jpg
--------------------------------------------------------------------------------
/images/sayfakaynagi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orcuntuna/react-turkce-kaynak/HEAD/images/sayfakaynagi.png
--------------------------------------------------------------------------------
/images/yasamdongusu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orcuntuna/react-turkce-kaynak/HEAD/images/yasamdongusu.png
--------------------------------------------------------------------------------
/React.js Türkçe Kaynak.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orcuntuna/react-turkce-kaynak/HEAD/React.js Türkçe Kaynak.pdf
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: tunaorcun
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
13 |
--------------------------------------------------------------------------------
/kaynaklar.txt:
--------------------------------------------------------------------------------
1 | https://reactjs.org/docs/
2 | https://goalkicker.com/ReactJSBook/
3 | https://www.infoworld.com/article/3195951/review-the-10-best-javascript-editors.html
4 | http://kangax.github.io/compat-table/es6/
5 | https://ceaksan.com/tr/webpack-nedir/
6 | https://medium.com/t%C3%BCrkiye/javascriptin-en-g%C4%B1c%C4%B1k-konular%C4%B1-webpack-babel-eslint-ve-di%C4%9Ferleri-fb2e1232a085
7 | https://www.w3schools.com/jsref/dom_obj_style.asp
8 | https://medium.com/path2code/map-in-jsx-2d7285b39f8
9 | https://medium.com/@Zwenza/functional-vs-class-components-in-react-231e3fbd7108
10 | https://developer.mozilla.org/tr/docs/Web/JavaScript/Reference/Classes
11 | https://www.npmjs.com/package/prop-types
12 | https://flaviocopes.com/react-events/
13 | https://medium.com/@mmuratcoskun/javascript-call-apply-ve-bind-fonksiyonlar%C4%B1-3b0242fbc7dd
14 | https://programmingwithmosh.com/javascript/react-lifecycle-methods/
15 | http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/
16 | https://github.com/axios/axios
17 | https://jsonplaceholder.typicode.com/
18 | https://www.quora.com/What-is-the-right-way-to-use-AJAX
19 | https://reacttraining.com/react-router/web/guides/quick-start
20 | https://sozluk.gov.tr/
--------------------------------------------------------------------------------
/images/kofi.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React.js Türkçe Kaynak
2 |
3 | 
4 |
5 | ## İçindekiler
6 |
7 | 1. [Giriş ve Tanışma](#giriş-ve-tanışma)
8 | 2. [Nelere İhtiyacımız Olacak?](#nelere-i̇htiyacımız-olacak)
9 | 3. [React Nedir?](#react-nedir)
10 | 4. [Webpack ve Babel Kavramları](#webpack-ve-babel-kavramları)
11 | 1. [Webpack](#webpack)
12 | 2. [Babel](#babel)
13 | 5. [Kurulum ve create-react-app](#kurulum-ve-create-react-app)
14 | 6. [JSX ve HTML](#jsx-ve-html)
15 | 7. [Bileşenler (components)](#bileşenler-components)
16 | 1. [Bileşeni Dışarı Aktarmak](#bileşeni-dışarı-aktarmak)
17 | 8. [Props (Bileşen Parametreleri)](#props-bileşen-parametreleri)
18 | 1. [Prop Types ile Kısıtlama ve Zorlama](#prop-types-ile-kısıtlama-ve-zorlama)
19 | 2. [Varsayılan Prop Değerlerini Belirlemek](#varsayılan-prop-değerlerini-belirlemek)
20 | 9. [State](#state)
21 | 1. [jQuery tarafında state mantığı](#jquery-tarafında-state-mantığı)
22 | 10. [Yaşam Döngüsü](#yaşam-döngüsü)
23 | 11. [Olay Yönetimi (Events)](#olay-yönetimi-events)
24 | 1. [Eventler için Bind](#eventler-için-bind)
25 | 2. [Event'ler ile Parametre Göndermek](#eventler-ile-parametre-göndermek)
26 | 12. [Bileşenler Arasında İletişim](#bileşenler-arasında-i̇letişim)
27 | 1. [Üst'ten Alt Bileşene Erişim (Parent to Child)](#1-üstten-alt-bileşene-erişim-parent-to-child)
28 | 2. [Alt'dan Üst Bileşene Erişim (Child to Parent)](#2-altdan-üst-bileşene-erişim-child-to-parent)
29 | 3. [Alt-Üst İlişkisi Olmayan Bileşenlere Erişim](#3-alt-üst-i̇lişkisi-olmayan-bileşenlere-erişim)
30 | 13. [React Router](#react-router)
31 | 14. [UI Kütüphanesi Dahil Etmek (bootstrap vs.)](#ui-kütüphanesi-dahil-etmek-bootstrap-vs)
32 | 15. [React Fragment](#react-fragment)
33 | 16. [Hook'lara Giriş](#hooklara-giriş)
34 | 1. [Hook'lar ile State Kullanımı](#hooklar-ile-state-kullanımı)
35 | 2. [Hook'lar ile Effect Kullanımı](#hooklar-ile-effect-kullanımı)
36 | 17. [API Kullanımı (axios)](#api-kullanımı-axios)
37 | 18. [Döngülerde Key Kullanımı](#döngülerde-key-kullanımı)
38 | 19. [Server Side Rendering](#server-side-rendering)
39 | 20. [Build Almak (create-react-app)](#build-almak-create-react-app)
40 | 21. [Çoklu import/export Kullanımı (webpack)](#çoklu-importexport-kullanımı-webpack)
41 | 22. [Kapanış](#kapanış)
42 |
43 | ## Giriş ve Tanışma
44 |
45 | React.js ile ilgili içeriklere başlamadan önce kısaca kendimden bu kaynağın yapılış amacından bahsedeyim. İsmim **Orçun Tuna**, yazılım mühendisi adayıyım. Bu kaynak ile sizlerin günümüzün en popüler ön yüz kütüphanesi olan React'ı öğrenmesini amaçlıyorum. Bu projenin çıkış noktası ise ücretsiz yazılım kaynakları sunan goalkicker oldu. Aynı şekilde Türkçe olarak da detaylı bir kaynak olması açısından bu dökümanı baz alarak bu kaynağı hazırlamaya başladım. Bahsettiğim kaynak üzerindeki bilgileri çeviri ile sizlere sunmayacağım. Kendim düzenlemeler, eklemeler ve çıkarmalar yapacağım. Ama genel olarak rotamızı oradan kopya çekerek ilerleteceğiz. Bu kaynak GitHub üzerinde paylaşılacağı için eksik veya yanlış gördüğünüz yerleri "pull request" göndererek kaynağı iyileştirmeme yardımcı olabilirsiniz.
46 |
47 | ## Nelere İhtiyacımız Olacak?
48 |
49 | React bir JavaScript kütüphanesi ve JavaScript platform bağımsız çalışan bir dil olduğundan işletim sistemi olarak herhangi bir kısıtlamamız yok. Aynı şekilde editör tarafında da birçok editör veya IDE arasından seçim yapabilirsiniz. Geliştirme yaparken kullanabileceğiniz birkaç editörü yazalım bunlar arasından tercihinizi siz yapın.
50 |
51 | - Visual Studio Code
52 |
53 | - WebStorm (ide)
54 |
55 | - Atom
56 |
57 | - Sublime Text
58 |
59 | - Brackets
60 |
61 | Benim tavsiyemi soracak olursanız eğer öğrenci iseniz JetBrains ürünlerinden ücretsiz faydalanarak WebStorm kullanmanızı öneririm. Değilseniz üzülmeyin, VS Code'da çok kaliteli ve işinizi fazlasıyla görecek bir editör.
62 |
63 | Kurulum tarafında ihtiyacımız olacak yazılım ise NPM ve Node.js olacak. Bunları da kolaylıkla indirip platform bağımsız şekilde kurabilirsiniz.
64 |
65 | Geldik programlama dillerine, aşağıdakileri bilmeden maalesef React öğrenmeye başlayamazsınız. Eğer listedeki dil veya kavramlardan eksiğiniz var ise öncelikle bunları tamamlayıp sonrasında buraya dönmenizi tavsiye ederim. Aksi halde çoğu şeyi anlayamayabilirsiniz.
66 |
67 | - HTML
68 |
69 | - CSS
70 |
71 | - JavaScript + Biraz da olsa ECMAScript
72 |
73 | ## React Nedir?
74 |
75 | React, Facebook tarafından geliştirilen ve açık kaynaklı bir front-end kütüphanesidir. Ayrıca daha önce duymuş olabileceğiniz "component based" yani bileşen tabanlıdır.
76 |
77 | Ayrıca React DOM'u kullanarak sanal bir DOM (Document Object Model) oluşturur. Bu sayede sayfa üzerinde bir değişiklik olduğunda tüm sayfayı güncellemek yerine sadece değişiklik yapılan kısmı güncellenecek. Böylelikle performans tarafında fark gerçek DOM'a göre daha hızlı çalışır.
78 |
79 | React içerisinde JSX adı verilen özel bir biçimlendirme dili kullanılır. React bu JSX kodlarını HTML kodlarına dönüştürür ve tarayıcı tarafından çalıştırılmasını sağlar. JSX denildiğinde gözünüz korkmasın. Neredeyse birebir olarak HTML şeklinde fakat kendine özgü birkaç özelliği daha olan bir biçimlendirme dili.
80 |
81 | İlk paragrafta basettiğim bileşen tabanlılık özelliği ile geliştirme tarafında büyük kolaylıklar sağlar. Bunu şu şekilde basit bir örnek ile açıklayabiliriz. Bir yemek tarifi sitesinin anasayfasını düşünelim. Header, footer, sidebar ve yemek tariflerinin bulunduğu kartlar var. Buradaki her bir alanı bir bileşen olarak böleriz ve bunları tekrar tekrar kullanabiliriz. Header bileşeni, yemek tarifi kartı bileşeni ve bu şekilde bileşenleri oluştururuz.
82 |
83 | Bu kısımda son olarak React'ın neden bir framework değilde kütüphane olduğunu konuşalım. Framework ve kütüphane ayrımı front-end tarafında içinde router bulunup bulunmadığına bakılarak karar veriliyor. React.js içinde varsayılan olarak bir router bulunmadığı için React'a kütüphane diyebiliriz. Router kısmını ise ileride react-router veya next.js gibi ekstra çözümler ile halletmeye çalışacağız.
84 |
85 | ## Webpack ve Babel Kavramları
86 |
87 | Geliştirmeye başlamadan önce webpack ve babel kavramları hakkında bilgi sahibi olunması gerektiğini düşünüyorum. Şayet bunları sıklıkla kullanacağız ve ne olduklarını bilmeden kullanmamız saçma olacaktır.
88 |
89 | ### Webpack
90 |
91 | 
92 |
93 | Bildiğiniz gibi JavaScript üzerinde farklı kodları içeri aktarıp bir dosya üzerinden kodlamaya devam edebileceğimiz bir sistem mevcut değil (Python'daki import, PHP'deki include gibi). Burada webpack devreye giriyor. Webpack oluşturduğumuz dosyalar arasında içeri aktarma yapmamızı sağlıyor. Sonrasında ise bir bundle dosyasında tüm içerikleri bir araya getiriyor. Böylelikle JavaScript üzerinde import işlemi yapabilmiş oluyoruz.
94 |
95 | ### Babel
96 |
97 | Gereksinimler kısmında JavaScript yanında biraz da ecmascript demiştik. Babel'in görevi ecmascript üzerine ve bu yüzden ecmascript'e biraz hakim olmak gerekiyor.
98 |
99 | Şuanda kullandığımız tarayıcılar tam olarak bütün ecmascript sürümlerini maalesef destekleyemiyorlar. Bu yüzden tarayıcının bizim kodlarımızı anlayabilmesi için ecmascript kodlarını daha düşük ecmascript versiyonlarına çevirmemiz gerekiyor.
100 |
101 | Babel tam olarak bu işi yapıyoruz. Böylelikle daha modern ve anlaşılır kod yazabiliyoruz.
102 |
103 | ## Kurulum ve create-react-app
104 |
105 | Yeni bir React projesi oluşturmak için create-react-app paketini kullanacağız. Paket kullanılmadan manuel olarak da React projeleri oluşturulabilir. Fakat hem çok fazla kullanılmadığı hem de başlangıçta kafa karışıklığına sebep olmamak için bu kısımdan bahsetmeyeceğim. Direkt olarak kurulumumuzu create-react-app paketini kullanarak yapacağız.
106 |
107 | create-react-app paketi Facebook tarafından sunulan react proje oluşturma aracı. Bu aracı kullanarak manuel olarak yapmamız gereken her şeyden kurtulacağız. Paket bize hazır olarak şunları sağlıyor:
108 |
109 | 1. ES6 ve JSX çevrimi
110 |
111 | 2. Geliştirme sunucusunda değişiklik yapıldığında otomatik yenileme
112 |
113 | 3. Kodlama standartları ile çalışma (eslint)
114 |
115 | 4. Otomatik CSS tamamlama
116 |
117 | 5. JS, CSS ve Görsel dosyaları paketleme
118 |
119 | 6. Jest Unit Test ortamı
120 |
121 | Kuruluma başlamak için gereksinimlerdeki npm uygulamasını yüklemiş olmanız gerekiyor. Bundan sonraki kısımlarda işlemlerimizi terminal üzerinden yürüteceğiz. Eğer Linux tabanlı bir işletim sistemi kullanıyorsanız sisteminizin kendi terminalini kullanabilirsiniz. Windows kullanıyorsanız "Git bash" kullanmanızı tavsiye ederim. Eğer onu kullanmayacaksanız cmd yerine powershell kullanın. Böylece en azından komutları farklılık olmadan -umuyorum ki- çalıştırabilirsiniz.
122 |
123 | ```bash
124 | npx create-react-app ilk-uygulama
125 | ```
126 |
127 | Bu komut ile proje dosyalarını oluşturduktan sonra proje dizinine gidelim ve uygulamamızı ayağa kaldıralım.
128 |
129 | ```bash
130 | cd ilk-uygulama
131 | npm start
132 | ```
133 |
134 | Şuanda yerel sunucunuzda React çalışır durumda olması gerekiyor. Otomatik olarak tarayıcınızda bağlantı açılacaktır eğer açılmaz ise, tarayıcınızda adres çubuğuna **http://localhost:3000** yazarak bağlanabilirsiniz. Karşılaşmanız gereken ekran şu şekilde olmalı:
135 |
136 | 
137 |
138 | package.json dosyasını incelerseniz "scripts" kısmında kullanabileceğiniz bazı komutlara rastlayacaksınız. Buradaki start, build, test ve eject komutlarını kısaca inceleyelim.
139 |
140 | - **npm run start:** geliştirme ortamında React uygulamasını ayağa kaldırır.
141 |
142 | - **npm run build:** geliştirme ortamından canlı ortalama transfer için build işlemini gerçekleştirir.
143 |
144 | - **npm run test:** projemize dahil olan jest ile hazırladığınız testleri çalıştırır.
145 |
146 | - **npm run eject:** proje dosyaları içinde görmediğimiz server ve config dosyalarını manuel olarak yönetmek için dışarı çıkarır. Bu işlem yapılmak isteniyorsa proje oluşturulduğunda hiçbir ekleme ve düzenleme yapılmadan çalıştırılmalıdır. Aksi halde çalışmaz ve bu komutu çalıştırırken dikkatli olunması gerekir çünkü kalıcı bir zarar verebilir.
147 |
148 | create-react-app haricinde React projesi oluşturmak için birçok farklı alternatif araç mevcut. Biz facebook tarafından geliştirilen resmi araç olduğu için create-react-app kullanacağız. Siz diğer alternatiflere de göz atmak isterseniz diye onları da bir liste halinde ekleyeceğim.
149 |
150 | Alternatif araçlar: [enclave](https://github.com/eanplatter/enclave), [nwb](https://github.com/insin/nwb), [motion](https://github.com/steelbrain/motion), [rackt-cli](https://github.com/mzabriskie/rackt-cli), [budo](https://github.com/mattdesl/budo), [rwb](https://github.com/petehunt/rwb), [quik](https://github.com/satya164/quik), [sagui](https://github.com/saguijs/sagui), [roc](https://github.com/rocjs/roc)
151 |
152 | ## JSX ve HTML
153 |
154 | 
155 |
156 | JSX React için özel olarak hazırlanmış bir biçimlendirme dilidir. React içinde HTML değil de JSX kullanmamızın en büyük sebeplerinden biri de JSX ile oluşturduğumuz şablonlara macOS Catalina ile kolaylıkla hükmedebiliyor olmamızdır. Yani JSX yazarken aslında biraz eskiye dönüp JavaScript ve HTML dillerini bir arada yazıyoruz.
157 |
158 | Örneğin HTML ile değişkenleri, matematiksel işlemleri, fonksiyonları, koşullu karşılaştırmaları, döngüleri ve bunlar gibi dinamik olan hiçbir şeyi kullanamazken JSX ile bunları kullanabiliyoruz.
159 |
160 | Genel olarak JSX yazımı HTML üzerine kurulmuştur. Bazı anahtar kelimeler değiştirilmiş ve bazı zorunluluklar getirilmiştir.
161 |
162 | **HTML ve JSX arasındaki bazı anahtar kelime farkları:**
163 |
164 | | HTML | JSX | Açıklama |
165 | | -------- | -------------- | ---------------------------------------------------------------------------------------------------------------- |
166 | | checked | defaultChecked | checkbox veya radio tipindeki elemanlarda varsayılan olarak seçili gelme özelliği |
167 | | class | className | bir elemanın tasarımını CSS ile ilişkilendirme özelliği |
168 | | for | htmlFor | genellikle label için kullanılan for anahtar sözcüğü |
169 | | style="" | style={} | style özelliği ile inline CSS verilirken HTML'de string olarak jsx'de ise JavaScript objesi olarak değer girilir |
170 | | value | defaultValue | input ve textarea için varsayılan değer |
171 |
172 | **Bir elemana sınıf atama karşılaştırması:**
173 |
174 | ```html
175 |
176 |
177 | ```
178 |
179 | ```jsx
180 | // JSX ile div'e sınıf atama
181 | // {"container"} yerine "container" de kullanılabilir
182 |
183 | ```
184 |
185 | **Bir elemana inline CSS atama karşılaştırması:**
186 |
187 | ```html
188 |
189 |
195 | ```
196 |
197 | HTML ve JSX arasında style tanımlamalarında farklar görmüş olabilirsiniz. Biraz da bu farklarda değinelim. JSX tarafında tanımlamalar JavaScript objesi olarak yapıldığı için direkt olarak style üzerinde de JavaScript üzerinde kullanılan CSS isimlendirmelerini kullanıyoruz. Yani normalde "margin-top: 10px" derken aradaki çizgiyi kaldırıp her ilk kelime hariç sonraki harflerin ilk harfini büyük harfe çevirerek "marginTop: 10" şeklinde yazıyoruz. Ayrıca fark ettiğiniz gibi HTML'de "10px" yazarken JSX'de integer olarak 10 yazdık. Aynı yazım biçimini fontSize, height, weight gibi sayısal değerler girilen özelliklerde de kullanıyoruz. Burada integer olarak yazılan değerler piksel olarak algılanıyor. Eğer yüzde şeklinde bir ifade girmek isterseniz bunu tırnakların içine olarak belirtiyorsunuz. Eğer bu yazım tarzı size sıkıcı geldi ise özel bir CSS dosyası oluşturup içine normal CSS kodlarını yazmaya devam edebilirsiniz, bileşene "className" özelliğini kullanarak bu sınıf ismini verdiğinizde CSS kodlarınız geçerli olacaktır.
198 |
199 | | HTML (style) | JSX (style) |
200 | | ------------------------------- | -------------------------------- |
201 | | margin-top: 10px | marginTop: 10 |
202 | | color: red | color: "red" |
203 | | background-color: #fff | backgroundColor: "#fff" |
204 | | background-image: url('bg.png') | backgroundImage: "url('bg.png')" |
205 | | z-index: 10 | zIndex: 10 |
206 |
207 | CSS ve HTML DOM Style biçimlendirmesi arasındaki tüm farkları (aslında HTML DOM stillerini) görmek için [buraya tıklayarak](https://www.w3schools.com/jsref/dom_obj_style.asp) w3school'un hazırladığı listeye göz atabilirsiniz.
208 |
209 | Yukarıdaki tabloda da görüldüğü gibi neredeyse bire bir olarak aynılar. Üst kısımda bazı zorunluluklar olduğundan bahsetmiştik. Bunlara da kısaca bir göz atalım.
210 |
211 | HTML üzerinde bir eleman açılır ve kapatılmaz ise genellikle tarayıcılar bunu gözardı eder ve bir sorun yokmuş gibi devam eder. JSX tarafında eğer bir bileşen açıldıysa kapatılmak zorundadır, kapatmazsanız hata alacaksınız.
212 |
213 | Bir eleman HTML ve jsx üzerinde 2 farklı şekilde kapatılabilir.
214 |
215 | 1. İçinde başka bir eleman olacak şekilde kapatma
216 |
217 | 2. Açılış ve kapanış için tek etiket
218 |
219 | ```html
220 |
221 |
merhaba dünya
222 |
223 | açtık kapattık
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 | ```
232 |
233 | Yukarıda 2. örnekte sondan hemen önce koyduğumuz "/" işareti o elemanı kapattığımızın göstergesidir. Yukarıdaki 2 örnek de doğrudur ve bu şekilde tüm elemanlar açıldığı gibi kapatılmalıdır. Eğer HTML tarafında input, img ve br gibi etiketleri kapatmasaydınız da kod çalışmaya devam edecekti.
234 |
235 | Başka bir zorunluluk ise oluşturacağımız bileşenlerde ilk harfi büyük seçmemiz gerekiyor. Aksi taktirde bu özel bir bileşen değil HTML elemanı olarak algınacaktır ve bileşene erişimimizi engelleyecektir.
236 |
237 | Son olarak JSX'in birkaç özelliğine daha değinip JSX bölümünü bitirelim. Az biraz yukarıda JSX içinde HTML tarafında yapamadığımız bazı şeyleri de yapabildiğimizi söyledik. Bunlardan bazılarında JSX kodlarını bir değişkene atayabiliriz ya da bir JSX kodu içinde mevcut JavaScript değişkenlerini kullanabiliriz. O da mı yetmedi? Fonksiyon çağırıp bir de gelen cevaba 5 bile ekleriz.
238 |
239 | ```jsx
240 | // JSX'i değişkene atama ve içerisinde değişken kullanma
241 |
242 | const isim = "orçun";
243 | const baslik =
{isim} 15 sene yaşlandın, yeni yaşın: {kacYasindasin(mevcutYas) + 5}
253 | ```
254 |
255 | ## Bileşenler (components)
256 |
257 | Öncelikle bileşenlerin tanımından başlayalım, sonrasında türlerini inceleyip örnek kodlara göz atalım.
258 |
259 | Bileşenleri bir bütünü oluşturan parçalar olarak düşünebiliriz. Bu bileşenler birbirinden bağımsız olarak çalışır fakat, istenilen durumlarda bu bileşenler arasında kendimiz bağlantılar oluşturabiliriz. Yarattığımız bileşenleri başka bileşenler içinde bir ya da birden fazla kez kullanabiliriz. Bir bileşeni ekranda gösterebilmenin (render) iki yolu vardır.
260 |
261 | 1. index üzerinde render edilmesi ve dökümana yazdırılması
262 |
263 | 2. Render edilen başka bir bileşen içinde çağrılması
264 |
265 | Varsayılan olarak oluşturduğumuz uygulamada index.js içinde 1. maddedeki gibi App bileşeni render ediliyor ve bu sayede tarayıcıda App bileşenini görüyoruz. Eğer başka bir bileşen daha oluşturup bunu da App içinde çağırıp kullansaydık bu da 2. maddedeki gibi bir bileşen kullanımı olacaktı. Aşağıda birinci maddeye projemizdeki örnek kodu ekledim, ikinci maddenin örneğini de kendi bileşenlerimizi oluşturmaya başladığımızda göreceğiz.
266 |
267 | ```jsx
268 | // bahsedilen index.js içeriği
269 |
270 | import React from 'react';
271 | import ReactDOM from 'react-dom';
272 | import App from './App';
273 |
274 | ReactDOM.render(, document.getElementById('root'));
275 | ```
276 |
277 | Kendi bileşenlerimizi oluşturmadan önce bilmemiz gereken bir ayrıntı daha var. Bileşenler yapı olarak 2 tipte olabilir.
278 |
279 | 1. Fonksiyonel Bileşen
280 |
281 | 2. Sınıf (class) Bileşen
282 |
283 | Bu iki tip bileşen aslında aynı şeyi temsil ediyor fakat kullanım tarafında büyük farklar oluşuyor. Yaşam döngüsü içinde bulunan bazı metodları sınıf tabanlı bileşenlerde kullanabiliyorken fonksiyon tabanlı metodlarda kullanamıyoruz. Aynı şekilde daha işlemediğimiz ama en önemli kavramlardan biri olan state'ler önceden fonksiyon tabanlı bileşenlerde kullanılamıyordu, React 16.8 ile birlikte gelen Hooks güncellemesi ile state'ler fonksiyonel bileşenlerde de kullanılmaya başlandı.
284 |
285 | Bahsettiğimiz iki tip bileşen arasında özellik olarak bakıldığında çok fark kalmıyor. Daha önemli kısım olan optimizasyon tarafına baktığımızda ise React'ın resmi dökümanında fonksiyonel bileşen kullanımının daha performanslı olduğundan bahsediliyor ve kullanımı tavsiye ediliyor. Bunun sebebi de aslında JavaScript tarafında normalde sınıf diye bir kavram yok. Ecmascript 2015 ile sınıfları kullanmamıza olanak sağlanıyor fakat hala arka tarafta bir sınıf yok. Bizim yazdığımız sınıf kodları işlenirken prototype'lara dönüştürülüyor. Bu yüzden direkt olarak OOP mimarisini kullanamıyoruz ve bir yavaşlık söz konusu oluyor.
286 |
287 | Syntax olarak fonksiyon ve sınıf tabanlı bileşenlere göz atalım. (Bu örneklerde props'lar devreye sokulmamıştır)
288 |
289 | ```jsx
290 | import React from "react";
291 |
292 | function Hosgeldin() {
293 | return
303 | }
304 | }
305 | ```
306 |
307 | **Dikkat edilmesi gereken bazı noktalar:**
308 |
309 | - Oluşturulan bileşen isimlerinin ilk harfi büyük olmak zorundadır.
310 |
311 | - return ifadesinde sadece bir adet ana JSX veya HTML elemanı döndürülebilir. (Doğru ve yanlış kullanım için örnekler ekleyeceğim)
312 |
313 | - Sadece sınıf tabanlı bileşenlerde render metodu kullanılır, fonksiyonel bileşenlerde fonksiyon içinden geri dönen değer otomatik render edilir.
314 |
315 | - return ifadesi içinde geri dönen değerler direkt olarak yazılabileceği gibi parantez içinde de yazılabilir. Bu şekilde çok satırlı ifadeleri geri döndürebiliriz.
316 |
317 | - JSX bölümünde JSX kodlarını değişkene atayabileceğimizi söylemiştik. Bu şekilde değişkene atanan bir JSX ifadesini de geri döndürebiliriz.
318 |
319 | ```jsx
320 | // Hatalı geri döndürme
321 | // Birden fazla ana eleman döndürülemez
322 |
323 | function Hosgeldin() {
324 | return (
325 |
hoşgeldin
326 |
bugün çok güzelsin
327 | )
328 | }
329 | ```
330 |
331 | ```jsx
332 | // Doğru geri döndürme
333 | // Birden fazla elemanı tek bir ana eleman altında birleştirdik ve tek bir ana eleman geri döndürdük
334 |
335 | // src/Hosgeldin.js
336 |
337 | function Hosgeldin() {
338 | return (
339 |
340 |
hoşgeldin
341 |
bugün çok güzelsin
342 |
343 | )
344 | }
345 | ```
346 |
347 | ### Bileşeni Dışarı Aktarmak
348 |
349 | Bileşen oluşturmayı öğrendiğimize göre artık bileşenimizi diğer bileşenlerin içinde kullanabiliriz. Bunun için oluşturduğumu bileşen içindeyken bileşenimizi dışarı aktarmamız gerekiyor. Dışarı aktarmak yetmeyecek, kullanmak istediğimiz yerde de içeri aktaracağız.
350 |
351 | Şuanda mevcut uygulamamızda index.js üzerinde App bileşenimiz çağırılıyor. Projemizdeki src dizini içerisine **HavaDurumu.js** adında bir dosya oluşturalım ve yukarıda öğrendiğimiz gibi fonksiyon tabanlı bir bileşen oluşturalım. Fazladan bir satır daha ekleyeceğiz ve bileşenimizi dışarı aktaracağız.
352 |
353 | ```jsx
354 | // Webpack dışarı aktarma yöntemi 1
355 |
356 | import React from "react";
357 |
358 | function HavaDurumu() {
359 | return
bugün hava güneşli
360 | }
361 |
362 | export default HavaDurumu;
363 | ```
364 |
365 | İstersek satır fazlalığını kaldırmak için fonksiyonumuzu tanımlarken de "export default" anahtar sözcüklerini kullanarak dışarı aktarma yapabiliriz.
366 |
367 | ```jsx
368 | // Webpack dışarı aktarma yöntemi 2
369 |
370 | import React from "react";
371 |
372 | export default function HavaDurumu() {
373 | return
bugün hava güneşli
374 | }
375 | ```
376 |
377 | İki kod bloğundan birini seçip kullanabilirsiniz bir farkı yok. Dışarı aktarmayı tamamladığımıza göre içeri aktarma kısmına geçebiliriz. App.js dosyamızda kod kalabalığını engellemek için biraz temizlik yapalım. Fazla yazıları ve logoyu kaldıralım ki daha rahat çalışalım.
378 |
379 | ```jsx
380 | import React from "react";
381 | import "./App.css";
382 | import HavaDurumu from "./HavaDurumu";
383 |
384 | function App() {
385 | return (
386 |
387 |
388 |
389 |
390 |
391 | )
392 | }
393 |
394 | export default App;
395 | ```
396 |
397 | Burada nasıl React'ı import ediyorsak aynı şekilde kendi bileşenimizi de import ettik. Sadece farkettiyseniz bir dosyayı içeri aktardığımız halde "./HavaDurumu" yazdık ve ".js" uzantısını eklemedik. JavaScript dosyalarını içeri atarırken bu şekilde sadece dosya ismini yazmamız yeterli oluyor.
398 |
399 | Eğer projeniz çalışır durumda değilse "npm start" ile ayağa kaldırın ve localhost:3000 üzerinde bu ekranı görüp görmediğinizi kontrol edin. Eğer bu şekilde çıktıyı aldıysanız her şey tamam demektir.
400 |
401 | 
402 |
403 | ## Props (Bileşen Parametreleri)
404 |
405 | Şimdiye kadar oluşturduğumuz bileşenlerde herhangi bir özelleştirme yapmadık ve hiçbir parametre kullanmadık. Prop'lar ile bileşenlerimize veri gönderimi sağlayabiliyoruz. Bu şekilde gönderdiğimiz parametreleri bileşen içinde kullanarak özelleştirmeler yapabiliyoruz.
406 |
407 | Prop'ları bileşenlerde sınıf tabanlı veya fonksiyonel tabanlı olması farketmeksizin tümünde kullanabiliyoruz. Aralarında nesne yönelimli kullanımdan kaynaklanın tek kelimelik bir fark oluyor fakat bunu da nesneye biraz hakimseniz karıştıracağınızı düşünmüyorum.
408 |
409 | Prop'ların örneklerine geçmeden önce HTML üzerinden basit bir örnek vererek mantığını pekiştirebileceğinizi düşünüyorum. Html üzerinde bir resim çağırdığımızı düşünelim. Bunu koda nasıl ekleriz?
410 |
411 | ```html
412 |
413 | ```
414 |
415 | Burada gördüğünüz gibi img elemanına src ve alt olmak üzere iki paremetre gönderdik. Tarayıcı kodu görüntüye çevirirken bu parametreleri kullanacak ve bize bir sonuç üretecek. Aynı şekilde bileşenlere de direkt olarak aynı şekilde (biraz daha gelişmiş) parametreler göndereceğiz. HTML içinde bu parametrelerin nasıl kullanılacağına karar veremeyiz ama bileşenimiz üzerinden gelen bu değişkenleri kontrol edip ona göre hareket etmesini sağlayacağız.
416 |
417 | Yukarıda oluşturduğumuz HavaDurumu bileşenine prop desteği ekleyelim ve gelen parametreye göre geri dönüş yapalım.
418 |
419 | ```jsx
420 | // fonksiyon tabanlı bileşende prop kullanımı
421 |
422 | import React from "react";
423 |
424 | function HavaDurumu(props) {
425 | return
439 | }
440 | }
441 |
442 | export default HavaDurumu;
443 | ```
444 |
445 | Örneklerde de görüldüğü gibi fonksiyon tabanlı bileşenlerde propsları okuyabilmek için bileşenmizi oluşturan fonksiyona props adında bir parametre ekledik ve bunun içindeki durum parametresini kullandık.
446 |
447 | Sınıf tabanlı bileşende ise prop'ları kullanmak için herhangi bir ekstra kod eklemedik. Bunun sebebi sınıfımızın içinde zaten prop'ların barındırılması. Bu prop'lara erişmek için this sözcüğünü kullanarak sınıf içindeki props değerlerine erişebiliyoruz.
448 |
449 | ```jsx
450 | import React from "react";
451 | import "./App.css";
452 | import HavaDurumu from "./HavaDurumu";
453 |
454 | function App() {
455 | return (
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 | )
464 | }
465 | export default App;
466 | ```
467 |
468 | App tarafında da HavaDurumu olarak çağırdığımız bileşenlerin sayısını 3'e çıkardım ve her birine durum parametresi ile farklı bir string değer gönderdim. Görmemiz gereken ekran şuna benzer bir şey olması gerekiyor.
469 |
470 | 
471 |
472 | HTML içinde bu parametrelere attributes diyoruz ve bunlara sadece string olarak parametreler gönderiliyor. JSX'de ise burada sadece string gönderme gibi bir durum yok.
473 |
474 | Prop içeriği olarak string, integer, boolean, object, array ve hatta fonksiyon bile gönderebiliriz. String haricinde bir prop gönderimini incelemek için 2 parametre daha ekleyelim. Birincisi style (object), ikincisi ise aktiflik (boolean) olsun. Tanımladığımız style'ı bileşenimiz içerisindeki HTML üzerinden kullanığımız p'nin style özelliğine bağlayacağız ve eğer aktiflik parametresinde false değeri geldiyse geri dönüş olarak yazımızı değil de null bir değer döndüreceğiz.
475 |
476 | Bu sefer öncelikle App tarafını yapalım sonrasında bileşenimizi düzenleyelim.
477 |
478 | ```jsx
479 | import React from "react";
480 | import "./App.css";
481 | import HavaDurumu from "./HavaDurumu";
482 |
483 | function App() {
484 | return (
485 |
486 |
487 |
491 |
495 |
499 |
500 |
501 | )
502 | }
503 |
504 | export default App;
505 | ```
506 |
507 | Yaptığımız düzenlemelere göre hava durumlarımızdan ikinci olanın gözükmemesi gerekecek. Birinci ve sonuncunun arkaplan renkleri ise sırasıyla sarı ve turkuaz olmalı. Bunun için bileşenimizde düzenleme yapmaya başlayalım.
508 |
509 | ```jsx
510 | // fonksiyon tabanlı bileşen
511 |
512 | import React from "react";
513 |
514 | function HavaDurumu(props) {
515 | return (
516 |
545 | )
546 | }
547 | }
548 |
549 | export default HavaDurumu;
550 | ```
551 |
552 | Her iki bileşen türünde de JSX içinde kısa if/else bloğunu kullanabilmek için objelerimizi ana bir div elemanı içine aldım. Böylelikle artık "sorgu ? if bloğu : else bloğu" şeklindeki kısa yazımı kullanabildik. Ana bir div elemanı içine almadan düz if sorgusu ile eğer aktiflik true ise deyip if bloğu içinde render da yapabilirdik. Böylelikle geriye boş bir div değil sadece null döndürmüş olurduk. Benim bu şekilde yapmaktaki amacım JSX içinde kısa if/else kullanımını da göstermek.
553 |
554 | 
555 |
556 | ### Prop Types ile Kısıtlama ve Zorlama
557 |
558 | Oluşturduğunuz bileşen kullanılmak istendiğinde mutlaka gönderilmesi gereken parametreler olabilir. Aynı şekilde zorunlu olmasa bile gelen prop değerinin belirli bir değişken tipinde olması gerekiyor olabilir. Örneğin adet prop'unuza "eşyan" gelmesi anlamsız olur, çünkü bu prop sadece integer tipinde değerler almalı. Bunun için bileşen içinde tek tek if sorguları yazmak yerine "prop-types" paketini kullanarak basit bir şekilde prop değerlerine kısıtlamalar koyabilir ya da prop değerlerini zorunlu kılabilirsiniz.
559 |
560 | > prop-types paketi create-react-app aracı ile otomatik olarak kurulmaktadır, eğer paket yok ise "npm install --save prop-types" komutu ile projenize ekleyebilirsiniz.
561 |
562 | Örnek olması açısında daha önceki yazdığımız kodlardan bağımsız bir bileşen oluşturacağım. Bileşenimiz bir sitedeki blog yazısını temsil edecek ve 4 adet prop değerine sahip olacak.
563 |
564 | 1. Başlık (string tipinde olacak ve zorunlu olacak)
565 |
566 | 2. İçerik (string tipinde olacak ve zorunlu olmayacak)
567 |
568 | 3. Puan (1 ve 10 arasındaki bir integer değer olacak ve zorunlu olmayacak)
569 |
570 | 4. Kategoriler (string dizisi olacak ve zorunlu olmayacak)
571 |
572 | ```jsx
573 | import React from "react";
574 | import PropTypes from "prop-types";
575 |
576 | class Blog extends React.Component {
577 | render() {
578 | return (
579 |
591 | )
592 | }
593 | }
594 |
595 | Blog.propTypes = {
596 | baslik: PropTypes.string.isRequired,
597 | icerik: PropTypes.string,
598 | puan: PropTypes.oneOf([1,2,3,4,5,6,7,8,9,10]),
599 | kategoriler: PropTypes.arrayOf(PropTypes.string)
600 | }
601 |
602 | export default Blog;
603 | ```
604 |
605 | **Kullanabileceğiniz PropTypes değerleri:** array, bool, func, number, object, string, symbol
606 |
607 | **Kullanabileceğiniz PropTypes fonksiyonları:** instanceOf, oneOf, oneOfType, arrayOf, objectOf, shape, exact
608 |
609 | Yukarıdaki örnekte prop-types haricinde kategoriler kısmında map kullanarak bir dizi içindeki tüm elemanları span etiketi içerisinde yazdırmayı da görmüş olduk.
610 |
611 | > Eğer bileşeninizde prop-types kullanarak olması gereken prop'ları belirtirseniz bu hem sizin için hem de daha sonrasında kodunuzu okuyacak başka yazılımcılar için büyük fayda sağlayacaktır. Bir takım olarak proje geliştiriyorsanız veya büyük çaplı bir işin altına girdiyseniz prop-types kullanmanızı şiddetle tavsiye ederim.
612 |
613 | ### Varsayılan Prop Değerlerini Belirlemek
614 |
615 | Prop'lar üzerinden değer gönderilmediği zaman kullanılmak için varsayılan değerler belirleyebilirsiniz. PropTypes'a benzer bir şekilde kolaylıkla bu atamaları yapabiliriz. Yine önceki projemizden bağımsız basit bir örnek ile kodu inceleyelim.
616 |
617 | ```jsx
618 | import React from "react";
619 |
620 | class Telefon extends React.Component {
621 | render() {
622 | return (
623 |
624 |
Marka: {this.props.marka}
625 |
RAM: {this.props.ram}
626 |
Bellek: {this.props.disk}
627 |
628 | )
629 | }
630 | }
631 |
632 | Telefon.defaultProps = {
633 | marka: "Xiaomi",
634 | ram: 4,
635 | disk: 64
636 | }
637 |
638 | export default Telefon;
639 | ```
640 |
641 | Telefon örneğinin çok mantıklı olmadığının farkındayım fakat genel olarak yapıyı göstermek için basit bir şekilde bileşen oluşturdum. İhtiyacınıza göre kendi varsayılan değerlerinizi ayarlayabilirsiniz.
642 |
643 | ## State
644 |
645 | React.js öğrenmeye başladığımda daha önce kullanmadığımdan state mevzusunu tam olarak kafama oturtamamıştım. O yüzden en basit şekilde anlatmaya çalışacağım. Hatta state mantığına benzer bir şekilde jQuery tarafında bunun ne anlama geldiğini de anlatmaya çalışacağım.
646 |
647 | Bir önceki bölümde prop'lardan bahsetmiştik. Bir üst bileşenden gönderilen prop değerlerini bileşen içinde kullanıyorduk. Bileşene gönderilen prop değeri sabittir, sonradan değişmez.
648 |
649 | State ise isminden de anlaşılabileceği gibi durumu temsil ediyor ve her an değişebilir bir şekilde bekliyor. State değeri değiştiğinde bileşen tekrar render edilir ve değişen değeri bileşen içinde kullanırız.
650 |
651 | State'ler, prop'larda olduğu gibi bir üst bileşenden aktarılmaz. Ama istersek prop'dan gelen değeri state değişkenine eşitleriz ve state'in ilk değerini belirlemiş olabiliriz.
652 |
653 | Ayrıca şu an için (React 16.12) state'ler normal yazımı ile sınıf tabanlı bileşenlerde kullanılabilir durumdalar. Fonksiyon tabanlı bileşenlerde de state'leri kullanmamızı sağlayan hooks güncellemesini ileriki bölümlerde göreceğiz. Bu sebeple bu bölümde sınıf tabanlı bileşenlerle çalışacağız.
654 |
655 | ### jQuery tarafında state mantığı
656 |
657 | > State mantığını daha iyi kavrayabilmeniz için jQuery ile basit bir state mimarisi oluşturacağım. Bunun React ile hiçbir ilgisi yok. Eğer jQuery bilmiyorsanız burayı atlayabilirsiniz.
658 |
659 | ```JavaScript
660 | 0
661 |
662 | var sayac = 0;
663 |
664 | function sayacGuncelle(sure){
665 | sayac = sure;
666 | $("#sayac").text(sayac);
667 | }
668 |
669 | $(function(){
670 | setInterval(function(){
671 | sayacGuncelle(sayac + 1);
672 | }, 1000);
673 | });
674 | ```
675 |
676 | Kabataslak böyle bir jquery kodu yazdığımızda ekranımızda sıfırdan başlayarak her saniye bir artan bir sayaç görüntüleceğiz.
677 |
678 | Hadi bunu React ile yapalım. Sayaca adında bir bileşen oluşturup App üzerinden çağıralım ve içine şu şekilde dolduralım.
679 |
680 | ```jsx
681 | import React from "react";
682 |
683 | export default class Sayac extends React.Component {
684 |
685 | state = {
686 |
687 | sayac: 0
688 | }
689 |
690 | componentDidMount(){
691 | setInterval(() => {
692 | this.setState({
693 | sayac: this.state.sayac + 1
694 | })
695 | }, 1000);
696 | }
697 |
698 | render() {
699 | return (
700 |
701 | {this.state.sayac}
702 |
703 | )
704 | }
705 | }
706 | ```
707 |
708 | State değerleri sınıfın içindeki state değişkeninde bir obje olarak tutuluyor. Bu değerleri this.state.state_ismi şeklinde erişebiliyoruz. Buradaki en önemli şey ise bir state değerini değiştirmek istediğimizde bu değere direkt olarak müdahale etmemek. Değişiklik yapacağımızda **setState** metodunu kullanmalıyız. Böylece React state üzerinde bir değişiklik olduğunu anlayacak ve bileşeni tekrar render edecek.
709 |
710 | Varsayılan state değerleri oluşturmak için de sınıf içinde direkt olarak state objesinin içine ekleme yapabiliriz.
711 |
712 | > Kodda gördüğünüz **componentDidMount** React içinde tanımlı özel bir metoddur. Bileşen render edildikten hemen sonra çalıştırılır. Bir sonraki bölümde yaşam döngüsü dediğimiz bu özel metodları listeleyeceğiz.
713 |
714 | 
715 |
716 | Ekranım ara verdiğimde açık kalmış ve aşağıdaki gibi 2210 saniye ilerlemiş :)
717 |
718 | ## Yaşam Döngüsü
719 |
720 | Yazdığımız React kodları ekranda görülebilir bir hale gelmeden önce belirli aşamalaradan geçiyor ve yaşam döngüsünde özel metodları kullanarak bu aşamalara dahil olup işleyişe müdahaleler yapabiliyoruz. Önceki bölümde kullandığımız componentDidMount bu özel metodlardan biriydi. Aynı şekilde kaynağın başından beri her yerde gördüğünüz render'da bu özel metodların arasında. React'ın işleyişindeki bu yaşam döngüsüne lifecycle ismini veriyoruz. Birkaç önemli noktaya değindikten sonra bir görsel ile tüm bu işleyişi öğreneceğiz.
721 |
722 | **Yaşam döngüsü aşamaları:**
723 |
724 | - Mounting (ekleme)
725 |
726 | - Updating (güncelleme)
727 |
728 | - Unmounting (kaldırma)
729 |
730 | 
731 |
732 | Görsele biraz göz atarak tüm özel metodların hangi sırayla ilerlediğini kavrayabilirsiniz. Bu şablondaki yeşil ile gösterilen özel metodları async olarak da kullanabiliyoruz. Görsel üzerinden her şey anlaşılsa da kısa bir şekilde en çok kullanılan 5 özel metodu tablo üzerinde inceleyelim.
733 |
734 | | Metod | Açıklama |
735 | | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
736 | | constructor | Bileşen çağrıldığında ilk çalışan metod budur. Çalıştığı anda bileşen üzerinde herhangi bir şey render edilmemiş olur ve bu yüzden DOM ile ilgili işlemler yapılamaz. Prop'lar ve state'ler ile ilgili kontrolleri yapabiliriz. |
737 | | render | Yazdığımız kodların işlendiği kısımdır. render içeriside state'leri ve prop'ları kullanabiliriz. State güncelleme işlemini de burası da dahil olacak şekilde bu kısımdan kısımdan itibaren yapabiliriz. |
738 | | componentDidMount | render işleminden sonra çalışan kısımdır. Genel olarak API ile ilgili işlemlerde veya bileşen oluşturulduğunda başlaması gereken olaylar için kullanıyoruz. |
739 | | componentDidUpdate | Daha önceden render edilen bileşenimiz üzerinde bir değişiklik olduğunda çalışır. Örneğin setState kullanarak yaptığımız state değişiklerinden sonra bu metod aktif olur. |
740 | | componentWillUnmount | Bileşen eğer DOM'dan çıkarılacak ise çıkarılmadan önce bu metod çalışır. Örneğin az önce yaptığımız sayaç bileşenden sonlanırken durdurulmalı ve bu işlemi burada yapmalıyız. |
741 |
742 | ## Olay Yönetimi (Events)
743 |
744 | JavaScript tarafındaki eventler ile neredeyse aynıdır fakat bazı isimlendirme farkları bulunuyor. Bu farkları CSS tarafındaki ve jsx tarafındaki style isimleri gibi değerlendirebiliriz.
745 |
746 | Örneğin DOM'da "onclick" (lowercase) iken React tarafında bunu "onClick" (camelCase) olarak kullanıyoruz. Ekstra olarak DOM tarafında bu eventlere string içerisinde fonksiyon isimlerini giriyorken react'da direkt olarak fonksiyonu belirtiyoruz.
747 |
748 | Bir diğer fark ise DOM tarafında bir elemanın varsayılan işlemini engellemek için "return false" ifadesi de kullanılabiliyorken React'da bu tanımlı değildir. Eğer bir eventin varsayılan özelliğini pasifleştirmek isterseniz "e.preventDefault()" fonksiyonunu kullanmalısınız.
749 |
750 | React'ın kendi dökümanında tüm eventlerin bir listesi bulunmuyor ya da ben bulamadım. Burada bir tablo halinde kullanabileceğininiz tüm event isimlerini kategorilendirerek paylaşacağım fakat tek tek açılmalarını yapmayacağım. Çünkü zaten isimlerinden kolaylıkla ne için kullanılacağı anlaşılabiliyor.
751 |
752 | | Kategori | Event Listesi |
753 | | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
754 | | Clipboard | onCopy, onCut, onPaste |
755 | | Composition | onCompositionEnd, onCompositionStart, onCompositionUpdate |
756 | | Keyboard | onKeyDown, onKeyPress, onKeyUp |
757 | | Focus | onFocus, onBlur |
758 | | Form | onChange, onInput, onSubmit |
759 | | Mouse | onClick, onContextMenu, onDoubleClick, onDrag, onDragEnd, onDragEnter, onDragExit, onDragLeave, onDragOver, onDragStart, onDrop, onMouseDown, onMouseEnter, onMouseLeave, onMouseMove, onMouseOut, onMouseOver, onMouseUp |
760 | | Selection | onSelect |
761 | | Touch | onTouchCancel, onTouchEnd, onTouchMove, onTouchStart |
762 | | UI | onScroll |
763 | | Mouse Whell | onWhell |
764 | | Media | onAbort, onCanPlay, onCanPlayThrough, onDurationChange, onEmptied, onEncrypted, onEnded, onError, onLoadedData, onLoadedMetadata, onLoadStart, onPause, onPlay, onPlaying, onProgress, onRateChange, onSeeked, onSeeking, onStalled, onSuspend, onTimeUpdate, onVolumeChange, onWaiting |
765 | | Image | onLoad, onError |
766 | | Animation | onAnimationStart, onAnimationEnd, onAnimationIteration |
767 | | Transition | onTransitionEnd |
768 |
769 | Kategori isimlerini özellikle çevirmedim çünkü bazı çevirilerin anlamı bozduğunu düşünüyorum.
770 |
771 | ### Eventler için Bind
772 |
773 | Eğer bileşen sınıfımızdaki nesneleri event bağlantısını yaptığımız metod içinde kullanmaya devam etmek istiyorsak bind işlemi uygulamalıyız. JavaScript üzerinde bind fonksiyonun tanımı için Mustafa Murat Coşkun'un medium yazısından bir alıntı yapacağım.
774 |
775 | > Bind() fonksiyonu, içine verilen objeye göre yeni bir fonksiyon kopyası yaratır. Oluşan bu kopya fonksiyonu daha sonradan argüman listesi ile beraber gönderilen objeye kullanabiliriz.
776 |
777 | Bind işlemini yazısal olarak açıklamak biraz zor ama kendimce de açıklamaya çalışacak olursam mevcut bulunduğumuz scope'u kullanmaya devam edebilmek için başka bir scope'a referans olarak göndermek diyebilirim.
778 |
779 | Bind işlemini 2 şekilde yapabiliriz.
780 |
781 | 1. Constructor içeresinde bir defa bind işlemi yaparak
782 |
783 | 2. Event işleminde her seferinde bind işlemi yaparak
784 |
785 | ```jsx
786 | // Yöntem 1: menuAc metodunu this ile bind ederek metod içinde this anahtarıyla sınıfı kullanmaya devam edebileceğiz.
787 |
788 | constructor(props){
789 | super(props);
790 | this.menuAc = this.menuAc.bind(this);
791 | }
792 | ```
793 |
794 | ```jsx
795 |
796 | ```
797 |
798 | ### Event'ler ile Parametre Göndermek
799 |
800 | Event yönetiminde eleman içinde olan bir değeri ya da mevcutta bulunan başka bir değeri parametre olarak gönderebilirsiniz. Bileşeni tamamen oluşturmadan 2 parça halinde metodu ve render edilen elemanı yazacağım.
801 |
802 | ```jsx
803 | // olay yöneticisi metod
804 | function kayit(yazi){
805 | console.log(yazi);
806 | }
807 |
808 | // render edilen eleman
809 | this.kayit(e.target.value)} />
810 | ```
811 |
812 | Hazırladığımız örnek kodda sayfamızda bulunan inputta bir değişiklik olduğunda (value değiştiğinde) konsolumuza log olarak değeri yazdırılacak.
813 |
814 | ## Bileşenler Arasında İletişim
815 |
816 | Bu bölümde 3 farklı iletişim türünü inceleyebiliriz.
817 |
818 | > Bu bölümde parent (ebeveyn) olarak bahsedilen üst bileşen, child (çocuk) olarak bahsedilen de alt bileşendir.
819 |
820 | ### 1. Üst'ten Alt Bileşene Erişim (Parent to Child)
821 |
822 | Burada yapmak istediğimiz şey, mevcut bir bileşenin içindeyken o bileşenin içindeki alt bileşene erişmek. Bunun için prop'ları kullanıyoruz ve bu şekilde alt bileşene mesaj gönderebiliyoruz. Standart prop kullanımı için tekrar bir örnek eklemeyeceğim. Prop'lar bölümündeki örnekler bu erişimi sağlamamıza yarıyan özelliktir.
823 |
824 | ### 2. Alt'dan Üst Bileşene Erişim (Child to Parent)
825 |
826 | Eğer bir bileşeni oluşturan bileşen ile iletişim geçmek istiyorsanız ne yaparsınız? Bileşen içerisinde direkt olarak parent bileşene ulaşmanızı sağlayacak bir yol yok. O yüzden kendi yolumu inşaa edeceğiz.
827 |
828 | Bunun için yine prop'ları kullanacağız ama mesaj göndermek için değil bir kanal oluşturmak için. Parent bileşendeki bir metodu öncelikle bind ederek sonrasında bir prop ile alt bileşene göndereceğiz. (Prop'lar kısmında değer olarak fonksiyon da gönderebileceğimizden bahsetmiştik)
829 |
830 | Yapacağımız örnek yine bir sayaç olacak fakat bu sefer otomatik artan bir sayaç olmayacak. Sayacımızı bir butona her tıklandığında 1 artacak şekilde ayarlayacağız. Parent bileşenimizde sayaç göstergesi, child bileşende de ise sayacı arttırmak için buton olacak. Bu örnek üzerinde sayaç değerini tutmak için state'leri de kullanacağız.
831 |
832 | ```jsx
833 | // Sayac.js (parent)
834 |
835 | import React from "react";
836 | import Dugme from "./Dugme";
837 |
838 | class Sayac extends React.Component {
839 |
840 | constructor(props) {
841 | super(props);
842 | this.sayacArttir = this.sayacArttir.bind(this);
843 | }
844 |
845 | state = {
846 | sayi: 0
847 | }
848 |
849 | sayacArttir() {
850 | this.setState({
851 | sayi: this.state.sayi + 1
852 | });
853 | }
854 |
855 | render() {
856 | return (
857 |
858 |
{this.state.sayi}
859 |
860 |
861 | )
862 | }
863 |
864 | }
865 |
866 | export default Sayac;
867 | ```
868 |
869 | ```jsx
870 | // Dugme.js (child)
871 |
872 | import React from "react";
873 |
874 | export default class Dugme extends React.Component {
875 | render() {
876 | return (
877 |
880 | )
881 | }
882 | }
883 |
884 | export default Dugme;
885 | ```
886 |
887 | > Bir sonraki (üçüncü) erişim türündeki kütüphaneler farklı bir kullanım biçimiyle bu aşamada yaptığımız işlemleri de yapabileceksiniz.
888 |
889 | ### 3. Alt-Üst İlişkisi Olmayan Bileşenlere Erişim
890 |
891 | Aslında bu başlığın ifade ediliş şekli yanlış ama Türkçe olarak nasıl bir başlık yazacağımı bulamadığım için bu şekilde yazdım. Alt-üst ilişkisi olmaması imkansız çünkü mutlaka bir yerde bu bileşenlerin kesişim noktaları olmalı. Bileşenleri soy ağacı gibi düşünebiliriz ama sadece 2 tane ebeveyn değil de bir tane ebeveyn varmış gibi oluyor (tree). Birinci madde babanın çocuğa mesaj vermesi, ikinci madde çocuğun babanın mesaj vermesi olarak örnek gösterilebilir. Son maddede ise sınırsız örnek yazabiliriz. Çocuğun kuzene, dedesine hatta eltisine mesaj göndermesi.
892 |
893 | Bunu yapmak yapmak için 2 yöntem var. Birincisi ölüm gibi ama kimse ölmüyor. İkincisinde ise ekstra kütüphaneler yüklüyoruz ve bunlar üzerinden global state kullanabiliyoruz.
894 |
895 | Öncelikle birinci yönteme göz atalım. Bu yöntemde az önce öğrendiğimiz birinci ve ikinci maddeyi kullanarak basamak basamak state'i taşıyoruz. Bu çok fazla karmaşıklığa sebep oluyor ve bir süre sonra içinden çıkılmaz bir hal alıyor.
896 |
897 | 
898 |
899 | İkinci adımda ise bir Provider (sarmalayıcı) ile uygulamamızı kaplıyoruz. Bunu en dışarıdaki App bileşenini Provider bileşini içine ekliyoruz gibi düşünebilirsiniz. Böylelikle uygulamada çalışan tüm bileşenler bir sarmalayıcının altında oluyor. Bu provider üzerinden de global bir state kullanımı sağlayabiliyoruz.
900 |
901 | Bu amaçla üretilen çok kütüphane olabilir fakat şuanda en fazla kullanılan 2 kütüphaneye değinelim.
902 |
903 | - **Redux**: Redux ile global state kavramını kullanabiliyoruz. Normalde tek state üzerinden yaptığımız işlemler action, reducer ve store katmanlarından geçiyor. Kullanımı yeni başlayanlar için gerçekten çok karmaşık ve neyin ne amaçla yapıldığı çok fazla anlaşılmıyor. Başlangıç için "bir şeyler sürekli bir yerlere gidiyor/geliyor ama neden?" benzeri soruların kaçınılmaz olduğu bir kütüphane. 2020 Ocak için en fazla kullanılan state yönetim aracı olduğunu söyleyebiliriz.
904 |
905 | - **MobX**: MobX'de redux gibi bir state yönetim aracı. Fakat kullanılabilirlik ve okunabilirlik açısından çok daha sade ve basit. MobX içerisinde sadece ekstra olarak store ve actionları tanımlamanız yeterli oluyor, reducer kavramını ortadan kaldırmış oluyoruz bu şekilde. Ayrıca mobX üzerinde decorators dediğimiz babel yazım biçimini kullanarak çok tatlı bir şekilde geliştirme yapabiliyoruz. Benim tavsiyem React uygulamalarında mobX kullanmanızdan yana olacaktır.
906 |
907 | > Redux ve MobX için yapılan övgü ve eleştiriler kesinlik içeren şeyler değil sadece benim düşüncelerimdir. Projeye ve kullanım yerine göre iki kütüphane de farklı sebeplerden dolayı tercih edilebilir.
908 |
909 | ---
910 |
911 | Şu an itibariyle React.js tarafındaki temel kavramları öğrendik diyebiliriz. Bundan sonrasında daha gelişmiş işlemleri ile ilgileneceğiz. Başlangıç için hooks, ui kütüphanesi kullanımı ve api kullanımına bakacağız. İleride talepler doğrultusunda server side rendering, mobx ve refler gibi daha karmaşık konularla da devam edebiliriz.
912 |
913 | ## React Router
914 |
915 | React router ile sayfalar arasında geçiş yapabiliyoruz. Şuana kadar hep tek bir sayfa üzerinde çalıştık. Şimdi ise birden fazla sayfaya sahip olacağız ve bu sayfalar arasında geçiş yapacağız. Aslında mantık olarak yine tek bir ana bileşene sahip olacağız. Router gelen url üzerinden, belirttiğimiz sayfa deseniyle eşleşen sayfa bileşenini aktif edecek.
916 |
917 | Router için alt kısımda bahsettiğimiz "server side rendering" bölümünde next.js kütüphanesi ile de bunu daha basit bir şekilde kullanacağımızı söyleyeceğiz. Daha güzel bir çözüm için orayı da okumayı unutmayın.
918 |
919 | ```bash
920 | npm i react-router-dom --save
921 | ```
922 |
923 | Kütüphaneyi projemize ekleyerek başlayalım. Sonrasında bütün bileşenleri kapsayan bir router bileşenine ihtiyacımız var. Bunun için yeni bir bileşen oluşturabiliriz ya da App bileşenimizi kullanabiliriz.
924 |
925 | Aşağıdaki kodda Anasayfa, Profil ve Ayarlar adında bileşenlerimizin olduğunu ve bunların components klasöründen export edildiğini varsayalım.
926 |
927 | ```jsx
928 | import React from "react";
929 | import { BrowserRouter, Switch, Route } from "react-router-dom";
930 | import { Anasayfa, Profil, Ayarlar } from "./components";
931 |
932 | export default function App() {
933 | return (
934 |
935 |
936 |
937 |
938 |
939 |
940 |
941 |
942 |
943 |
944 |
945 |
946 |
947 | )
948 | }
949 | ```
950 |
951 | Sayfalar arasında geçiş yapabilmek için ise tekrar hayali bir Anasayfa bileşeni oluşturalım ve ayarlar için 3 farklı yöntemle yönlendirme sağlayalım.
952 |
953 | ```jsx
954 | import React from "react";
955 | import { Link, useHistory } from "react-router-dom";
956 |
957 | export default function Anasayfa() {
958 | return (
959 |
967 | )
968 | }
969 | ```
970 |
971 | ## UI Kütüphanesi Dahil Etmek (bootstrap vs.)
972 |
973 | Tasarımları koda dökerken ui kütühaneleri gerçekten çok işimize yarıyor. Aslında sadece ui diğer bir çok kütüphaneyi kullanıyoruz. Sonuçta React bileşen tabanlı bir sistem ve geliştiriciler tarafından hazırlanmış binlerce hazır bileşen var. Yeri geldiğinde bunları kullanmak bize zamandan ve koddan tasarruf sağlatıyor.
974 |
975 | **React üzerinde en popüler ui kütühaneler:**
976 |
977 | - Ant Design (tavsiyem)
978 |
979 | - Blueprint (typescript)
980 |
981 | - React Bootstrap
982 |
983 | - React Toolbox
984 |
985 | - React Semantic UI
986 |
987 | - Material UI
988 |
989 | 
990 |
991 | Biz örnek kullanım olarak React Bootstrap'ı seçelim ve nasıl kurulup, kullanılacağına bakalım.
992 |
993 | React Bootstrap dökümanı: [https://react-bootstrap.github.io/](https://react-bootstrap.github.io/)
994 |
995 | ```bash
996 | npm i bootstrap react-bootstrap --save
997 | ```
998 |
999 | bootstrap kütüphanesini CSS tarafı için ekledik böylece bildiğimiz grid, button, alert vs. CSS sınıflarını direkt tanımlayarak kullanabileceğiz. react-bootstrap ise daha çok çalışması için JavaScript gereken modal, dropdown, carousel gibi bileşenler için. Bu demek değil ki react-bootstrap'ın içinde button, alert ve diğer basit bileşenler yok. Yine react-bootstrap içinden bu bileşenleri de JSX olarak kullanabileceğiz.
1000 |
1001 | Npm paketlerimizi indirdikten sonra projemize bootstrap'in CSS tarafını dahil edelim. Bunu 2 yöntem ile yapabiliriz.
1002 |
1003 | 1. public/index.html dosyamıza link tag olarak CSS dosyamızı ekleriz.
1004 |
1005 | 2. index.js veya App.js (tüm bileşenleri kapsayan) bir dosyadan import ile CSS dosyasını dahil ederiz. (tavsiye)
1006 |
1007 | Eğer birinci adımı uygulayacak isek CSS dosyalarını cdn üzerinden de çağırabiliriz. Aksi halde tarayıcı üzerinden projemizdeki bir dosyaya ulaşmak için public klasöründe barınması gerektiğinden bootstrap dosyasını taşımamız gerekecek ve bu çok saçma bir hareket olacak. O yüzden eğer HTML içinde ekliyorsak cdn kullanalım.
1008 |
1009 | ```html
1010 |
1011 |
1012 |
1013 | ```
1014 |
1015 | ```jsx
1016 | // 2. yöntem (index.js)
1017 |
1018 | import 'bootstrap/dist/css/bootstrap.min.css';
1019 | ```
1020 |
1021 | Yukarıdaki yöntemlerden birini seçip uygulayın. Benim tavsiyem ikinci yöntem olacak. Eklemeyi yaptıkran sonra artık bootstrap bileşenlerini kullanabilir durumdayız.
1022 |
1023 | Örnek olması için bir button eklemesi yapalım ve bunu hem bileşen hem de CSS olarak gösterelim.
1024 |
1025 | ```jsx
1026 | import React from "react";
1027 | import { Button } from "react-bootstrap";
1028 |
1029 | function Ornek(props) {
1030 | return (
1031 |
1032 |
1033 |
1034 |
1035 |
1036 | )
1037 | }
1038 |
1039 | export default Ornek;
1040 | ```
1041 |
1042 | ## React Fragment
1043 |
1044 | React üzerinde bir bileşende JSX kodu döndürürken tek bir ana eleman içinde olmasını gerektiğini en başlarda söylemiştim. Bu yüzden kodlarımızı boş bir div içine alıyorduk. Bazı durumlarda bu div tasarımsal sorunlara yol açabilir ve gereksiz bir div olmamasını isteyebiliriz.
1045 |
1046 | Bu durumda tüm kodumuzu div ile kapsamak yerine React.Fragment ile kapsayabiliriz. Böylece DOM üzerinde ekstra bir eleman olmadan sadece Fragment içindeki nesneler aktarılır. Kullanımı ise gerçekten çok basit, div yerine React.Fragment yazacağız.
1047 |
1048 | ```jsx
1049 | import React from "react";
1050 |
1051 | function Ornek(props) {
1052 | return (
1053 |
1054 |
birinci nesne
1055 | ikinci nesne
1056 | üçüncü nesne
1057 |
1058 | )
1059 | }
1060 |
1061 | export default Ornek;
1062 | ```
1063 |
1064 | React.Fragment yazmamızın sebebi import olarak react.js kodlarını React olarak içeri aktarmamız. Fragment, React altında olduğu için bu şekilde nokta ile altında olduğunu belirttik.
1065 |
1066 | Böyle katmanlı şekilde göstermeden şu kullanımı da yapabilirdik.
1067 |
1068 | ```jsx
1069 | import React, { Fragment } from "react";
1070 | ```
1071 |
1072 | Böylece artık React.Fragment yazmak yerine Fragment yazarak kullanabiliriz. Bu kullanım biçimini sınıf tabanlı bileşenlerde "class xxx extends React.Component" yazmak yerine, dahil ederken süslü parantezler içinde Component de eklersek direkt olarak Component olarak miras alabiliriz.
1073 |
1074 | ## Hook'lara Giriş
1075 |
1076 | Şuana kadar state işlemleri yapabilmek için hep sınıf tabanlı bileşen oluşturduk. React 16.8 sürümünde gelen hook'lar fonksiyonel bileşenlerde de state kullanmamıza olanak tanıyor. Aslında sadece state değil, sınıf üzerinde yapabildiğimiz diğer işlemleri de yapmanızı sağlıyor.
1077 |
1078 | 
1079 |
1080 | ### Hook'lar ile State Kullanımı
1081 |
1082 | Vazgeçilmez örneğimiz olan sayaç örneğimiz ile hook'ları inceleyelim.
1083 |
1084 | ```jsx
1085 | import React, { useState } from "react";
1086 |
1087 | function Ornek() {
1088 |
1089 | // sayac adinda yeni bir state değişkeni tanımlayalım
1090 | const [ sayac, setSayac ] = useState(0);
1091 |
1092 | return (
1093 |
1094 |
Butona {sayac} defa tıklandı!
1095 |
1096 |
1097 | )
1098 | }
1099 |
1100 | export default Ornek;
1101 | ```
1102 |
1103 | Gördüğünüz gibi basit bir kullanımı var. State kullanımı React kütüphanesinden çağırdığımız useState fonksiyonuyla sağlıyoruz.
1104 |
1105 | Tanımlama kısmındaki sayac ve setSayac'dan birincisi değişkenimizin adını, ikincisi ise state'i güncellememizi sağlayan fonksiyonu tanımlıyor. State'imizin başlangıç değerini ise useState içine gönderdiğimiz değer tanımlıyor. Biz "0" gönderdiğimiz için sayacımız 0'dan başlayacak.
1106 |
1107 | ### Hook'lar ile Effect Kullanımı
1108 |
1109 | Az önce yaptığımız örnekten bahsetmek gerekirse sayaç state'i değiştiğinde DOM üzerinde bir güncelleme olacak ve sayfadaki sayaç değeri yenilenecektir. Bu değişim yapıldığı anda bazı kontroller veya birbirini tetikleyen başka değişiklikler de yapmak isteyebiliririz. React'ın yaşam döngüsünde gördüğümüz componentDidUpdate metodu bunun için ideal fakat bunu sadece sınıf tabanlı bileşenlerde kullanabiliyoruz.
1110 |
1111 | Bu tarz durumlarda bir değişiklik olduğunda işlem yapmak için useEffect hook'unu kullanacağız.
1112 |
1113 | Az önceki yazdığımız kodda her butona tıklandığında p etiketi içindeki yazıyı tarayıcıda gözüken title'a yazmak isteseydik ne yapabilirdik? Sayfada title'a müdahale etmek için "document.title" kullanacağız fakat bunu direkt olarak sağlayacağımız bir yer yok. Aynı örneği kopyalayarak useEffect eklemesi yapalım.
1114 |
1115 | ```jsx
1116 | import React, { useState, useEffect } from "react";
1117 |
1118 | function Ornek() {
1119 |
1120 | // sayac adinda yeni bir state değişkeni tanımlayalım
1121 | const [ sayac, setSayac ] = useState(0);
1122 |
1123 | useEffect(() => {
1124 | // her güncelleme olduğunda burası çalışacak
1125 | document.title = "Butona " + sayac + " defa tıklandı!";
1126 | });
1127 |
1128 | return (
1129 |
1130 |
Butona {sayac} defa tıklandı!
1131 |
1132 |
1133 | )
1134 | }
1135 |
1136 | export default Ornek;
1137 | ```
1138 |
1139 | Hook tarafında sadece useState ve useEffect yok. Sınıf üzerinde yapabileceğimiz şeyleri yapmamızı sağladığını söylemiştik. Şuan için hook listesi şu şekilde.
1140 |
1141 | - **Basit hook'lar:** useState, useEffect, useContext
1142 |
1143 | - **Ekstra hook'lar:** useReducer, useCallback, useMemo, useRef, useImperativeHandle, useLayoutEffect, useDebugValue
1144 |
1145 | ## API Kullanımı (axios)
1146 |
1147 | İnternet üzerinden bir bağlantı yapmak istediğimizde genel olarak REST veya SOAP üzerinden bağlantı sağlarız ve veri alışverişinde bulunuruz. Bu bağlantıyı JavaScript üzerinde bulunan fetch ile sağlayabiliriz. Fetch yerine daha kullanışlı olan api kullanımı üzerine geliştirilen kütüphaneler de mevcut. Bunların bir listesini ve karşılaştırma tablosunu görsel olarak ekleyeceğim. Ben axios kullanmayı tercih ediyorum ve kaynak üzerinde de kullanım olarak basit bir şekilde bunu göstereceğim. Siz daha önceden aşina olduğunuz (tabloda jQuery de mevcut onu görmezden gelin) diğer kütüphaneleri de kullanabilirisiniz, ama mantık olarak zaten hepsi aynı olduğundan fark etmeyecektir.
1148 |
1149 | 
1150 |
1151 | Öncelikle axios'u projemize eklemekle başlayalım.
1152 |
1153 | ```bash
1154 | npm i axios --save
1155 | ```
1156 |
1157 | API kullanımını jsonplaceholder.com üzerinde bulunan users test verisi üzerinden sağlayacağız. Basit bir şekilde gelen kullanıcı verisinden isim ve e-posta adresini okuyup sayfamızda listeleyeceğiz.
1158 |
1159 | ```jsx
1160 | import React from "react";
1161 | import axios from "axios";
1162 |
1163 | export default class Users extends React.Component {
1164 |
1165 | state = {
1166 | data: []
1167 | }
1168 |
1169 | componentDidMount() {
1170 | axios({
1171 | method: 'get',
1172 | url: 'https://jsonplaceholder.typicode.com/users',
1173 | }).then(res => {
1174 | this.setState({data: res.data});
1175 | });
1176 | }
1177 |
1178 | render() {
1179 | return (
1180 |
1196 | )
1197 | }
1198 | }
1199 | ```
1200 |
1201 | Örnekte data isminde bir state oluşturduk ve varsayılan değerine boş bir dizi verdik. Render kısmında da data'nın uzunluğu var ise ul > li şeklinde datayı dönerek listelemesini yok ise bir bekleme mesajı yazdırmasını sağladık. Böylelikle ilk başta veri olmadığı için ekranda bekleyiniz şeklinde yazı gelecek ve veri yüklendiğinde otomatik olarak liste ekrana gelecek.
1202 |
1203 | Biz burada GET metodu için bir örnek verdik. axios içerisinde POST, DELETE, PUT vb. diğer bütün metodları da kullanabilirsiniz. İstek içerisinde headers ve data belirterek ekstra veri alışverişi de sağlayabilirsiniz.
1204 |
1205 | Axios üzerinde yapabileceğiniz işlemler kendi readme'sinde mevcut onu da aşağıdaki linkten inceleyebilirsiniz.
1206 |
1207 | Axios dökümanı: [https://github.com/axios/axios](https://github.com/axios/axios)
1208 |
1209 | ---
1210 |
1211 | Hazır konu REST Api kısmına gelmişken @ahmetkorkmaz3 ile birlikte geliştirdiğimiz github üzerindeki açık kaynaklı rest api client uygulaması olan **guvercin**'i de inceleyebilirsiniz. Uygulama windows, linux ve mac üzerinde kullanılabilir durumda.
1212 |
1213 | Hatta linux üzerinden hızlı bir şekilde snap üzerinden yükleyebilirsiniz.
1214 |
1215 | ```bash
1216 | sudo snap install guvercin
1217 | ```
1218 |
1219 | Guvercin uygulamasını yüklemek veya kaynak kodlarını incelemek için : [https://github.com/orcuntuna/guvercin](https://github.com/orcuntuna/guvercin)
1220 |
1221 | 
1222 |
1223 | ---
1224 |
1225 | ## Döngülerde Key Kullanımı
1226 |
1227 | Araya küçük bir reklam girmiş gibi oldu ama bir önceki örnekte aslında key kullanımını zaten yaptık. Eğer bir döngü ile listeleme yapıyorsanız listelediğiniz elemana key parametresini de eklemeniz gerekiyor. Eğer az önceki örnekte li elemanına key eklemeseydiniz geliştirici konsolunda şu hatayı görecektiniz.
1228 |
1229 | > Warning: Each child in a list should have a unique "key" prop.
1230 |
1231 | Uyarıdan da görüldüğü gibi sadece key parametresi olması yetmiyor ayrıca bu key parametreleri her elemana özgün olup tekrar etmemeli.
1232 |
1233 | Bunu yapmamızın sebebi React sayfalarda değişiklikler olduğunda bu elemanlara bir kimlik atıyor. Böylece hangi elemanın değiştini, silindiğini veya yeni bir eleman eklendiğini anlayabilecek ve daha hızlı işlem yapacak.
1234 |
1235 | **Önemli:** Key değerleri özgün olması gerektiği gibi veri tipi de string olması gerekiyor.
1236 |
1237 | Bir önceki örnekte bizim verimizdeki id'lerimiz integer olarak bulunuyordu. Ben yanına "user-" şeklinde bir ön ek koyarak bunu hem bu liste için özgün bir hale çevirdim hem de string türüne çevirmiş oldum. Size de bu şekilde kullanmanızı tavsiye ederim. Başka liste elemanları ile denk gelme ihtimalini de yoketmiş olursunuz.
1238 |
1239 | ## Server Side Rendering
1240 |
1241 | React üzerinde yazdığımız kodlar tarayıcı üzerinde sayfa açıldığıda render edilir ve ekrana çıktı üretilir. Bu yüzden geliştirci konsolundan sayfanın kaynağını incele dediğinizde yazdığınız kodları göremezsiniz. Göreceğiniz içerik public/index.html dosyasının içeriği ve ekstra olarak bundle haline getirilmiş JavaScript dosyaları.
1242 |
1243 | 
1244 |
1245 | **Peki bu ne gibi bir soruna yol açıyor?**
1246 |
1247 | Birincil olarak en büyük problem SEO tarafında. Google sayfaları index'leyip veritabanına kaydeder ve sonrasında arama sonuçlarında görünür olmasını sağlar. Buradaki en büyük etkenler title, description ve sayfa kaynak kodunda bulunan metinlerdir. Bizim içeriğimiz client tarafında render edildiği için Google tüm sayfalarda boş bir index.html görecek ve bunu sağlıklı bir şekilde index'lemeyecektir. Eğer doğrudan erişme kapalı bir site değilsek ve google arama sonuçlarında çıkmazsak bu gerçekten büyük bir problem yaratır.
1248 |
1249 | Bunu Server Side Rendering dediğimiz yöntem ile çözebiliyoruz. Mevcut React kodlarımız build alınarak statik HTML sayfalar oluşturuluyor. Böylelikle yazdığımız kodların HTML haline dönüştürülmüş versiyonunu yayımlıyoruz ve örümcekler (google ve diğer arama motorlarının sayfaları dolaşan yazılımlarına verilen isim) sitemizin içeriğini anlayabiliyor ve indexliyor.
1250 |
1251 | Bahsettiğimiz build kısmı kullandığımız create-react-app oluşturucusunda da mevcut fakat yine bir bundle üretiyor ve kaynak kodu statik olarak oluşturmuyor.
1252 |
1253 | 
1254 |
1255 | Bu sebeple kullanabileceğimiz en iyi çözüm React üzerine server side rendering uygulamalar geliştirmek için hazırlanmış **next.js** kütüphanesi olacaktır. Next.js içinde dahili bir router bulunduğundan ekstra bir router kütüphanesi kullanmamıza da gerek kalmayacak. Ayrıca create-react-app üzerinde eject işlemi yaparak yapabildiğimiz konfigurasyonları da yapmamızı sağlıyor. Bu yüzden basit ve tatlı bir kütüphane.
1256 |
1257 | Şuan için next.js kütüphanesinin kullanımına girmeyeceğim, ileriki zamanlarda bir yazı ya da video olarak kullanımı hakkında paylaşım yapabilirim.
1258 |
1259 | ## Build Almak (create-react-app)
1260 |
1261 | package.json dosyasından da görebileceğiniz üzere create-react-app ile oluşturduğunuz bir projeyi canlıya almak için "npm run build" komutunu kullanıyorsunuz.
1262 |
1263 | ```bash
1264 | npm run build
1265 | ```
1266 |
1267 | İşlem tamamlandığında proje dizininde build adında bir klasör oluşacak. static klasörü içerisinde bundle halindeki CSS ve JavaScript dosyaları bulunuyor. Projenizde public klasörüne koyduğunuz dosyalar ise direkt olarak build klasörü içine geliyor ve böylelikle sunucu tarafında erişilebilir oluyor. Sunucuyu aktarımı sağladığınız zaman gelen bir istek olduğunda index.html dosyası çalışacak ve bundle dosyaları ile projenizi kullanıcıya render ederek gösterecek.
1268 |
1269 | ## Çoklu import/export Kullanımı (webpack)
1270 |
1271 | Başlık olarak ne yazacağıma tam olarak karar veremedim. Vereceğim örnek ile daha iyi anlaşılacağını düşünüyorum. Hook'lar ve fragment kısmında süslü parentezlerin arasında bileşenleri import ettik. Router kullanımı kısmında da hayali sayfalarımızı çoklu şekilde "./components" üzerinden import ettik.
1272 |
1273 | Hatırlamayanlar için flashback:
1274 |
1275 | ```jsx
1276 | import { Anasayfa, Profil, Ayarlar } from "./components";
1277 | ```
1278 |
1279 | Bunu kullandım fakat bu sayfaları nasıl bu şekilde dışarı aktaracağımızı göstermedim. Components dediğimiz yer aslında bizim src dizinimizin içinde ek bir dizin. Bileşenlerimizi bu dzin içinde topluyoruz ki diğer materyaller ile karışıklık olmasın. Bu şekilde çağırım yapabilmek için dizin yapımız şu şekilde olacak:
1280 |
1281 | ```bash
1282 | └───src
1283 | └───components
1284 | index.js
1285 |
1286 | Anasayfa.js
1287 | Ayarlar.js
1288 |
1289 | Profil.js
1290 | ```
1291 |
1292 | Gördüğünüz gibi 3 adet sayfa bileşenimizin haricinde bir adet de index.js adında dosya mevcut. import işlemini yaparken nasıl dosya adını yazarken sonuna ".js" eklememiz gerekmiyorsa benzer bir şekilde bir dizin ismi yazdığımız zaman da otomatik olarak o dizindeki index.js dosyasını okuyor. Aslında biz "./components/index.js" veya "./components/index" de yazabilirdik, hepsi aynı dosyanın farklı yazılış şekilleri.
1293 |
1294 | **Peki index.js içeriğimiz nasıl olacak?**
1295 |
1296 | Index.js dosyamızda yapacağımız işlem öncelikle bileşenlerimizi tek tek içeri aktarmak ve sonrasında toplu bir şekilde dışarı aktarmak olacak. Böylelikle tek bir dosya üzerinden bütün bileşenlerimize ulaşabileceğiz.
1297 |
1298 | ```jsx
1299 | // index.js
1300 |
1301 | import Anasayfa from "./Anasayfa";
1302 | import Ayarlar from "./Ayarlar";
1303 | import Profil from "./Profil";
1304 |
1305 | export { Anasayfa, Ayarlar, Profil }
1306 | ```
1307 |
1308 | Burada çoklu aktarım yaparken "export" yanında "default" anahtar kelimesini kullanmadık. Bu kelimenin anlamı o dosyada tek bir dışa aktarma yapılacağıdır, bu dışarı aktarılan bileşeni içe aktarırken herhangi bir isimle kullanabilirsiniz. Fakat çoklu aktarımlarda içeri aktarırken aktardığımız bileşen ismini kullanmak durumundayız. Eğer farklı bir isimde kullanmak istiyorsak "as" anahtarını kullanabiliriz.
1309 |
1310 | ```jsx
1311 | import { BrowserRouter as Router } from "react-router-dom";
1312 | ```
1313 |
1314 | Örnekte görüldüğü gibi artık BrowserRouter bileşenini Router olarak kullanacağız.
1315 |
1316 | ---
1317 |
1318 | ## Kapanış
1319 |
1320 | Şuan için genel olarak React konularını bitirdik. Eğer eksik veya hatalı gördüğünüz bir kısım var ise öncelikle bu repoyu forklayıp sonrasında kendinize göre düzenleme yaptıktan sonra pull request gönderirseniz, kaynağa siz de katkı sağlamış olursunuz.
1321 |
1322 | Eğer kaynağı beğenerek okuduysanız ve bir kahve ısmarlamak isterseniz aşağıdan ko-fi profilime ulaşabilirsiniz.
1323 |
1324 | [](https://ko-fi.com/tunaorcun)
1325 |
1326 | Bu kaynak [Orçun Tuna](https://github.com/orcuntuna) tarafından hazırlanmıştır ve en güncel hali [https://github.com/orcuntuna/react-turkce-kaynak](https://github.com/orcuntuna/react-turkce-kaynak) üzerinden ücretsiz bir şekilde okunabilir durumdadır. PDF ve HTML versiyonlarını da github üzerinden edinebilirsiniz.
1327 |
--------------------------------------------------------------------------------