├── .gitignore ├── README.md └── ornekler ├── Makefile ├── build ├── 01_merhaba_dunya.js ├── 02_selamlama.js ├── 03_selamlama_props.js ├── 04_sayac.js ├── 05_sayac_gerisayim.js └── 06_sayaclar.js ├── css ├── app.css └── pure.css ├── index.html ├── libs ├── react.js └── underscore.js ├── ornek1.html ├── ornek2.html ├── ornek3.html ├── ornek4.html ├── ornek5.html ├── ornek6.html └── src ├── 01_merhaba_dunya.js ├── 02_selamlama.js ├── 03_selamlama_props.js ├── 04_sayac.js ├── 05_sayac_gerisayim.js └── 06_sayaclar.js /.gitignore: -------------------------------------------------------------------------------- 1 | .module-cache 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React.js'e Giriş 2 | 3 | Sunumlar şu adreste: https://speakerdeck.com/ustun/react-dot-jse-giris 4 | 5 | React.js Facebook ve Instagram tarafından geliştirilmiş bir kullanıcı arayüzü 6 | kütüphanesidir. Kullanıcı arayüzü geliştirmede MVC, yani model-view-controller 7 | (model-görüntü-kontrolcü) tasarım deseni çok fazla kullanılır. React'in temel 8 | görevi buradaki View, yani görüntü kısmını düzenlemek olarak düşünülebilir; ama 9 | aslında sadece bir görüntü katmanından çok daha fazlasıdır. 10 | 11 | ## Tarihçe 12 | 13 | React'in tarihçesinden hızlıca bahsedecek olursak, Facebook Instagram'ı 14 | bünyesine kattığında Instagram'ın bir web sitesi yoktu, sadece mobil 15 | uygulamaları vardı. Bir web sitesi geliştirmek isteyen Instagram mühendisleri 16 | Facebook'un yorumlar, reklamlar gibi bazı bileşenlerinde kullandığı dahili 17 | kütüphaneyi kullanmak istedi. Yapılan çalışma sonucu kütüphanenin Facebook kod 18 | tabanındaki diğer bağımlılıkları kaldırıldı ve kütüphane 2013 Mayıs'ında 19 | JSConf'ta açık kaynak olarak dünyaya tanıtıldı. 20 | 21 | React.js'e ilk başta oldukça şüpheyle yaklaşıldı, hatta tanıtıldığı konferansta 22 | Facebook'un piyasadaki bütün bilinen doğruları sorguladığı, JS ile HTML'i çorba 23 | yaptığı şeklinde alay konusu bile oldu. Ancak sonraki dönemde bu kütüphanenin 24 | karmaşık sistemleri basitleştirdiği ve hızlandırdığı birçok firma tarafından 25 | fark edildi ve Netflix, Airbnb, Khan Academy gibi pek çok firma arayüzlerinde 26 | React.js'e geçti. 27 | 28 | ## Büyük Uygulamalarda Arayüz Geliştirmenin Zorlukları 29 | 30 | React'in temel hedefini şu şekilde özetleyebiliriz: Verinin zaman içerisinde 31 | değiştiği büyük uygulamaları basit ve hızlı bir şekilde geliştirmek. 32 | 33 | Çoğu durumda arayüz geliştirmek oldukça zordur, peki buradaki asıl zorluk nedir? 34 | Örneğin sunucu tabanlı bir web sistemi geliştirdiğimizi 35 | düşünelim. Veritabanından verileri çektik, daha sonra bir taslak, yani template 36 | aşamasından geçirip HTML çıktısını oluşturduk. Çoğu uygulamada, örneğin PHP'de, 37 | Django'da ya da Rails'te bu oldukça kolay bir işlemdir. Bu işlemi veriyi alan ve 38 | sonuç olarak HTML üreten bir fonksiyon olarak soyutlayabiliriz. 39 | 40 | Halbuki işler istemci tabanlı, yani clientside bir arayüz geliştirmeye 41 | geldiğinde oldukça zorlaşır. Buradaki zorluğun sebebi kullanılan dil olan 42 | JavaScript midir? 43 | 44 | Aslında birkaç yıl öncesine kadar çoğu kişinin kanısı bu yöndeydi. Bilindiği 45 | gibi JavaScript dili Brendan Eich tarafından yalnızca 10 gün içinde, deyim 46 | yerindeyse yangından mal kaçırırcasına tasarlanmış bir programlama dili. Bu 47 | nedenle dilde hala giderilmeye çalışılan bazı hatalar ve gariplikler var. 48 | 49 | Ancak Douglas Crockford'un JavaScript the Good Parts kitabında anlattığı üzere 50 | bu 10 gün içerisinde Brendan Eich, görüntü olarak C'ye benzese de altında bir 51 | Lisp yatan, çok esnek, fonksiyonel bir dil yaratmıştı. Zaten dildeki hatalar da 52 | CoffeeScript, ES6 gibi diller aracılığıyla ve underscore gibi fonksiyonel 53 | kütüphaneler sayesinde zaman içerisinde oldukça azaltıldı. 54 | 55 | Peki arayüz geliştirmedeki ana zorluk dil değilse nedir? Büyük uygulamaları 56 | incelediğimizde ve sunucuda oluşturulan arayüzleri tarayıcıdaki arayüzlerle 57 | karşılaştırdığımızda asıl zorluğun zaman içerisinde değişen veri yönetimi 58 | olduğunu görürüz. Sunucu taraflı bir uygulamayı düşünelim, veriyi veritabanından 59 | çektik, taslağa gönderdik. Bu esnada veriyi aslında değişmeyen bir yapı olarak 60 | düşünebiliriz. 61 | 62 | Ancak istemci tarafında işler bu şekilde ilerlemez. Diyelim kullanıcı tarayıcıyı 63 | açtı, uygulamayı başlattı; işte bu noktadan sonra uygulamadaki veri sürekli 64 | değişim halindedir ve uygulamadaki görüntü ile verinin senkronizasyon sorunu 65 | başlar. Hele aynı veri görüntünün birden fazla yerinde gösteriliyorsa işler daha 66 | da karmaşıklaşır. 67 | 68 | Örneğin bir chat uygulaması düşünelim. Şu an çevrimici olan arkadaşlarımızı ve 69 | toplam kaç arkadaşımızın çevrimiçi olduğunu göstersin. Diyelim ki bir 70 | arkadaşımız daha çevrimiçi hale geldi. Burada herhangi bir arayüz kütüphanesi 71 | kullanmıyorsak yapmamız gereken iki değişiklik var: Öncelikle yeni gelen 72 | arkadaşımızın ismini listeye eklemeli, daha sonra da tepedeki arkadaş sayısını 73 | bir artırmalıyız. Yani bir anlamda görüntüde kısmi bir değişiklik, bir yama 74 | yapmalıyız. Bu basit bir örnek gibi görünse de arayüz geliştirmedeki sorunların 75 | birçoğu işte bu veri ve görüntü arasındaki köşe kapmaca yüzünden yaşanmakta; 76 | veri değiştiğinde programcı görüntüdeki bir veri değiştirmeyi unutmakta. 77 | 78 | ## React'in Temel Felsefesi: Görüntüyü her seferinde yeniden oluşturmak 79 | 80 | İşte bu noktada React'in arayüz oluşturmadaki birinci ve temel felsefesi devreye 81 | giriyor: Verideki her değişimde görüntüyü yamamak yerine sil baştan 82 | oluşturalım. Yani görüntü yapacağımız değişiklikleri düşünmek yerine sadece 83 | veride bir değişiklik yapalım, görüntü sanki sayfayı yeniden yüklemişiz gibi 84 | sıfırdan oluşturulsun. Bu şekilde veri ve görüntü arasında hiçbir zaman bir 85 | anlaşmazlık olmasın. 86 | 87 | Tabii kulağa çok hoş geliyor, ama bu konuda kafanızda bazı soru işaretleri olmuş 88 | olabilir: Diyelim 100 kişilik bir listemiz var, veriye bir kişi daha ekledik, 89 | 101 kişilik yeni bir liste oluşturmamız gerekmekte. Bunu naif bir şekilde 90 | yaparsak, elimizde halihazırda bulunan 100 kişilik listeyi çöpe atacağız ve 91 | sıfırdan 101 kişilik bir liste oluşturacağız. Bu oldukça yavaş olmaz mı? 92 | 93 | React'in kütüphane olarak devreye girdiği yer tam da bu nokta. React, kullanıcı 94 | olarak sizin sadece veriye ve o verinin nasıl görüntüleneceğine odaklanmanızı 95 | sağlarken arkaplanda görüntüdeki değişimin en etkin biçimde yapılmasını 96 | sağlamakta. Yani 101 kişilik yeni listeyi oluştururken sizin yerinize görüntüde 97 | yapılması değişiklikleri hesaplamakta ve sadece bu değişiklikleri görüntüye 98 | uygulamakta. İşte React'in bunu yaparken kullandığı yönteme de sanal DOM 99 | (virtual DOM) diyoruz. React görüntü elemanlarını sanal DOM adı verilen bir veri 100 | yapısında tutuyor ve değişiklik olduğunda bu veri yapısını güncelleyerek 101 | görüntüde toplu değişiklikler yapiyor. Bu yöntemle React verideki değişiklikler 102 | sonucunda optimum olarak hangi HTML elemanlarının eklenip çıkarılacağına kendisi 103 | karar veriyor. 104 | 105 | Dolayısıyla React'in birinci temel kuralını şu şekilde özetleyebiliriz: 106 | Kullanıcı temel olarak arayüzün arkasındaki veri yapısına ve değişikliklerine 107 | odaklanmalı ve bu verinin nasıl görüntüleneceğini yalnızca bir kez tanımlamalı. 108 | 109 | ## React'in İkinci İlkesi: Bileşenler 110 | 111 | Şimdi gelelim React'in ikinci temel ilkesine. React'e göre arayüz geliştirirken 112 | temel hedefimiz aslında bileşen oluşturmak olmalı; yani elimizdeki arayüzü 113 | bileşenlere ayırmalı ve bileşenler cinsinden analiz etmeliyiz. Elimizde 114 | halihazırda bir HTML taslağı olduğu düşünelim, örneğin bir adres defteri. Bunu 115 | gerçekleştirmek için bunu küçük bileşenlere ayıralım. Örneğin tepedeki bileşen 116 | bir arama bileşeni, aşağıdaki her bir harfe ait kişiler bir `Sayfa` bileşeni, 117 | her bir adres satırı ise birer `Adres` bileşeni olarak düşünülebilir. 118 | 119 | İşte bu yaptığımız temelde bir soyutlama işlemi, elimizdeki küçük Lego 120 | bloklarından daha büyük Lego blokları yapıyoruz ve en nihayetinde en büyük Lego 121 | bloku olan uygulamamızı kuruyoruz. 122 | 123 | Bunu programlamada birden fazla cümleden fonksiyon oluşturmaya 124 | benzetebiliriz. Bu fonksiyonları kullanan yeni üst fonksiyonlar oluşturduğumuz 125 | gibi bileşenleri kullanan üst bileşenler oluşturabiliriz. Bu şekilde elimizde 126 | yeniden kullanılabilir (reusable), birbiri içine geçebilen (composable), nasıl 127 | kullanılacağı tanımlanmış küçük ve hatasız birimler oluşacak. React 128 | terminolojisinde temelde kullanılan bu yapıya component, yani bileşen denmekte. 129 | 130 | ### Basit Bir Bileşen: MerhabaDunya 131 | 132 | Bileşenlerin nasıl oluşturulduğuna ve kullanıldığına bir örnek verelim. Bir 133 | React component'i oluşturmak için `React.createClass` metodunu bir nesne 134 | (object) ile çağırıyoruz. Bileşenin nasıl görüneceğini de bu nesnenin `render` 135 | metodunda tanımlıyoruz. Mesela, `MerhabaDunya` adında bir bileşen tanımlayalım. 136 | 137 | ```js 138 | var MerhabaDunya = React.createClass({ 139 | render: function () { 140 | return
Merhaba Dunya
; 141 | } 142 | }) 143 | ``` 144 | 145 | Burada React aslında sadece JavaScript dilini kullanıyor, herhangi bir taslak 146 | dili değil bu. Normal JavaScript'ten tek farkı JSX adında HTML sözdizimine 147 | benzeyen yapıları kullanmamıza izin vermesi. JSX isteğe bağlı kullanılan bir 148 | araç, tek yaptığı bu sözdizimi alıp bu etiketleri JavaScript fonksiyonlarına 149 | çevirmek. Yani `
Merhaba Dünya
` deyimini `React.createElement("div", null, "Merhaba Dünya")` 150 | fonksiyonuna dönüştürmekte. 151 | 152 | Bu bileşeni tanımladıktan sonra sayfamızda göstermek için sayfada halihazırda 153 | bulunan boş bir elemana monte etmemiz gerekmekte. Bunun için de `React.render` 154 | komutunu kullanmaktayız, örneğin bu bileşeni `body` elemanına monte etmek için 155 | `React.render(, document.body)` kullanıyoruz. Monte edeceğimiz 156 | eleman `body` yerine sayfada bulunan başka bir HTML elemanı da olabilirdi. 157 | 158 | Gördüğünüz gibi HTML'de tanımlı olan `div` bileşenini kullanarak `MerhabaDunya` 159 | adında yeni bir bileşen oluşturduk ve artık bunu sanki HTML'de bu şekilde bir 160 | bileşen varmış gibi kullanabilmekteyiz. 161 | 162 | ### Karmaşık Bir Bileşen: Selamlama 163 | 164 | Şimdi bu işlemi bir adım ileri götürelim, bu basit bileşeni kullanarak daha 165 | büyük bir bileşen oluşturalım. Örneğin, iki kere "Merhaba Dünya" diyecek bir 166 | `Selamlama` bileşeni oluşturalım. `Selamlama` adlı bileşeni oluşturmak için 167 | yapmamız gereken `React.createClass` içerisine `MerhabaDunya` bileşenini iki kez 168 | kullanan bir `render` metodu yazmak. Daha sonra `Selamlama` bileşenini yine 169 | `React.render` ile `body` elemanına monte edebiliriz. 170 | 171 | ```js 172 | var Selamlama = React.createClass({ 173 | render: function () { 174 | return ( 175 |
176 | 177 | 178 |
) 179 | } 180 | }) 181 | ``` 182 | 183 | Gördüğünüz gibi artık `MerhabaDunya` bileşenini başka bir bileşen içerisinde 184 | yeniden kullanabiliyoruz. Şimdi bunu bir adım ileri götürelim, diyelim ki 185 | `MerhabaDunya` bileşeni parametre olarak selamlayacağı kişinin ismini bir 186 | parametre olarak alsın ve bu kişinin ismini görüntülesin. 187 | 188 | Fonksiyonların giriş parametrelerine benzer bir şekilde React bileşenleri de 189 | `props` adında bir nesne içerisinde parametre kümesi alabilir ve bu 190 | parametrelere `props` üzerinden `render` metodunda erişebilir. `MerhabaDunya` 191 | bileşenini bu şekilde yeniden yazalım: 192 | 193 | ```js 194 | var MerhabaDunya = React.createClass({ 195 | render: function () { 196 | return
Merhaba {this.props.isim}
197 | } 198 | }) 199 | ``` 200 | 201 | Buradaki { } (süslü parantezler) yine React'in JSX aracıyla JavaScript'e yaptığı 202 | bir ekleme, alt tarafta aslında parantezin icindekiler fonksiyon parametresine 203 | dönüşmekte. Yani `
Merhaba {this.props.isim}
` yerine `React.createElement("div", null, 204 | "Merhaba", this.props.isim)` de yazabilirdik. 205 | 206 | Şimdi de `Selamlama` bileşenimizi `MerhabaDunya` bileşenine isim parametresini aktaracak şekilde yeniden yazalım: 207 | 208 | ```js 209 | var Selamlama = React.createClass({ 210 | render: function () { 211 | return
212 | 213 | 214 |
215 | } 216 | }) 217 | ``` 218 | 219 | İşte bu noktada artık `MerhabaDunya` adında yeniden kullanılabilir ve arayüzü, 220 | yani giriş degişkenleri tam olarak belirlenmiş bir çocuk bileşenimiz oldu. 221 | 222 | ### Veri değişimi 223 | 224 | React'in temel felsefesinden bahsederken React'in asıl öneminin verinin 225 | değiştiği uygulamaları yönetmek olduğunu söylemiştik. Şu ana kadar verdiğimiz 226 | örneklerde veri hep sabit olduğu için bunu henüz görmedik. Verideki değişimi 227 | örneklemek için bir Sayaç bileşeni düşünelim. 228 | 229 | Sayaç bileşenindeki değişkenleri düşünecek olursak tek değişkenimiz sayaç adında 230 | bir sayı. React'te bileşen ait değişkenler `state` adında bir nesnede 231 | toplanmakta. Yani nasıl ki `props` adında tepeden çocuk bileşene gönderilen 232 | parametrelerin toplandığı bir nesne var, çocuk bileşendeki değişimleri izlemek 233 | için de `state` adında bir nesne bulunmakta. Bu `state`'in ilk değerini vermek 234 | için yazmamız gereken bileşen metodu ise `getInitialState`. Bunu yaptıktan sonra 235 | artık bu state değişkenine `render` içerisinde erişebiliyoruz. 236 | 237 | ```js 238 | var Sayac = React.createClass({ 239 | getInitialState: function () { 240 | return {sayac: 0}; 241 | }, 242 | 243 | render: function () { 244 |
Sayaca {this.state.sayac} kez tıkladınız
245 | } 246 | }) 247 | ``` 248 | 249 | Şimdi sayacı artıracak bir de düğme ekleyelim. 250 | 251 | ```js 252 | var Sayac = React.createClass({ 253 | getInitialState: function () { 254 | return {sayaç: 0}; 255 | }, 256 | 257 | render: function () { 258 | return ( 259 |
260 | Sayaca {this.state.sayac} kez tıkladınız 261 | 262 |
); 263 | } 264 | }) 265 | ``` 266 | 267 | Amacımız bu düğmeye her tıkladığımızda sayacı bir artırmak. Bunun için sayaç'a 268 | bir `onClick` handler fonksiyon eklememiz ve bu fonksiyonda `state`'teki sayacı 269 | bir artırmamız gerekmekte. 270 | 271 | ```js 272 | var Sayac = React.createClass({ 273 | 274 | getInitialState: function () { 275 | return {sayac: 0}; 276 | }, 277 | 278 | artir: function () { 279 | // Buraya ne yazmalıyız? 280 | }, 281 | 282 | render: function () { 283 | return ( 284 |
285 | Sayaca {this.state.sayac} kez tıkladınız 286 | 287 |
; 288 | } 289 | }) 290 | ``` 291 | 292 | İşte burada React'in `state`'e diğer birçok kütüphaneye göre farklı bakış açısı 293 | devreye giriyor. React'te yapacağınız her veri değişimini mutlaka `setState` 294 | denilen bir metod üzerinden yapmanız gerekiyor, bu şekilde React sistemde bir 295 | şeylerin değiştiğini ve `render` metodunu yeniden çalıştırması gerektiğini 296 | anlıyor. 297 | 298 | ```js 299 | var Sayac = React.createClass({ 300 | getInitialState: function () { 301 | return {sayac: 0}; 302 | }, 303 | 304 | artir: function () { 305 | var suAnkiSayac = this.state.sayac; 306 | this.setState({sayac: suAnkiSayac + 1}); 307 | }, 308 | 309 | render: function () { 310 | return ( 311 |
312 | Sayaca {this.state.sayac} kez tıkladınız 313 | 314 |
) 315 | } 316 | }) 317 | ``` 318 | 319 | Örneğin AngularJS ile karşılaştıracak olursak AngularJS'te `setState` benzeri 320 | bir şey yok, doğrudan değişkeni değiştiriyorsunuz, bu nedenle AngularJS'in 321 | sayfada bir değişiklik olup olmadığını anlamak için sürekli digest loop 322 | (sindirim döngüsü) adı verilen kod parçası gerekmekte. Bu döngü de büyük 323 | uygulamalarda performans sorunlarına yol açıyor, sistemin neyi ne zaman 324 | değiştireceğini anlamayı güçleştiriyor. 325 | 326 | React'te ise `state` değişiklikleri `explicit`, yani açık seçik belirtilmiş 327 | durumda. React'in felsefesine göre veri değişiklikleri bir uygulamadaki en 328 | önemli zorluğu oluşturmakta, bu nedenle her türlü değişiklik mutlaka açık seçik 329 | `setState` üzerinden yapılmakta. 330 | 331 | Şimdi sayaç uygulamamızı biraz geliştirelim, örneğin 0'dan ileri doğru sayarken 332 | aynı zamanda da 10'dan 0'a doğru bir gerisayım yapsın; ama bu iki sayı birbiri 333 | ile tamamen bağlantılı olsun. Yani sayaca 3 kez tıklarsak "3 kez tıkladınız, 7 334 | kez daha tıklayın" desin. Şimdi burada kaç farklı değişken kullanmamız 335 | gerekmekte? İşte React uygulamaları geliştirirken kendimize sürekli sormamız 336 | gereken soru bu olacak: Veriyi nerede ve nasıl saklamalıyım? 337 | 338 | Bu uygulamada iki farklı veri görüntülenecek olsa da aslında kaynakta sadece tek 339 | sayaç değeri olduğunu görmeliyiz. Bu nedenle `state`'te sadece kaç kez 340 | tıklandığı değerini tutmamız yeterli. İşte React uygulamalarında sıklıkla 341 | düşünmemiz gereken önemli noktalardan biri de yine bu kaynak veri ve bu veriden 342 | oluşturulan işlenmiş veri konusu. Burada tek bir kaynak veri var; ancak iki 343 | farklı işlenmiş veri bulunmakta. `State`'te sadece kaynak veriyi tutmalı, 344 | işlenmiş verileri `render` metodunda anlık olarak hesaplatmalıyız. 345 | 346 | Bu değişiklikle Sayaç bileşenimizi yeniden yazalım: 347 | 348 | ```js 349 | var Sayac = React.createClass({ 350 | getInitialState: function () { 351 | return {sayac: 0}; 352 | }, 353 | 354 | artir: function () { 355 | var suAnkiSayac = this.state.sayac; 356 | this.setState({sayac: suAnkiSayac + 1}); 357 | }, 358 | 359 | render: function () { 360 | return ( 361 |
362 | Sayaca {this.state.sayac} kez tıkladınız. 363 | {10 - this.state.sayac} kez daha tıklamalısınız. 364 | 365 |
366 | ); 367 | } 368 | }) 369 | ``` 370 | 371 | Gördüğünüz gibi `render` metodumuz görüntümüzün uygulamanın her anında nasıl 372 | görüneceği hakkında bize doğru bilgi veriyor. Yani render sadece ilk anda 373 | oluşturulan, sonra elle yama yapılması gereken bir görüntü sağlamıyor, her zaman 374 | doğru görüntü verecek bir sonuç veriyor. 375 | 376 | ### Ana Bileşen-Çocuk Bileşen Haberleşmesi 377 | 378 | Son olarak da çocuk bileşenlerin ana bileşen ile nasıl haberleşeceğine göz 379 | atalım. Burada da örneğin iki farklı sayacımız bulunsun, birine tıkladığımızda 380 | hem kendi değerini artırsın, hem de diğer sayacın değerini bir azaltsın. Şimdi 381 | burada düşünmemiz gereken konu şu: Veriyi, yani `state`'i nerede saklamalıyız? 382 | Çocuk bileşenlerin kendilerine ait birer `state`'i mi olsun, yoksa ana bileşen her 383 | iki `state`'i de kendisinde tutup bunları parametre olarak çocuklara mı aktarsın? 384 | 385 | Bu soruya döneceğiz, ama bir de chat uygulamasına dönüp aynı soruyu orada 386 | soralım: Burada arkadaş listesi hangi bileşende tutulmalı, ana bileşende mi, 387 | çevrimiçi sayısını gösteren bileşende mi, yoksa arkadaşların isimlerinin 388 | gösterildiği bileşende mi? Aynı veriye hem isim listesinde, hem de sayı 389 | bileşeninde gereksinim duyulduğu için bu verinin en tepede tutulup aşağıya doğru 390 | aktarılması en mantıklısı. 391 | 392 | Sayaç uygulamasına dönelim, burada da verinin ana bileşende tutulup çocuklara 393 | bir parametre olarak aktarılması daha mantıklı. Bunun bir güzel yanı da tüm 394 | değişkenlerin veritabanı mantığına benzer şekilde merkezi bir yerde 395 | toplanması. Bu sayede çocuk bileşenler verinin yönetimi konusuyla çok 396 | ilgilenmemekte, basit veri gösterici bileşenlere dönüşmekte. 397 | 398 | Peki bu durumda çocuk bileşenler verinin değişmesi gerektiğini ana bileşene 399 | nasıl haber verecek? İşte bu noktada parametre olarak çocuklara aktarılan 400 | callbackler ya da event handler'lar devreye giriyor. Çocuk bileşenlere ana 401 | bileşenden önemli bir olay olduğunda çalıştırması gereken kod bir parametre 402 | olarak aktarılıyor. Çocuk bileşen çalışacak kodun içeriğini bilmek zorunda 403 | değil, hatta bilmemesi daha da iyi, tek yapması gereken tepedeki bileşenden 404 | gelecek fonksiyonu çağırması gerektiği. 405 | 406 | Dolayısıyla React'teki veri akışını şu şekilde özetleyebiliriz: Veri tepeden 407 | aşağı doğru tek yönlü akar, aşağıdaki bileşenler değişiklikleri tepeye geri 408 | arama (callback) fonksiyonları ile haber verir, bu haber ile tepedeki bileşenler 409 | veriyi değiştirir ve yeni veriyi tepeden aşağı aktarır. React de veri 410 | değişikliğini fark ederek veri ile görüntüyü senkronize eder. 411 | 412 | Şimdi bu metodolojiyi kullanarak iki sayaçlı uygulamamızı yazalım, öncelikle 413 | görmemiz gereken artık sayaçların değerlerini `state`'ten değil `props`'tan 414 | aldıkları ve düğmelere tıklandığında tepeden hangi kod aktarılırsa onun 415 | çalıştırıldığı: 416 | 417 | ```js 418 | var Sayac = React.createClass({ 419 | 420 | render: function () { 421 | return ( 422 |
423 | Sayaca {this.props.sayac} kez tıkladınız. 424 | {10 - this.props.sayac} kez daha tıklamalısınız. 425 | 426 |
); 427 | } 428 | }); 429 | ``` 430 | 431 | ```js 432 | var Sayaclar = React.createClass({ 433 | getInitialState: function () { 434 | return {sayac1: 3, sayac2: 5}; 435 | }, 436 | 437 | sayac1Artir: function () { 438 | this.setState({sayac1: this.state.sayac1 + 1, 439 | sayac2: this.state.sayac2 - 1}); 440 | }, 441 | 442 | sayac2Artir: function () { 443 | this.setState({sayac1: this.state.sayac1 - 1, 444 | sayac2: this.state.sayac2 + 1}); 445 | }, 446 | 447 | render: function () { 448 | return ( 449 |
450 | 451 | 452 |
); 453 | } 454 | }) 455 | ``` 456 | 457 | Böylece sistemdeki asıl karmaşıklık, merkezi olarak tepede, ana bileşende 458 | toplanmış oldu, aynı Sayaç bileşenini iki farklı bileşen için 459 | kullanabildik. Sonuç olarak React'in veriyi merkezileştirme ve uygulamayı 460 | bileşenlere ayırmasının uygulamanın geliştirilmesini ne kadar kolaylaştırdığını 461 | ve hatalardan ayırdını görmüş olduk. 462 | 463 | ## Diğer Önemli Konular 464 | 465 | Reactjs konusunda diğer önemli konular olarak şunları sayabiliriz: 466 | 467 | 1. Geliştirme aşamasında React DevTools çok büyük kolaylık getirmekte, HTML DOM 468 | yapısına benzer şekilde bileşen ağacının görülmesine, bileşenlerin props ve 469 | state değişkenlerinin incelenmesi ve değiştirilmesine olanak vermekte. 470 | 471 | 2. node.js kullanarak sunucu tarafında React çalıştırmak suretiyle isomorphic 472 | denilen hem sunucu, hem istemci tarafında çalışan uygulamalar 473 | geliştirilmesi. Burada `React.render` yerine HTML çıktısını string olarak 474 | oluşturan `React.renderToString` kullanılmakta ve bu uygulamalar sayesinde daha 475 | hızlı görüntülenen uygulamalar yapılabilmekte. 476 | 477 | 3. Yeni duyurulan React Native ile bu yapının iPhone ve Android geliştirmesinde 478 | kullanılması mümkün hale geldi. Burada PhoneGap tarzı HTML'in mobil uygulamaya 479 | gömülmesi değil, doğrudan native (yerel) uygulamalar geliştirilmesi sözkonusu. 480 | 481 | 4. React uygulamaları daha büyüdükçe, veri yönetimi için yine Facebook'un 482 | duyurduğu Flux kütüphanesi kullanılmakta. React'te değişken verinin giderek 483 | yukarı çıktığını gördük, bunun bir sonraki adımı verinin tamamen bileşenlerin 484 | dışında Store (depo) denilen bir yapıda tutulması ve bileşenlerin bu 485 | Store'lardaki verilere üye olması. Store'lardaki değişimlerin de bileşenlerden 486 | gelen action (hareket) denilen değişiklik haberlerine göre yapılması. 487 | 488 | ## Sonuç 489 | 490 | Sonuç olarak React'in 3 temel özelliği olduğunu gördük. Birincisi veri 491 | değişimlerinin her zaman açık seçik yapıldığı ve verinin tek taraflı olarak 492 | aktarıldığı. İkincisi uygulamanın bileşenlere ayrıldığı ve bu bileşenlerin 493 | verilerini tepeden props, kendi içinde state şeklinde yönettiği ve yukarıda bir 494 | değişiklik yapılacaksa bu değişikliklerin callbackler ile yapıldığı. Üçüncüsü 495 | veri ile görüntü senkronizasyonu için bileşenlerin görüntüsünün her zaman baştan 496 | oluşturulduğu, React'in de sanal DOM adı verilen metodla bunu çok hızlı bir 497 | şekilde yaptığı. Bu özellikler sayesinde React kütüphanesi ile yüksek 498 | performanslı arayüzleri hızlı ve hatasız şekilde geliştirebilmekteyiz. 499 | -------------------------------------------------------------------------------- /ornekler/Makefile: -------------------------------------------------------------------------------- 1 | 2 | build: 3 | jsx --watch src build 4 | 5 | start_server: 6 | python -m SimpleHTTPServer 7 | 8 | ornekler: 9 | open -a 'Google Chrome' http://localhost:8000 10 | 11 | 12 | .PHONY: build 13 | -------------------------------------------------------------------------------- /ornekler/build/01_merhaba_dunya.js: -------------------------------------------------------------------------------- 1 | var MerhabaDunya = React.createClass({displayName: "MerhabaDunya", 2 | render: function () { 3 | return React.createElement("div", null, "Merhaba Dunya"); 4 | } 5 | }) 6 | 7 | React.render(React.createElement(MerhabaDunya, null), document.body); 8 | -------------------------------------------------------------------------------- /ornekler/build/02_selamlama.js: -------------------------------------------------------------------------------- 1 | var MerhabaDunya = React.createClass({displayName: "MerhabaDunya", 2 | render: function () { 3 | return React.createElement("div", null, "Merhaba Dunya"); 4 | } 5 | }); 6 | 7 | var Selamlama = React.createClass({displayName: "Selamlama", 8 | render: function () { 9 | return ( 10 | React.createElement("div", null, 11 | React.createElement(MerhabaDunya, null), 12 | React.createElement(MerhabaDunya, null) 13 | )) 14 | } 15 | }) 16 | 17 | React.render(React.createElement(Selamlama, null), document.body) 18 | -------------------------------------------------------------------------------- /ornekler/build/03_selamlama_props.js: -------------------------------------------------------------------------------- 1 | var MerhabaDunya = React.createClass({displayName: "MerhabaDunya", 2 | render: function () { 3 | return React.createElement("div", null, "Merhaba ", this.props.isim) 4 | } 5 | }); 6 | 7 | var Selamlama = React.createClass({displayName: "Selamlama", 8 | render: function () { 9 | return React.createElement("div", null, 10 | React.createElement(MerhabaDunya, {isim: "Üstün"}), 11 | React.createElement(MerhabaDunya, {isim: "Özgür"}) 12 | ) 13 | } 14 | }) 15 | 16 | React.render(React.createElement(Selamlama, null), document.body) 17 | -------------------------------------------------------------------------------- /ornekler/build/04_sayac.js: -------------------------------------------------------------------------------- 1 | var Sayac = React.createClass({displayName: "Sayac", 2 | getInitialState: function () { 3 | return {sayac: 0}; 4 | }, 5 | 6 | artir: function () { 7 | var suAnkiSayac = this.state.sayac; 8 | this.setState({sayac: suAnkiSayac + 1}); 9 | }, 10 | 11 | render: function () { 12 | return ( 13 | React.createElement("div", null, 14 | "Sayaca ", this.state.sayac, " kez tıkladınız", 15 | React.createElement("button", {onClick: this.artir}, "Sayaç") 16 | )) 17 | } 18 | }) 19 | 20 | 21 | 22 | React.render(React.createElement(Sayac, null), document.body); 23 | -------------------------------------------------------------------------------- /ornekler/build/05_sayac_gerisayim.js: -------------------------------------------------------------------------------- 1 | var Sayac = React.createClass({displayName: "Sayac", 2 | getInitialState: function () { 3 | return {sayac: 0}; 4 | }, 5 | 6 | artir: function () { 7 | var suAnkiSayac = this.state.sayac; 8 | this.setState({sayac: suAnkiSayac + 1}); 9 | }, 10 | 11 | render: function () { 12 | return ( 13 | React.createElement("div", null, 14 | "Sayaca ", this.state.sayac, " kez tıkladınız.", 15 | 10 - this.state.sayac, " kez daha tıklamalısınız.", 16 | React.createElement("button", {onClick: this.artir}, "Sayaç") 17 | ) 18 | ); 19 | } 20 | }) 21 | 22 | React.render(React.createElement(Sayac, null), document.body); 23 | -------------------------------------------------------------------------------- /ornekler/build/06_sayaclar.js: -------------------------------------------------------------------------------- 1 | var Sayac = React.createClass({displayName: "Sayac", 2 | 3 | render: function () { 4 | return ( 5 | React.createElement("div", null, 6 | "Sayaca ", this.props.sayac, " kez tıkladınız.", 7 | 10 - this.props.sayac, " kez daha tıklamalısınız.", 8 | React.createElement("button", {onClick: this.props.artir}, "Sayaç") 9 | )); 10 | } 11 | }); 12 | 13 | 14 | var Sayaclar = React.createClass({displayName: "Sayaclar", 15 | getInitialState: function () { 16 | return {sayac1: 3, sayac2: 5}; 17 | }, 18 | 19 | sayac1Artir: function () { 20 | this.setState({sayac1: this.state.sayac1 + 1, 21 | sayac2: this.state.sayac2 - 1}); 22 | }, 23 | 24 | sayac2Artir: function () { 25 | this.setState({sayac1: this.state.sayac1 - 1, 26 | sayac2: this.state.sayac2 + 1}); 27 | }, 28 | 29 | render: function () { 30 | return ( 31 | React.createElement("div", null, 32 | React.createElement(Sayac, {sayac: this.state.sayac1, artir: this.sayac1Artir}), 33 | React.createElement(Sayac, {sayac: this.state.sayac2, artir: this.sayac2Artir}) 34 | )); 35 | } 36 | }) 37 | 38 | 39 | React.render(React.createElement(Sayaclar, null), document.body); 40 | -------------------------------------------------------------------------------- /ornekler/css/app.css: -------------------------------------------------------------------------------- 1 | 2 | 3 | body { 4 | 5 | font-size: 34px; 6 | width: 80%; 7 | margin: 20px auto 0 auto; 8 | text-align: center; 9 | /* display: flex; */ 10 | } 11 | 12 | div { 13 | margin: 20px; 14 | padding: 20px; 15 | border: 1px dashed black; 16 | text-align: center; 17 | } 18 | 19 | button { 20 | background-color: orange; 21 | border: none; 22 | padding: 20px; 23 | color: white; 24 | margin: 20px auto 0 auto; 25 | display: block; 26 | 27 | } 28 | 29 | ol { 30 | text-align: left; 31 | } 32 | -------------------------------------------------------------------------------- /ornekler/css/pure.css: -------------------------------------------------------------------------------- 1 | /*! 2 | Pure v0.5.0 3 | Copyright 2014 Yahoo! Inc. All rights reserved. 4 | Licensed under the BSD License. 5 | https://github.com/yui/pure/blob/master/LICENSE.md 6 | */ 7 | /*! 8 | normalize.css v1.1.3 | MIT License | git.io/normalize 9 | Copyright (c) Nicolas Gallagher and Jonathan Neal 10 | */ 11 | /*! normalize.css v1.1.3 | MIT License | git.io/normalize */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none;height:0}[hidden]{display:none}html{font-size:100%;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}html,button,input,select,textarea{font-family:sans-serif}body{margin:0}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{font-size:2em;margin:.67em 0}h2{font-size:1.5em;margin:.83em 0}h3{font-size:1.17em;margin:1em 0}h4{font-size:1em;margin:1.33em 0}h5{font-size:.83em;margin:1.67em 0}h6{font-size:.67em;margin:2.33em 0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:1em 40px}dfn{font-style:italic}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}mark{background:#ff0;color:#000}p,pre{margin:1em 0}code,kbd,pre,samp{font-family:monospace,serif;_font-family:'courier new',monospace;font-size:1em}pre{white-space:pre;white-space:pre-wrap;word-wrap:break-word}q{quotes:none}q:before,q:after{content:'';content:none}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,menu,ol,ul{margin:1em 0}dd{margin:0 0 0 40px}menu,ol,ul{padding:0 0 0 40px}nav ul,nav ol{list-style:none;list-style-image:none}img{border:0;-ms-interpolation-mode:bicubic}svg:not(:root){overflow:hidden}figure{margin:0}form{margin:0}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0;white-space:normal;*margin-left:-7px}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;*overflow:visible}button[disabled],html input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0;*height:13px;*width:13px}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}[hidden]{display:none!important}.pure-img{max-width:100%;height:auto;display:block}.pure-g{letter-spacing:-.31em;*letter-spacing:normal;*word-spacing:-.43em;text-rendering:optimizespeed;font-family:FreeSans,Arimo,"Droid Sans",Helvetica,Arial,sans-serif;display:-webkit-flex;-webkit-flex-flow:row wrap;display:-ms-flexbox;-ms-flex-flow:row wrap}.opera-only :-o-prefocus,.pure-g{word-spacing:-.43em}.pure-u{display:inline-block;*display:inline;zoom:1;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-g [class *="pure-u"]{font-family:sans-serif}.pure-u-1,.pure-u-1-1,.pure-u-1-2,.pure-u-1-3,.pure-u-2-3,.pure-u-1-4,.pure-u-3-4,.pure-u-1-5,.pure-u-2-5,.pure-u-3-5,.pure-u-4-5,.pure-u-5-5,.pure-u-1-6,.pure-u-5-6,.pure-u-1-8,.pure-u-3-8,.pure-u-5-8,.pure-u-7-8,.pure-u-1-12,.pure-u-5-12,.pure-u-7-12,.pure-u-11-12,.pure-u-1-24,.pure-u-2-24,.pure-u-3-24,.pure-u-4-24,.pure-u-5-24,.pure-u-6-24,.pure-u-7-24,.pure-u-8-24,.pure-u-9-24,.pure-u-10-24,.pure-u-11-24,.pure-u-12-24,.pure-u-13-24,.pure-u-14-24,.pure-u-15-24,.pure-u-16-24,.pure-u-17-24,.pure-u-18-24,.pure-u-19-24,.pure-u-20-24,.pure-u-21-24,.pure-u-22-24,.pure-u-23-24,.pure-u-24-24{display:inline-block;*display:inline;zoom:1;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-u-1-24{width:4.1667%;*width:4.1357%}.pure-u-1-12,.pure-u-2-24{width:8.3333%;*width:8.3023%}.pure-u-1-8,.pure-u-3-24{width:12.5%;*width:12.469%}.pure-u-1-6,.pure-u-4-24{width:16.6667%;*width:16.6357%}.pure-u-1-5{width:20%;*width:19.969%}.pure-u-5-24{width:20.8333%;*width:20.8023%}.pure-u-1-4,.pure-u-6-24{width:25%;*width:24.969%}.pure-u-7-24{width:29.1667%;*width:29.1357%}.pure-u-1-3,.pure-u-8-24{width:33.3333%;*width:33.3023%}.pure-u-3-8,.pure-u-9-24{width:37.5%;*width:37.469%}.pure-u-2-5{width:40%;*width:39.969%}.pure-u-5-12,.pure-u-10-24{width:41.6667%;*width:41.6357%}.pure-u-11-24{width:45.8333%;*width:45.8023%}.pure-u-1-2,.pure-u-12-24{width:50%;*width:49.969%}.pure-u-13-24{width:54.1667%;*width:54.1357%}.pure-u-7-12,.pure-u-14-24{width:58.3333%;*width:58.3023%}.pure-u-3-5{width:60%;*width:59.969%}.pure-u-5-8,.pure-u-15-24{width:62.5%;*width:62.469%}.pure-u-2-3,.pure-u-16-24{width:66.6667%;*width:66.6357%}.pure-u-17-24{width:70.8333%;*width:70.8023%}.pure-u-3-4,.pure-u-18-24{width:75%;*width:74.969%}.pure-u-19-24{width:79.1667%;*width:79.1357%}.pure-u-4-5{width:80%;*width:79.969%}.pure-u-5-6,.pure-u-20-24{width:83.3333%;*width:83.3023%}.pure-u-7-8,.pure-u-21-24{width:87.5%;*width:87.469%}.pure-u-11-12,.pure-u-22-24{width:91.6667%;*width:91.6357%}.pure-u-23-24{width:95.8333%;*width:95.8023%}.pure-u-1,.pure-u-1-1,.pure-u-5-5,.pure-u-24-24{width:100%}.pure-button{display:inline-block;*display:inline;zoom:1;line-height:normal;white-space:nowrap;vertical-align:baseline;text-align:center;cursor:pointer;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.pure-button::-moz-focus-inner{padding:0;border:0}.pure-button{font-family:inherit;font-size:100%;*font-size:90%;*overflow:visible;padding:.5em 1em;color:#444;color:rgba(0,0,0,.8);*color:#444;border:1px solid #999;border:0 rgba(0,0,0,0);background-color:#E6E6E6;text-decoration:none;border-radius:2px}.pure-button-hover,.pure-button:hover,.pure-button:focus{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#1a000000', GradientType=0);background-image:-webkit-gradient(linear,0 0,0 100%,from(transparent),color-stop(40%,rgba(0,0,0,.05)),to(rgba(0,0,0,.1)));background-image:-webkit-linear-gradient(transparent,rgba(0,0,0,.05) 40%,rgba(0,0,0,.1));background-image:-moz-linear-gradient(top,rgba(0,0,0,.05) 0,rgba(0,0,0,.1));background-image:-o-linear-gradient(transparent,rgba(0,0,0,.05) 40%,rgba(0,0,0,.1));background-image:linear-gradient(transparent,rgba(0,0,0,.05) 40%,rgba(0,0,0,.1))}.pure-button:focus{outline:0}.pure-button-active,.pure-button:active{box-shadow:0 0 0 1px rgba(0,0,0,.15) inset,0 0 6px rgba(0,0,0,.2) inset}.pure-button[disabled],.pure-button-disabled,.pure-button-disabled:hover,.pure-button-disabled:focus,.pure-button-disabled:active{border:0;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);filter:alpha(opacity=40);-khtml-opacity:.4;-moz-opacity:.4;opacity:.4;cursor:not-allowed;box-shadow:none}.pure-button-hidden{display:none}.pure-button::-moz-focus-inner{padding:0;border:0}.pure-button-primary,.pure-button-selected,a.pure-button-primary,a.pure-button-selected{background-color:#0078e7;color:#fff}.pure-form input[type=text],.pure-form input[type=password],.pure-form input[type=email],.pure-form input[type=url],.pure-form input[type=date],.pure-form input[type=month],.pure-form input[type=time],.pure-form input[type=datetime],.pure-form input[type=datetime-local],.pure-form input[type=week],.pure-form input[type=number],.pure-form input[type=search],.pure-form input[type=tel],.pure-form input[type=color],.pure-form select,.pure-form textarea{padding:.5em .6em;display:inline-block;border:1px solid #ccc;box-shadow:inset 0 1px 3px #ddd;border-radius:4px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.pure-form input:not([type]){padding:.5em .6em;display:inline-block;border:1px solid #ccc;box-shadow:inset 0 1px 3px #ddd;border-radius:4px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.pure-form input[type=color]{padding:.2em .5em}.pure-form input[type=text]:focus,.pure-form input[type=password]:focus,.pure-form input[type=email]:focus,.pure-form input[type=url]:focus,.pure-form input[type=date]:focus,.pure-form input[type=month]:focus,.pure-form input[type=time]:focus,.pure-form input[type=datetime]:focus,.pure-form input[type=datetime-local]:focus,.pure-form input[type=week]:focus,.pure-form input[type=number]:focus,.pure-form input[type=search]:focus,.pure-form input[type=tel]:focus,.pure-form input[type=color]:focus,.pure-form select:focus,.pure-form textarea:focus{outline:0;outline:thin dotted \9;border-color:#129FEA}.pure-form input:not([type]):focus{outline:0;outline:thin dotted \9;border-color:#129FEA}.pure-form input[type=file]:focus,.pure-form input[type=radio]:focus,.pure-form input[type=checkbox]:focus{outline:thin dotted #333;outline:1px auto #129FEA}.pure-form .pure-checkbox,.pure-form .pure-radio{margin:.5em 0;display:block}.pure-form input[type=text][disabled],.pure-form input[type=password][disabled],.pure-form input[type=email][disabled],.pure-form input[type=url][disabled],.pure-form input[type=date][disabled],.pure-form input[type=month][disabled],.pure-form input[type=time][disabled],.pure-form input[type=datetime][disabled],.pure-form input[type=datetime-local][disabled],.pure-form input[type=week][disabled],.pure-form input[type=number][disabled],.pure-form input[type=search][disabled],.pure-form input[type=tel][disabled],.pure-form input[type=color][disabled],.pure-form select[disabled],.pure-form textarea[disabled]{cursor:not-allowed;background-color:#eaeded;color:#cad2d3}.pure-form input:not([type])[disabled]{cursor:not-allowed;background-color:#eaeded;color:#cad2d3}.pure-form input[readonly],.pure-form select[readonly],.pure-form textarea[readonly]{background:#eee;color:#777;border-color:#ccc}.pure-form input:focus:invalid,.pure-form textarea:focus:invalid,.pure-form select:focus:invalid{color:#b94a48;border-color:#ee5f5b}.pure-form input:focus:invalid:focus,.pure-form textarea:focus:invalid:focus,.pure-form select:focus:invalid:focus{border-color:#e9322d}.pure-form input[type=file]:focus:invalid:focus,.pure-form input[type=radio]:focus:invalid:focus,.pure-form input[type=checkbox]:focus:invalid:focus{outline-color:#e9322d}.pure-form select{border:1px solid #ccc;background-color:#fff}.pure-form select[multiple]{height:auto}.pure-form label{margin:.5em 0 .2em}.pure-form fieldset{margin:0;padding:.35em 0 .75em;border:0}.pure-form legend{display:block;width:100%;padding:.3em 0;margin-bottom:.3em;color:#333;border-bottom:1px solid #e5e5e5}.pure-form-stacked input[type=text],.pure-form-stacked input[type=password],.pure-form-stacked input[type=email],.pure-form-stacked input[type=url],.pure-form-stacked input[type=date],.pure-form-stacked input[type=month],.pure-form-stacked input[type=time],.pure-form-stacked input[type=datetime],.pure-form-stacked input[type=datetime-local],.pure-form-stacked input[type=week],.pure-form-stacked input[type=number],.pure-form-stacked input[type=search],.pure-form-stacked input[type=tel],.pure-form-stacked input[type=color],.pure-form-stacked select,.pure-form-stacked label,.pure-form-stacked textarea{display:block;margin:.25em 0}.pure-form-stacked input:not([type]){display:block;margin:.25em 0}.pure-form-aligned input,.pure-form-aligned textarea,.pure-form-aligned select,.pure-form-aligned .pure-help-inline,.pure-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.pure-form-aligned textarea{vertical-align:top}.pure-form-aligned .pure-control-group{margin-bottom:.5em}.pure-form-aligned .pure-control-group label{text-align:right;display:inline-block;vertical-align:middle;width:10em;margin:0 1em 0 0}.pure-form-aligned .pure-controls{margin:1.5em 0 0 10em}.pure-form input.pure-input-rounded,.pure-form .pure-input-rounded{border-radius:2em;padding:.5em 1em}.pure-form .pure-group fieldset{margin-bottom:10px}.pure-form .pure-group input{display:block;padding:10px;margin:0;border-radius:0;position:relative;top:-1px}.pure-form .pure-group input:focus{z-index:2}.pure-form .pure-group input:first-child{top:1px;border-radius:4px 4px 0 0}.pure-form .pure-group input:last-child{top:-2px;border-radius:0 0 4px 4px}.pure-form .pure-group button{margin:.35em 0}.pure-form .pure-input-1{width:100%}.pure-form .pure-input-2-3{width:66%}.pure-form .pure-input-1-2{width:50%}.pure-form .pure-input-1-3{width:33%}.pure-form .pure-input-1-4{width:25%}.pure-form .pure-help-inline,.pure-form-message-inline{display:inline-block;padding-left:.3em;color:#666;vertical-align:middle;font-size:.875em}.pure-form-message{display:block;color:#666;font-size:.875em}@media only screen and (max-width :480px){.pure-form button[type=submit]{margin:.7em 0 0}.pure-form input:not([type]),.pure-form input[type=text],.pure-form input[type=password],.pure-form input[type=email],.pure-form input[type=url],.pure-form input[type=date],.pure-form input[type=month],.pure-form input[type=time],.pure-form input[type=datetime],.pure-form input[type=datetime-local],.pure-form input[type=week],.pure-form input[type=number],.pure-form input[type=search],.pure-form input[type=tel],.pure-form input[type=color],.pure-form label{margin-bottom:.3em;display:block}.pure-group input:not([type]),.pure-group input[type=text],.pure-group input[type=password],.pure-group input[type=email],.pure-group input[type=url],.pure-group input[type=date],.pure-group input[type=month],.pure-group input[type=time],.pure-group input[type=datetime],.pure-group input[type=datetime-local],.pure-group input[type=week],.pure-group input[type=number],.pure-group input[type=search],.pure-group input[type=tel],.pure-group input[type=color]{margin-bottom:0}.pure-form-aligned .pure-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.pure-form-aligned .pure-controls{margin:1.5em 0 0}.pure-form .pure-help-inline,.pure-form-message-inline,.pure-form-message{display:block;font-size:.75em;padding:.2em 0 .8em}}.pure-menu ul{position:absolute;visibility:hidden}.pure-menu.pure-menu-open{visibility:visible;z-index:2;width:100%}.pure-menu ul{left:-10000px;list-style:none;margin:0;padding:0;top:-10000px;z-index:1}.pure-menu>ul{position:relative}.pure-menu-open>ul{left:0;top:0;visibility:visible}.pure-menu-open>ul:focus{outline:0}.pure-menu li{position:relative}.pure-menu a,.pure-menu .pure-menu-heading{display:block;color:inherit;line-height:1.5em;padding:5px 20px;text-decoration:none;white-space:nowrap}.pure-menu.pure-menu-horizontal>.pure-menu-heading{display:inline-block;*display:inline;zoom:1;margin:0;vertical-align:middle}.pure-menu.pure-menu-horizontal>ul{display:inline-block;*display:inline;zoom:1;vertical-align:middle}.pure-menu li a{padding:5px 20px}.pure-menu-can-have-children>.pure-menu-label:after{content:'\25B8';float:right;font-family:'Lucida Grande','Lucida Sans Unicode','DejaVu Sans',sans-serif;margin-right:-20px;margin-top:-1px}.pure-menu-can-have-children>.pure-menu-label{padding-right:30px}.pure-menu-separator{background-color:#dfdfdf;display:block;height:1px;font-size:0;margin:7px 2px;overflow:hidden}.pure-menu-hidden{display:none}.pure-menu-fixed{position:fixed;top:0;left:0;width:100%}.pure-menu-horizontal li{display:inline-block;*display:inline;zoom:1;vertical-align:middle}.pure-menu-horizontal li li{display:block}.pure-menu-horizontal>.pure-menu-children>.pure-menu-can-have-children>.pure-menu-label:after{content:"\25BE"}.pure-menu-horizontal>.pure-menu-children>.pure-menu-can-have-children>.pure-menu-label{padding-right:30px}.pure-menu-horizontal li.pure-menu-separator{height:50%;width:1px;margin:0 7px}.pure-menu-horizontal li li.pure-menu-separator{height:1px;width:auto;margin:7px 2px}.pure-menu.pure-menu-open,.pure-menu.pure-menu-horizontal li .pure-menu-children{background:#fff;border:1px solid #b7b7b7}.pure-menu.pure-menu-horizontal,.pure-menu.pure-menu-horizontal .pure-menu-heading{border:0}.pure-menu a{border:1px solid transparent;border-left:0;border-right:0}.pure-menu a,.pure-menu .pure-menu-can-have-children>li:after{color:#777}.pure-menu .pure-menu-can-have-children>li:hover:after{color:#fff}.pure-menu .pure-menu-open{background:#dedede}.pure-menu li a:hover,.pure-menu li a:focus{background:#eee}.pure-menu li.pure-menu-disabled a:hover,.pure-menu li.pure-menu-disabled a:focus{background:#fff;color:#bfbfbf}.pure-menu .pure-menu-disabled>a{background-image:none;border-color:transparent;cursor:default}.pure-menu .pure-menu-disabled>a,.pure-menu .pure-menu-can-have-children.pure-menu-disabled>a:after{color:#bfbfbf}.pure-menu .pure-menu-heading{color:#565d64;text-transform:uppercase;font-size:90%;margin-top:.5em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#dfdfdf}.pure-menu .pure-menu-selected a{color:#000}.pure-menu.pure-menu-open.pure-menu-fixed{border:0;border-bottom:1px solid #b7b7b7}.pure-paginator{letter-spacing:-.31em;*letter-spacing:normal;*word-spacing:-.43em;text-rendering:optimizespeed;list-style:none;margin:0;padding:0}.opera-only :-o-prefocus,.pure-paginator{word-spacing:-.43em}.pure-paginator li{display:inline-block;*display:inline;zoom:1;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-paginator .pure-button{border-radius:0;padding:.8em 1.4em;vertical-align:top;height:1.1em}.pure-paginator .pure-button:focus,.pure-paginator .pure-button:active{outline-style:none}.pure-paginator .prev,.pure-paginator .next{color:#C0C1C3;text-shadow:0 -1px 0 rgba(0,0,0,.45)}.pure-paginator .prev{border-radius:2px 0 0 2px}.pure-paginator .next{border-radius:0 2px 2px 0}@media (max-width:480px){.pure-menu-horizontal{width:100%}.pure-menu-children li{display:block;border-bottom:1px solid #000}}.pure-table{border-collapse:collapse;border-spacing:0;empty-cells:show;border:1px solid #cbcbcb}.pure-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.pure-table td,.pure-table th{border-left:1px solid #cbcbcb;border-width:0 0 0 1px;font-size:inherit;margin:0;overflow:visible;padding:.5em 1em}.pure-table td:first-child,.pure-table th:first-child{border-left-width:0}.pure-table thead{background:#e0e0e0;color:#000;text-align:left;vertical-align:bottom}.pure-table td{background-color:transparent}.pure-table-odd td{background-color:#f2f2f2}.pure-table-striped tr:nth-child(2n-1) td{background-color:#f2f2f2}.pure-table-bordered td{border-bottom:1px solid #cbcbcb}.pure-table-bordered tbody>tr:last-child td,.pure-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.pure-table-horizontal td,.pure-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #cbcbcb}.pure-table-horizontal tbody>tr:last-child td{border-bottom-width:0} -------------------------------------------------------------------------------- /ornekler/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
    11 |
  1. Merhaba Dunya
  2. 12 |
  3. Selamlama
  4. 13 |
  5. Selamlama (props)
  6. 14 |
  7. Sayac
  8. 15 |
  9. Sayac (gerisayim)
  10. 16 |
  11. Sayaclar
  12. 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /ornekler/libs/underscore.js: -------------------------------------------------------------------------------- 1 | // Underscore.js 1.7.0 2 | // http://underscorejs.org 3 | // (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors 4 | // Underscore may be freely distributed under the MIT license. 5 | (function(){var n=this,t=n._,r=Array.prototype,e=Object.prototype,u=Function.prototype,i=r.push,a=r.slice,o=r.concat,l=e.toString,c=e.hasOwnProperty,f=Array.isArray,s=Object.keys,p=u.bind,h=function(n){return n instanceof h?n:this instanceof h?void(this._wrapped=n):new h(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=h),exports._=h):n._=h,h.VERSION="1.7.0";var g=function(n,t,r){if(t===void 0)return n;switch(null==r?3:r){case 1:return function(r){return n.call(t,r)};case 2:return function(r,e){return n.call(t,r,e)};case 3:return function(r,e,u){return n.call(t,r,e,u)};case 4:return function(r,e,u,i){return n.call(t,r,e,u,i)}}return function(){return n.apply(t,arguments)}};h.iteratee=function(n,t,r){return null==n?h.identity:h.isFunction(n)?g(n,t,r):h.isObject(n)?h.matches(n):h.property(n)},h.each=h.forEach=function(n,t,r){if(null==n)return n;t=g(t,r);var e,u=n.length;if(u===+u)for(e=0;u>e;e++)t(n[e],e,n);else{var i=h.keys(n);for(e=0,u=i.length;u>e;e++)t(n[i[e]],i[e],n)}return n},h.map=h.collect=function(n,t,r){if(null==n)return[];t=h.iteratee(t,r);for(var e,u=n.length!==+n.length&&h.keys(n),i=(u||n).length,a=Array(i),o=0;i>o;o++)e=u?u[o]:o,a[o]=t(n[e],e,n);return a};var v="Reduce of empty array with no initial value";h.reduce=h.foldl=h.inject=function(n,t,r,e){null==n&&(n=[]),t=g(t,e,4);var u,i=n.length!==+n.length&&h.keys(n),a=(i||n).length,o=0;if(arguments.length<3){if(!a)throw new TypeError(v);r=n[i?i[o++]:o++]}for(;a>o;o++)u=i?i[o]:o,r=t(r,n[u],u,n);return r},h.reduceRight=h.foldr=function(n,t,r,e){null==n&&(n=[]),t=g(t,e,4);var u,i=n.length!==+n.length&&h.keys(n),a=(i||n).length;if(arguments.length<3){if(!a)throw new TypeError(v);r=n[i?i[--a]:--a]}for(;a--;)u=i?i[a]:a,r=t(r,n[u],u,n);return r},h.find=h.detect=function(n,t,r){var e;return t=h.iteratee(t,r),h.some(n,function(n,r,u){return t(n,r,u)?(e=n,!0):void 0}),e},h.filter=h.select=function(n,t,r){var e=[];return null==n?e:(t=h.iteratee(t,r),h.each(n,function(n,r,u){t(n,r,u)&&e.push(n)}),e)},h.reject=function(n,t,r){return h.filter(n,h.negate(h.iteratee(t)),r)},h.every=h.all=function(n,t,r){if(null==n)return!0;t=h.iteratee(t,r);var e,u,i=n.length!==+n.length&&h.keys(n),a=(i||n).length;for(e=0;a>e;e++)if(u=i?i[e]:e,!t(n[u],u,n))return!1;return!0},h.some=h.any=function(n,t,r){if(null==n)return!1;t=h.iteratee(t,r);var e,u,i=n.length!==+n.length&&h.keys(n),a=(i||n).length;for(e=0;a>e;e++)if(u=i?i[e]:e,t(n[u],u,n))return!0;return!1},h.contains=h.include=function(n,t){return null==n?!1:(n.length!==+n.length&&(n=h.values(n)),h.indexOf(n,t)>=0)},h.invoke=function(n,t){var r=a.call(arguments,2),e=h.isFunction(t);return h.map(n,function(n){return(e?t:n[t]).apply(n,r)})},h.pluck=function(n,t){return h.map(n,h.property(t))},h.where=function(n,t){return h.filter(n,h.matches(t))},h.findWhere=function(n,t){return h.find(n,h.matches(t))},h.max=function(n,t,r){var e,u,i=-1/0,a=-1/0;if(null==t&&null!=n){n=n.length===+n.length?n:h.values(n);for(var o=0,l=n.length;l>o;o++)e=n[o],e>i&&(i=e)}else t=h.iteratee(t,r),h.each(n,function(n,r,e){u=t(n,r,e),(u>a||u===-1/0&&i===-1/0)&&(i=n,a=u)});return i},h.min=function(n,t,r){var e,u,i=1/0,a=1/0;if(null==t&&null!=n){n=n.length===+n.length?n:h.values(n);for(var o=0,l=n.length;l>o;o++)e=n[o],i>e&&(i=e)}else t=h.iteratee(t,r),h.each(n,function(n,r,e){u=t(n,r,e),(a>u||1/0===u&&1/0===i)&&(i=n,a=u)});return i},h.shuffle=function(n){for(var t,r=n&&n.length===+n.length?n:h.values(n),e=r.length,u=Array(e),i=0;e>i;i++)t=h.random(0,i),t!==i&&(u[i]=u[t]),u[t]=r[i];return u},h.sample=function(n,t,r){return null==t||r?(n.length!==+n.length&&(n=h.values(n)),n[h.random(n.length-1)]):h.shuffle(n).slice(0,Math.max(0,t))},h.sortBy=function(n,t,r){return t=h.iteratee(t,r),h.pluck(h.map(n,function(n,r,e){return{value:n,index:r,criteria:t(n,r,e)}}).sort(function(n,t){var r=n.criteria,e=t.criteria;if(r!==e){if(r>e||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.index-t.index}),"value")};var m=function(n){return function(t,r,e){var u={};return r=h.iteratee(r,e),h.each(t,function(e,i){var a=r(e,i,t);n(u,e,a)}),u}};h.groupBy=m(function(n,t,r){h.has(n,r)?n[r].push(t):n[r]=[t]}),h.indexBy=m(function(n,t,r){n[r]=t}),h.countBy=m(function(n,t,r){h.has(n,r)?n[r]++:n[r]=1}),h.sortedIndex=function(n,t,r,e){r=h.iteratee(r,e,1);for(var u=r(t),i=0,a=n.length;a>i;){var o=i+a>>>1;r(n[o])t?[]:a.call(n,0,t)},h.initial=function(n,t,r){return a.call(n,0,Math.max(0,n.length-(null==t||r?1:t)))},h.last=function(n,t,r){return null==n?void 0:null==t||r?n[n.length-1]:a.call(n,Math.max(n.length-t,0))},h.rest=h.tail=h.drop=function(n,t,r){return a.call(n,null==t||r?1:t)},h.compact=function(n){return h.filter(n,h.identity)};var y=function(n,t,r,e){if(t&&h.every(n,h.isArray))return o.apply(e,n);for(var u=0,a=n.length;a>u;u++){var l=n[u];h.isArray(l)||h.isArguments(l)?t?i.apply(e,l):y(l,t,r,e):r||e.push(l)}return e};h.flatten=function(n,t){return y(n,t,!1,[])},h.without=function(n){return h.difference(n,a.call(arguments,1))},h.uniq=h.unique=function(n,t,r,e){if(null==n)return[];h.isBoolean(t)||(e=r,r=t,t=!1),null!=r&&(r=h.iteratee(r,e));for(var u=[],i=[],a=0,o=n.length;o>a;a++){var l=n[a];if(t)a&&i===l||u.push(l),i=l;else if(r){var c=r(l,a,n);h.indexOf(i,c)<0&&(i.push(c),u.push(l))}else h.indexOf(u,l)<0&&u.push(l)}return u},h.union=function(){return h.uniq(y(arguments,!0,!0,[]))},h.intersection=function(n){if(null==n)return[];for(var t=[],r=arguments.length,e=0,u=n.length;u>e;e++){var i=n[e];if(!h.contains(t,i)){for(var a=1;r>a&&h.contains(arguments[a],i);a++);a===r&&t.push(i)}}return t},h.difference=function(n){var t=y(a.call(arguments,1),!0,!0,[]);return h.filter(n,function(n){return!h.contains(t,n)})},h.zip=function(n){if(null==n)return[];for(var t=h.max(arguments,"length").length,r=Array(t),e=0;t>e;e++)r[e]=h.pluck(arguments,e);return r},h.object=function(n,t){if(null==n)return{};for(var r={},e=0,u=n.length;u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},h.indexOf=function(n,t,r){if(null==n)return-1;var e=0,u=n.length;if(r){if("number"!=typeof r)return e=h.sortedIndex(n,t),n[e]===t?e:-1;e=0>r?Math.max(0,u+r):r}for(;u>e;e++)if(n[e]===t)return e;return-1},h.lastIndexOf=function(n,t,r){if(null==n)return-1;var e=n.length;for("number"==typeof r&&(e=0>r?e+r+1:Math.min(e,r+1));--e>=0;)if(n[e]===t)return e;return-1},h.range=function(n,t,r){arguments.length<=1&&(t=n||0,n=0),r=r||1;for(var e=Math.max(Math.ceil((t-n)/r),0),u=Array(e),i=0;e>i;i++,n+=r)u[i]=n;return u};var d=function(){};h.bind=function(n,t){var r,e;if(p&&n.bind===p)return p.apply(n,a.call(arguments,1));if(!h.isFunction(n))throw new TypeError("Bind must be called on a function");return r=a.call(arguments,2),e=function(){if(!(this instanceof e))return n.apply(t,r.concat(a.call(arguments)));d.prototype=n.prototype;var u=new d;d.prototype=null;var i=n.apply(u,r.concat(a.call(arguments)));return h.isObject(i)?i:u}},h.partial=function(n){var t=a.call(arguments,1);return function(){for(var r=0,e=t.slice(),u=0,i=e.length;i>u;u++)e[u]===h&&(e[u]=arguments[r++]);for(;r=e)throw new Error("bindAll must be passed function names");for(t=1;e>t;t++)r=arguments[t],n[r]=h.bind(n[r],n);return n},h.memoize=function(n,t){var r=function(e){var u=r.cache,i=t?t.apply(this,arguments):e;return h.has(u,i)||(u[i]=n.apply(this,arguments)),u[i]};return r.cache={},r},h.delay=function(n,t){var r=a.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},h.defer=function(n){return h.delay.apply(h,[n,1].concat(a.call(arguments,1)))},h.throttle=function(n,t,r){var e,u,i,a=null,o=0;r||(r={});var l=function(){o=r.leading===!1?0:h.now(),a=null,i=n.apply(e,u),a||(e=u=null)};return function(){var c=h.now();o||r.leading!==!1||(o=c);var f=t-(c-o);return e=this,u=arguments,0>=f||f>t?(clearTimeout(a),a=null,o=c,i=n.apply(e,u),a||(e=u=null)):a||r.trailing===!1||(a=setTimeout(l,f)),i}},h.debounce=function(n,t,r){var e,u,i,a,o,l=function(){var c=h.now()-a;t>c&&c>0?e=setTimeout(l,t-c):(e=null,r||(o=n.apply(i,u),e||(i=u=null)))};return function(){i=this,u=arguments,a=h.now();var c=r&&!e;return e||(e=setTimeout(l,t)),c&&(o=n.apply(i,u),i=u=null),o}},h.wrap=function(n,t){return h.partial(t,n)},h.negate=function(n){return function(){return!n.apply(this,arguments)}},h.compose=function(){var n=arguments,t=n.length-1;return function(){for(var r=t,e=n[t].apply(this,arguments);r--;)e=n[r].call(this,e);return e}},h.after=function(n,t){return function(){return--n<1?t.apply(this,arguments):void 0}},h.before=function(n,t){var r;return function(){return--n>0?r=t.apply(this,arguments):t=null,r}},h.once=h.partial(h.before,2),h.keys=function(n){if(!h.isObject(n))return[];if(s)return s(n);var t=[];for(var r in n)h.has(n,r)&&t.push(r);return t},h.values=function(n){for(var t=h.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=n[t[u]];return e},h.pairs=function(n){for(var t=h.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=[t[u],n[t[u]]];return e},h.invert=function(n){for(var t={},r=h.keys(n),e=0,u=r.length;u>e;e++)t[n[r[e]]]=r[e];return t},h.functions=h.methods=function(n){var t=[];for(var r in n)h.isFunction(n[r])&&t.push(r);return t.sort()},h.extend=function(n){if(!h.isObject(n))return n;for(var t,r,e=1,u=arguments.length;u>e;e++){t=arguments[e];for(r in t)c.call(t,r)&&(n[r]=t[r])}return n},h.pick=function(n,t,r){var e,u={};if(null==n)return u;if(h.isFunction(t)){t=g(t,r);for(e in n){var i=n[e];t(i,e,n)&&(u[e]=i)}}else{var l=o.apply([],a.call(arguments,1));n=new Object(n);for(var c=0,f=l.length;f>c;c++)e=l[c],e in n&&(u[e]=n[e])}return u},h.omit=function(n,t,r){if(h.isFunction(t))t=h.negate(t);else{var e=h.map(o.apply([],a.call(arguments,1)),String);t=function(n,t){return!h.contains(e,t)}}return h.pick(n,t,r)},h.defaults=function(n){if(!h.isObject(n))return n;for(var t=1,r=arguments.length;r>t;t++){var e=arguments[t];for(var u in e)n[u]===void 0&&(n[u]=e[u])}return n},h.clone=function(n){return h.isObject(n)?h.isArray(n)?n.slice():h.extend({},n):n},h.tap=function(n,t){return t(n),n};var b=function(n,t,r,e){if(n===t)return 0!==n||1/n===1/t;if(null==n||null==t)return n===t;n instanceof h&&(n=n._wrapped),t instanceof h&&(t=t._wrapped);var u=l.call(n);if(u!==l.call(t))return!1;switch(u){case"[object RegExp]":case"[object String]":return""+n==""+t;case"[object Number]":return+n!==+n?+t!==+t:0===+n?1/+n===1/t:+n===+t;case"[object Date]":case"[object Boolean]":return+n===+t}if("object"!=typeof n||"object"!=typeof t)return!1;for(var i=r.length;i--;)if(r[i]===n)return e[i]===t;var a=n.constructor,o=t.constructor;if(a!==o&&"constructor"in n&&"constructor"in t&&!(h.isFunction(a)&&a instanceof a&&h.isFunction(o)&&o instanceof o))return!1;r.push(n),e.push(t);var c,f;if("[object Array]"===u){if(c=n.length,f=c===t.length)for(;c--&&(f=b(n[c],t[c],r,e)););}else{var s,p=h.keys(n);if(c=p.length,f=h.keys(t).length===c)for(;c--&&(s=p[c],f=h.has(t,s)&&b(n[s],t[s],r,e)););}return r.pop(),e.pop(),f};h.isEqual=function(n,t){return b(n,t,[],[])},h.isEmpty=function(n){if(null==n)return!0;if(h.isArray(n)||h.isString(n)||h.isArguments(n))return 0===n.length;for(var t in n)if(h.has(n,t))return!1;return!0},h.isElement=function(n){return!(!n||1!==n.nodeType)},h.isArray=f||function(n){return"[object Array]"===l.call(n)},h.isObject=function(n){var t=typeof n;return"function"===t||"object"===t&&!!n},h.each(["Arguments","Function","String","Number","Date","RegExp"],function(n){h["is"+n]=function(t){return l.call(t)==="[object "+n+"]"}}),h.isArguments(arguments)||(h.isArguments=function(n){return h.has(n,"callee")}),"function"!=typeof/./&&(h.isFunction=function(n){return"function"==typeof n||!1}),h.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},h.isNaN=function(n){return h.isNumber(n)&&n!==+n},h.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"===l.call(n)},h.isNull=function(n){return null===n},h.isUndefined=function(n){return n===void 0},h.has=function(n,t){return null!=n&&c.call(n,t)},h.noConflict=function(){return n._=t,this},h.identity=function(n){return n},h.constant=function(n){return function(){return n}},h.noop=function(){},h.property=function(n){return function(t){return t[n]}},h.matches=function(n){var t=h.pairs(n),r=t.length;return function(n){if(null==n)return!r;n=new Object(n);for(var e=0;r>e;e++){var u=t[e],i=u[0];if(u[1]!==n[i]||!(i in n))return!1}return!0}},h.times=function(n,t,r){var e=Array(Math.max(0,n));t=g(t,r,1);for(var u=0;n>u;u++)e[u]=t(u);return e},h.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))},h.now=Date.now||function(){return(new Date).getTime()};var _={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},w=h.invert(_),j=function(n){var t=function(t){return n[t]},r="(?:"+h.keys(n).join("|")+")",e=RegExp(r),u=RegExp(r,"g");return function(n){return n=null==n?"":""+n,e.test(n)?n.replace(u,t):n}};h.escape=j(_),h.unescape=j(w),h.result=function(n,t){if(null==n)return void 0;var r=n[t];return h.isFunction(r)?n[t]():r};var x=0;h.uniqueId=function(n){var t=++x+"";return n?n+t:t},h.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var A=/(.)^/,k={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},O=/\\|'|\r|\n|\u2028|\u2029/g,F=function(n){return"\\"+k[n]};h.template=function(n,t,r){!t&&r&&(t=r),t=h.defaults({},t,h.templateSettings);var e=RegExp([(t.escape||A).source,(t.interpolate||A).source,(t.evaluate||A).source].join("|")+"|$","g"),u=0,i="__p+='";n.replace(e,function(t,r,e,a,o){return i+=n.slice(u,o).replace(O,F),u=o+t.length,r?i+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'":e?i+="'+\n((__t=("+e+"))==null?'':__t)+\n'":a&&(i+="';\n"+a+"\n__p+='"),t}),i+="';\n",t.variable||(i="with(obj||{}){\n"+i+"}\n"),i="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+i+"return __p;\n";try{var a=new Function(t.variable||"obj","_",i)}catch(o){throw o.source=i,o}var l=function(n){return a.call(this,n,h)},c=t.variable||"obj";return l.source="function("+c+"){\n"+i+"}",l},h.chain=function(n){var t=h(n);return t._chain=!0,t};var E=function(n){return this._chain?h(n).chain():n};h.mixin=function(n){h.each(h.functions(n),function(t){var r=h[t]=n[t];h.prototype[t]=function(){var n=[this._wrapped];return i.apply(n,arguments),E.call(this,r.apply(h,n))}})},h.mixin(h),h.each(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=r[n];h.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!==n&&"splice"!==n||0!==r.length||delete r[0],E.call(this,r)}}),h.each(["concat","join","slice"],function(n){var t=r[n];h.prototype[n]=function(){return E.call(this,t.apply(this._wrapped,arguments))}}),h.prototype.value=function(){return this._wrapped},"function"==typeof define&&define.amd&&define("underscore",[],function(){return h})}).call(this); 6 | //# sourceMappingURL=underscore-min.map -------------------------------------------------------------------------------- /ornekler/ornek1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /ornekler/ornek2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /ornekler/ornek3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /ornekler/ornek4.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /ornekler/ornek5.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /ornekler/ornek6.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /ornekler/src/01_merhaba_dunya.js: -------------------------------------------------------------------------------- 1 | var MerhabaDunya = React.createClass({ 2 | render: function () { 3 | return
Merhaba Dunya
; 4 | } 5 | }) 6 | 7 | React.render(, document.body); 8 | -------------------------------------------------------------------------------- /ornekler/src/02_selamlama.js: -------------------------------------------------------------------------------- 1 | var MerhabaDunya = React.createClass({ 2 | render: function () { 3 | return
Merhaba Dunya
; 4 | } 5 | }); 6 | 7 | var Selamlama = React.createClass({ 8 | render: function () { 9 | return ( 10 |
11 | 12 | 13 |
) 14 | } 15 | }) 16 | 17 | React.render(, document.body) 18 | -------------------------------------------------------------------------------- /ornekler/src/03_selamlama_props.js: -------------------------------------------------------------------------------- 1 | var MerhabaDunya = React.createClass({ 2 | render: function () { 3 | return
Merhaba {this.props.isim}
4 | } 5 | }); 6 | 7 | var Selamlama = React.createClass({ 8 | render: function () { 9 | return
10 | 11 | 12 |
13 | } 14 | }) 15 | 16 | React.render(, document.body) 17 | -------------------------------------------------------------------------------- /ornekler/src/04_sayac.js: -------------------------------------------------------------------------------- 1 | var Sayac = React.createClass({ 2 | getInitialState: function () { 3 | return {sayac: 0}; 4 | }, 5 | 6 | artir: function () { 7 | var suAnkiSayac = this.state.sayac; 8 | this.setState({sayac: suAnkiSayac + 1}); 9 | }, 10 | 11 | render: function () { 12 | return ( 13 |
14 | Sayaca {this.state.sayac} kez tıkladınız 15 | 16 |
) 17 | } 18 | }) 19 | 20 | 21 | 22 | React.render(, document.body); 23 | -------------------------------------------------------------------------------- /ornekler/src/05_sayac_gerisayim.js: -------------------------------------------------------------------------------- 1 | var Sayac = React.createClass({ 2 | getInitialState: function () { 3 | return {sayac: 0}; 4 | }, 5 | 6 | artir: function () { 7 | var suAnkiSayac = this.state.sayac; 8 | this.setState({sayac: suAnkiSayac + 1}); 9 | }, 10 | 11 | render: function () { 12 | return ( 13 |
14 | Sayaca {this.state.sayac} kez tıkladınız. 15 | {10 - this.state.sayac} kez daha tıklamalısınız. 16 | 17 |
18 | ); 19 | } 20 | }) 21 | 22 | React.render(, document.body); 23 | -------------------------------------------------------------------------------- /ornekler/src/06_sayaclar.js: -------------------------------------------------------------------------------- 1 | var Sayac = React.createClass({ 2 | 3 | render: function () { 4 | return ( 5 |
6 | Sayaca {this.props.sayac} kez tıkladınız. 7 | {10 - this.props.sayac} kez daha tıklamalısınız. 8 | 9 |
); 10 | } 11 | }); 12 | 13 | 14 | var Sayaclar = React.createClass({ 15 | getInitialState: function () { 16 | return {sayac1: 3, sayac2: 5}; 17 | }, 18 | 19 | sayac1Artir: function () { 20 | this.setState({sayac1: this.state.sayac1 + 1, 21 | sayac2: this.state.sayac2 - 1}); 22 | }, 23 | 24 | sayac2Artir: function () { 25 | this.setState({sayac1: this.state.sayac1 - 1, 26 | sayac2: this.state.sayac2 + 1}); 27 | }, 28 | 29 | render: function () { 30 | return ( 31 |
32 | 33 | 34 |
); 35 | } 36 | }) 37 | 38 | 39 | React.render(, document.body); 40 | --------------------------------------------------------------------------------