Redux Nedir ?

October 14, 2020

Bu yazımda size redux kavramından bahsetmek istiyorum. Redux nedir ? Neden Redux ihtiyaç duyuyoruz ? Redux terimleri nelerdir ? Bütün bu soruların cevaplarını bu yazımda bulabileceksiniz.

İlk önce Redux, React in için vazgeçilmez bir parçası değildir. Redux, state management olarak bilinir. Yani stateleri yönetmemizi sağlayan bir javascript kütüphanesidir. Küçük uygulamalar için çok gerekli bir kütüphane gibi görünmesede, büyük uygulamalarda state yönetimimizi çok kolaylaştırıyor. Ama tabiki redux kütüphanesini her projemizde kullanmak zorunda değiliz.

Şimdi biraz Redux terimlerinden bahsedelim. Nedir bu Actions, Dispatcher, Store ve Reducer ?

redux-shema

View : Yukarıda ki akış şemasında gördüğünüz view kısmı, altında da yazdığı gibi bizim componentlerimizdir. Kullanıcının gördüğü ekranlardır.

Actions : Kullanıcının yaptığı işlemler ( buttona tıklamak ) ile oluşan datayı store gönderme işlemini yapıyor.

Dispatcher: Action da bulunan datayı store gönderme işlemine dispatcher etmek denir.

Store : State tutan bir javascript objesidir.

Reducer : Storeda ki datayı güncelleme işlemini yapar. Actiondan store gelen datayı alır, güncelleme işlemini yapar ve tekrardan store geri verir.

Şimdi github hesabımda oluşturacağım bir react projesi ile redux kütüphanesi nasıl kullanılır görmüş olucaksınız. Projeyi burada birlikte yapıcağız. Tabi ki isteyen projenin source kodlarına buradan ulaşabilir.

Projeye geçmeden önde projemizde ki store durumunu görüntülememizi sağlayan redux DevTools eklentisini crome tarayıcınıza lütfen kurunuz. Bu eklenti sayesinde store görüntüleyebiliriz, bir önceki state ile şimdiki state farklarını inceleyebiliriz ve bunlar gibi birçok işlemi bu eklenti sayesinde yapabiliriz. Eklentiyi projemize burada bahsedildiği gibi ekleyebiliriz.

Terminalden create-react-app redux ile projemizi oluşturuyoruz. Daha sonra redux ve react-redux paketlerini projemize dahil ediyoruz. Oluşturduğumuz src/redux/store klasörüne redux store oluşturuyoruz.

// src/redux/store/index.js
import { createStore } from 'redux';

import rootReducer from '../reducers/index';

const store = createStore(rootReducer,
    {
      user: {
        name: "Özgün",
        surname: "Özdemir"
    }
},
   window.__REDUX_DEVTOOLS_EXTENSION__ &&                         window.__REDUX_DEVTOOLS_EXTENSION__()
);
export default store;

Gördüğünüz gibi store da sadece user datamız var. Şimdi store projemizden erişebilmemiz için app.js provider ile sarmamız gerekiyor.

// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import { Provider } from 'react-redux';
import store from './redux/store/index';

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

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

react-redux dan import ettiğimiz Provider ile uygulamamızı sarmaladık. Props olarakta store verdik. Böylece store bütün componentlerimizden erişeceğiz.

Artık user için reducer ve action ları oluşturalım.

// src/redux/actions/userActions.js
const UPDATE_USER = 'UPDATE_USER';

const updateUser = (name, surname) => {
  return {
      type: 'UPDATE_USER',
        payload: {
            name: name,
            surname: surname
         }
      }

}

export { updateUser, UPDATE_USER };

Aslında action dediklerimiz bildiğimiz fonksiyonlardır. name ve surname diye parametre alıyor. Payload da name ve surname dönüyor.

// src/redux/reducers/userReducer.js
import { UPDATE_USER } from '../actions/index';

const userReducer = (state = [], action) => {
  switch(action.type){
      case UPDATE_USER: 
      return action.payload;

      default:
       return state;
    }
}

export default userReducer;

Reducer larda action lar gibi birer fonsiyonlardır. Action type göre farklı işlemler yapıp store daki datayı güncelliyorlar. Yukarıda ki userReducer fonksiyonumuzda da gördüğünüz gibi UPDATE_USER action type da return olarak action.payload daki data dönüyor.

Reducer, action ve store oluşturmayı inceledik. Peki yazdığımız bir component de action nasıl tetikliyeceğiz ? Store nasıl ulaşacağız ? Şimdi ise bu soruların cevaplarına bakalım.

App.js componenttimizden store bağlantı sağlayalım. Bunu connect metodu ile yapıyoruz. Storeda ki dataya ulaşmak için ise mapStateToProps tanımı ile erişiyoruz. Bununla ilgili kodu aşağıda paylaşıyorum.

// src/App.js
import React, { Component } from "react";
import { connect } from "react-redux";

class App extends Component {
  render() {
    return (
      <div>
        <span>
          Merhaba {this.props.user.name} {this.props.user.surname}
        </span>
      </div>
    );
  } 
}

const mapStateToProps = state => ({
  user: state.user
});

export default connect(mapStateToProps)(App);

Projeyi npm run start komutu ile çalıştırdığınızda Merhaba Özgün Özdemir çıktısını görürsünüz. Özgün Özdemir bizim store daki user initial statemiz. Peki bu initial state action ile nasıl değiştiriyoruz. Bunun için de mapDispatchToProps tanımını kullanıyoruz. Redux action da yazığımız updateUser metodunu App.js import ediyoruz. mapDispatchToProps ile de action ı props a aktarıyoruz. Böylece metodu kullanbilecek duruma getiriyoruz.

Aşağıda App.js son halini paylaşıyorum.

// src/App.js
import React, { Component } from "react";
import { connect } from "react-redux";
import { updateUser } from "./redux/actions/index";

class App extends Component {
  constructor(props) {
    super(props);
  }

  onChangeName = () => {
    this.props.onUpdateUser('Software', 'Developer');
  };

  render() {
    return (
      <div>
        <span>
          Merhaba {this.props.user.name} {this.props.user.surname}
        </span><br />
        <button onClick={this.onChangeName}>Change Name</button>
      </div>
    );
  }
}

const mapStateToProps = state => ({
  user: state.user
});

const mapDispatchToProps = {
  onUpdateUser: updateUser
};

export default connect(mapStateToProps, mapDispatchToProps)(App);

Gördüğünüz gibi Change Name butonuna tıklayınca this.props.onUpdateUser(‘Software’, ‘Developer’) ile action iki parametre gönderiyorum. Böylece önceden hazırladığım action ile name ve surname değişiyor.

Projeyi buradan alıp source kodlarına erişebilir ve daha detaylı projeyi inceleyebilirsiniz. Projeyi çalıştırarak store güncellendiğini görebilirsiniz.

Elimden geldiğince redux ı temel bir şekilde anlatmaya çalıştım. Tabi redux biraz karışık bir konudur. Dikkat edilmesi gereken birçok noktalar var. İleri ki yazılarımda belki onlardan bahsederim. Ama temel olarak redux nedir ? Redux neden ihtiyaç duyarız ? Nedir bu redux terimleri ? Bütün bu soruların cevaplarını bu yazımda vermiş olduğumu düşünüyorum. Umarım başarılı olmuşumdur. Diğer yazımda tekrardan görüşmek üzere …

Share: