Mobx Nedir, Nasıl Kullanılır?

Mobx oluşturmak istediğiniz uygulamalar üzerinde veri yönetimini kolaylaştıran bir kütüphane. SPA(Single Page Application) oluşturma konusunda karşılaşılan mühim sorunlardan biri de veri(state) yönetimi ve uygulamanın yaşam döngüsü boyunca barındırdığı verilerin geçirdiği değişiklikleri tespit etmek.

Dolayısıyla, birçok “component” barındıran bir uygulamanızın çeşitli aşamalarında söz konusu verileri değiştirmek, tekrardan kullanılabilir hale getirmek çok önemli. Çünkü yapınız ve uğraştığınız veri tipi büyüdükçe, iş içinden çıkılmaz bir hale gelebiliyor.

Mobx’in burada avantajlı olduğu konular, özellikle güçlü bir kütüphane olan Redux’a göre, “daha basit ve kullanışlı olması”, “hafif bir çözüm olarak” tanımlanabilmesi diyebiliriz. Özellikle varolan uygulamanıza mobx’i eklemek oldukça kolay.

Mobx’le küçük bir örnek yapmaya başlamadan önce kullanacağımız bazı kavramları açıklamakta fayda var.

@observable

Mobx ile birlikte öncelikle bir “store” oluşturmamız gerekiyor. “Store”u es6 ile birlikte gelen class özelliğiyle oluşturuyoruz ve “component”lara, dizinlere eklemleyebileceğimiz “observable decorator” ile kullanabileceğimiz değişkenler yaratıyoruz. Bu uygulamamız içerisinde merkez bir yerden kullanabileceğimiz ve iletişimi artıracak değişkenler yaratmamıza olanak veriyor.

Örnek olarak;

@observable degisken_ismi = degisken_degeri;

@computed

Computed, store’unuz içerisinde tanımladığınız bir observable bir değişken herhangi bir değişikliğe uğradığında devreye girip yaşamını başlatan değerlerdir. Gerektiğinde çalışır ve önemli bir performans etkisi yaratabilir.

@action

Action, ugulamamız içerisinde istediğimiz yerden erişebileceğimiz fonksiyonlar olarak tanımlanabilir. Mobx store’unu yönetmekte işlevsellik katarlar.

Örnek Kullanım

Ufak bir örnek yapacağız. Bunun için create-react-app ile projemizi oluşturuyoruz. Ve projeye mobx ile mobx-react paketlerini dahil ediyoruz.

npx create-react-app my-app
yarn add mobx
yarn add mobx-react

Mobx’le birlikte decorator’leri kullanacağız ve tarayacıların yazdığımız kodları anlayabilmesi için bir babel plugin’inini uygulamamızın çevirici araçlarına eklememiz gerekiyor. Öncelikle config’leri dışarı çıkarmamız gerekiyor.

yarn eject

Sonrasında gerekli olan babel plugin’inin projeye eklememiz gerekiyor.

yarn add babel-plugin-transform-decorators-legacy

Sonrasında package.json dosyasına babel plugin’i olarak eklediğimiz plugin’i tanımlamamız gerekiyor.

...
"babel": {
"presets": [
"react-app"
],
"plugins": [
"transform-decorators-legacy"
]
},
...

Şimdi src dizini altında bir store oluşturmamız gerekiyor. Store.js adında bir dosya oluşturuyoruz ve içerisindde mobx store’unu tanımlayacağız.

import { observable, action } from "mobx";

class MainStore {

}

const store = new MainStore();
export default store;

Dosyamıza mobx içerisinden kullanmak üzere observable ve action’i dahil ettik. Sonra da MainStore adında bir class tanımlayıp kullanabilir kıldık.

Bu aşamada @observable degisken_adi ile izlenebilir değişkenler tanımlamamız gerekiyor. Ancak burada bir hatırlatma yapalım. Vscode ile birlikte bu şekilde bir kullanım bir hata çıktısı yaratacaktır ve tanımladığınız değişkenin hatalı olarak gösterecektir. Bu durumu engellemek için; proje kök dizinine jsconfig.json adında bir config tanımlayıp içerisinde şu şekilde bir tanımlama yapmak gerekiyor.

{
"compilerOptions": {
"experimentalDecorators": true
}
}

Sonrasında store dosyamızın içerisinde verilerimizi oluşturabiliriz. Öncelikle “firstName” ve “lastName” “property”leri olan user adında bir “object” oluşturacağız.

import { observable, action } from "mobx";

export default class MainStore {
@observable user = {
firstName: "Erdem",
lastName: "Uslu"
}
}

const store = new MainStore();
export default store;

Sonrasında oluşturduğumuz store’u uygulamamız içerisinde kullanılabilir hale getirmemiz gerekiyor. index.js üzerinde mobx-react paketinden alacağımız Provider ile render edeceğimiz uygulamaya store’u props olarak göndereceğiz.

.... // Provider import { Provider } from 'mobx-react';
// Store
import MainStore from './store';

ReactDOM.render(<Provider MainStore={MainStore}><App /></Provider>, document.getElementById('root'));

Artın MainStore olarak ekleyeceğimiz her alt component’da kullanabileceğimiz bir store söz konusu. Bunu App.js’de çağıralım;

...
import { inject, observer } from 'mobx-react';

@inject('MainStore')
@observer
...

Temiz bir kullanımla App.js içerisinde store’u tanımladık ve kullanılabilir hale getirdik. Jsx return olmadan önce söz konusu store’a props olarak erişebiliriz artık.

import { inject, observer } from 'mobx-react';

@inject('MainStore')
@observer

class App extends Component {
render() {
const user = this.props.MainStore.user;
console.log(user.firstName);
console.log(user.lastName);
return (
...

Söz konusu store’u uygulamamız içerisinde istediğimiz yerde inject edebilir ve bu şekilde kullanabiliriz. Değiştirmek içinse @action kullanmamız gerekiyor.

Tekrar store.js’e dönüyoruz ve action metodunu dahil edip changeName adında bir action tanımlıyoruz.

import { observable, action } from "mobx";

class MainStore {
@observable user = {
firstName: "Erdem",
lastName: "Uslu"
}

@action changeName(firstName, lastName) {
this.user.firstName = firstName;
this.user.lastName = lastName;
}
}

const store = new MainStore();
export default store;

Bu action’u uygalamamız içerisinde tetiklediğimizde, artık store’da tuttuğumuz observable değişkenlere müdahale edebiliriz. Tetiklemek için;

import React, { Component } from 'react';
import './App.css';
import { inject, observer } from 'mobx-react';

@inject('MainStore')
@observer

class App extends Component {
render() {
const user = this.props.MainStore.user;
return (
<div className="App">
{user.firstName} {user.lastName}
<button onClick={() => this.props.MainStore.changeName("Algün", "Akgündüz")}>Değiştir</button>
</div>
);
}
}

export default App;

MainStore props’u üzerinden eriştiğimiz changeName metoduyla observable state’i güncellemiş bulunduk. Bu şekilde eklemlediğimiz her component’ta, mobx store’una erişebilir ve değişkenleri modifiye edip, kullanabiliriz.

Anlatımı gözden geçirerek gerekli yerlerde düzeltmelerde bulunan Tahsin Cem Yılmaz’a çok teşekkürler.