Friday, May 24, 2019

Vue

The Progressive Javascript Framework

Vue.js has become an extremely
popular JavaScript framework
..............................................................................................................................................................................................................................
Extensions
https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd?utm_source=chrome-ntp-icon







................................................................................................................................................................................................................................

Example :#1 [Global Installations Using CLI ]
npm install -g @vue/cli

OR
yarn global add @vue/cli
Link for more info   --> https://cli.vuejs.org/guide/




Check the version : vue --version




Example :#2 [How to create a New Project]
vue create projectName
vue create hello-world


..................................................................................................................................................................................................................................
Example :#3

..................................................................................................................................................................................................................................
Example :#4

..................................................................................................................................................................................................................................
Example :#5

..................................................................................................................................................................................................................................
Example :#6

..................................................................................................................................................................................................................................
Example :#7  [ props in vue js ]

Child.vue
<template>
    <div>
        <h2> Child</h2>
        <h3>{{name}}</h3>
    </div>
</template>
<script>
export default {
    name:'Child',
    props:['name']
}

</script>
........................................
App.vue
<template>
  <div>
    <Child name ='Sapan Kumar Das'/>
  </div>
</template>

<script>
import Child from "./components/child";
export default {
  name: "App",
  components: {
    Child
  }
};
</script>
..............................................................................................................................................................................................................................
Example :#8  [ props in vue js  pass some properties using v-bind ]

Child.vue
<template>
    <div>
        <h2> Child</h2>
        <h3>{{name}}</h3>
    </div>
</template>
<script>
export default {
    name:'Child',
    props:['name']
}

</script>
...............................
App.vue

<template>
  <div>
    <h3>{{title}}</h3>
    <Child v-bind:name ='value'/>
  </div>
</template>

<script>
import Child from "./components/child";
export default {
  name: "App",
  components: {
    Child
  },
  data:function(){
    return{
      value:'Johan Smith'
    }
  }
};

</script>
............................................................................................................................................................................................................................
Example :#9 [props in vue js  pass some properties using v-bind ]

Child.vue
<template>
    <div>
        <h2> Child</h2>
        <ul>
            <li v-for=" u in users" :key='u.id'>
                {{u.name}}
                {{u.email}}
            </li>
        </ul>
    </div>
</template>
<script>
export default {
    name:'Child',
    props:['users']
}

</script>
........................................
App.vue
<template>
  <div>
    <h3>{{title}}</h3>
    <Child v-bind:users ="users"/>
  </div>
</template>

<script>
import Child from "./components/child";
export default {
  name: "App",
  components: {
    Child
  },
  data:function(){
    return{
      users:[
        { name:'Sapan', email:'sapan@gmail.com'},
        { name:'johan', email:'johan@gmail.com'
      }]
    }
  }
};
</script>
<style>
...............................................................................................................................................................................................................................
Example :#10 [ props child to parent component]

Child.vue
<template>
<div>
    <h2>Child Component </h2>
    <button v-on:click="updateTitle"> Update Parent Title</button>
</div>
</template>
<script>
export default{
    name:'Child',
    methods:{
        updateTitle(){
            this.$emit('changeTitle', 'data update successfully')
        }
    }
}
</script>
.........................................
App.vue

<template>
  <div>
    <h3>{{title}}</h3>
    <SimpleTodo />
    <Child v-on:changeTitle="update($event)" />
  </div>
</template>
<script>
import Child from "./components/child";
export default {
  name: "App",
  components: {
    Child,
  },
  data:function() {
    return {
      title: "props tutorial"
    };
  },
  methods: {
    update(title) {
      this.title = title;
    }
  }
};
</script>
...............................................................................................................................................................................................................................


...............................................................................................................................................................................................................................
Vue Router Basics

Istallation
yarn add vue-router

Step :#1
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)

const router = new VueRouter({
mode:'history',
  routes:[
    {path:'/' ,component:Home},
    {path:'/about' ,component:About},
    { path:'/profile', component:Profile}
  ]
}
...................
Step :#2
import { router } from './component/router'
new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

Example :#1

route.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import About from './components/About'
import Profile from './components/Profile'

Vue.use(VueRouter)
export const router = new VueRouter({
    mode: 'history', // remove extra '/#/
    routes: [
        { path: '/', component: About },
        { path: '/profile', component: Profile }
    ]
})
..........................................
App.vue
<template>
  <div>
    <h3>Basic Router</h3>
    <nav>
      <ul>
        <li>
          <router-link to ='/'>About</router-link>
        </li>
        <li>
          <router-link to ='/profile'>Profile</router-link>
        </li>
      </ul>
    </nav>
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: "App"
};
</script>
.........................................
main.js
import Vue from 'vue'
import App from './App.vue'

import store from './store'
Vue.config.productionTip = false

import {router } from './route'

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

...............................................................................................................................................................................................................................


...............................................................................................................................................................................................................................



...............................................................................................................................................................................................................................


...............................................................................................................................................................................................................................


...............................................................................................................................................................................................................................
 vuex
Example :#1 [ How to install vuex]
vue add vuex
or 
yarn add vuex

Vue vs Vuex

LifeCycle


view components ---> Dispatch ---> Actions ---> commit ---> Mutations ----> mutate ---> State
....................................................................................................................................................................................................................................
Example :#2 [ Basic setup with display data ]
....................................................
Folder Structure

....................................................
components/Todos.vue
<template>
 <div class="app">
     <h4> Todos</h4>
     <ul>
         <li v-for="All in allTodos" :key="All.id">{{All.name}}
         </li>
     </ul>

 </div>
</template>

<script>
import { mapGetters} from  'vuex'
export default {
    name : 'Todo',
    computed: mapGetters(['allTodos'])
}

</script>
....................................................
store/modules.Todos.js
const state ={
    Todos :[
        {
            id:1,
            name :'Johan Smith'
        },
        {
            id:2,
            name :'Johan Doe'
        },
    ]
};
const getters ={
    allTodos : state=>state.Todos
};

export default {
    state,
    getters,
}
.....................................................
store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
import Todos from './modules/Todos'

Vue.use(Vuex)
export default new Vuex.Store({
  modules: {
    Todos
  }
})
........................................
App.vue
<template>
  <Todo />
</template>

<script>
import Todo from "./components/Todo";
export default {
  name: "App",
  components: {
    Todo
  }
};

</script>
..............................................
main.js
import Vue from 'vue'
import App from './App.vue'
import store from './store'

Vue.config.productionTip = false

new Vue({
  store,
  render: h => h(App)
}).$mount('#app')


Happy Coding :)
...............................................................................................................................................................................................................................
Example :#3 [ How to fetch Data using Axios]
install Axios
yarn add axios

.................................................
store\modules\Todo.js
import Axios from 'axios';
const state = {
    todos: []
};

const getters = {
    AllTodos: (state) => state.todos
};
const mutations = {
    setTodos: (state, todos) => (state.todos = todos)
};
const actions = {
    async fetchTodos({ commit }) {
        const reponse = await Axios.get('https://jsonplaceholder.typicode.com/todos')
        console.log(reponse.data)
        commit('setTodos', reponse.data)
    }
};
export default {
    state,
    getters,
    mutations,
    actions

}
.......................................
store\modules\index.js

import Vue from 'vue';
import Vuex from 'vuex';
import Todos from './modules/Todo'

Vue.use(Vuex)
export default new Vuex.Store({
    modules:{
        Todos
    }

})
..............................................
Todos.vue

<template>
  <div class="app">
    <h3>Todos</h3>
    <ul>
      <li v-for="AllTodo in AllTodos" :key="AllTodo.id">{{AllTodo.title}}</li>
    </ul>
  </div>
</template>

<script>
import { mapGetters, mapActions } from "vuex";
export default {
  name: "Todos",
  methods: {
    ...mapActions(["fetchTodos"])
  },
  computed: mapGetters(["AllTodos"]),
  created(){
      this.fetchTodos()
  }
};
</script>
.......................................
App.vue
<template>
  <Todo />
</template>

<script>
import Todo from "./components/Todos";
export default {
  name: "App",
  components: {
    Todo
  }
};
</script>



Happy Coding :)
...............................................................................................................................................................................................................................
Example :#4 [ How to install vuex]


...............................................................................................................................................................................................................................
Example :#5 [ How to install vuex]



...............................................................................................................................................................................................................................
Example :#6 [ How to install vuex]


...............................................................................................................................................................................................................................
Example :#7 [ How to install vuex]



...............................................................................................................................................................................................................................
Example :#3 [ How to install vuex]




To get started, use the following command.

cd myproject
npm install
npm run dev


...............................................................................................................................................................................................................................
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
</head>
<title>Vue js</title>

<body>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <div id='app'>
      <h1>{{msg}}</h1>
    </div>

   <script>
        var myObj = new Vue({
            el: '#app',
            data: { msg: 'Vue js from scrath' }
        })
    </script>
</body>
</html>
...........................................................................................................................................................................................................................
v-text

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
</head>
<title>Vue js</title>

<body>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

    <div id='app'>
        <h1>{{msg}}</h1>
        <p>{{content}}</p>
        <p v-text="content"></p>
        <button onClick='myFunc()'>Click here</button>
    </div>

    <script>
        var myObj = new Vue({
            el: '#app',
            data: {
                msg: 'Hello world' ,
                content:" Vue Content"
                }
        })
        function myFunc() {
            myObj.msg = 'Sapan Kumar Das'
        }
    </script>
</body>
</html>
..........................................................................................................................................................................................................................

..........................................................................................................................................................................................................................

..........................................................................................................................................................................................................................

Vue.js Binding

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
</head>
<title>Vue js</title>

<body>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

    <div id='app'>
        <h1>{{msg}}</h1>
        <button onClick='myFunc()'>Click here</button>
    </div>

    <script>
        var myObj = new Vue({
            el: '#app',
            data: { msg: 'Hello world' }
        })
        function myFunc() {
            myObj.msg = 'Sapan Kumar Das'
        }
    </script>
</body>
</html>
............................................................................................................................................................................................................................
Vue.js Two-Way Binding
The v-model directive binds the value of HTML elements to application data.

This is called two-way binding:

<h2>Vue.js</h2>

<div id='app'>
<h1>{{msg}}</h1>
<input v-model='msg'/>
</div>

<script>
var objMy = new Vue({
el:'#app',
data:{msg:'Hello Vue'}
})
</script>
...................................................................................................................................................................................................................................
Vue.js Loop Binding

<h2>Vue.js</h2>
<div id='app'>
<h1></h1>
<ul>
<li v-for='x in todos'>{{x.text}}</li>
</ul>

</div>

<script>
var myObj =new Vue({
el:'#app',
data:{
todos:[
{text:'Sapan kmar'},
{text:'Johan Doe'}
]
}

})
</script>

....................................................................................................................................................................................................................................
 event | how to use click event



<template>
  <div>
    <h2>{{text}}</h2>
    <button v-on:click="hello">About more</button>
    <button v-on:click="sapan">  Sapan</button>
  </div>
</template>
<script>
export default {
  name: "About",
  props: {
    text: String
  },
  methods:{
      hello(){
          console.log('hi...')
      },
      sapan(){
          console.log('bload')
      }
  }
};
</script>
....................................................................................................................................................................................................................................
....................................................................................................................................................................................................................................
........................................................................................................................................................................................................................................................................................................................................................................................................................................................................

Thursday, May 16, 2019

Saga

Fetching data from an API using Redux Saga




saga pattern

flow -->




Fetching and reducing return values in Saga is a two fold process: The yield call executes the API call. And yield put takes the fetched data and sends it to your reducer. The reducer then updates the state.


generator | What are Generators?
redux saga helps us manage the asynchronous flow of our application
really efficiently, one more things

-  It's simpler to test and better at handling failures
- Generators is similar to function but we need an asterisk after the function
- Generators returns  multiple value.
- Done value significant, finished its execution

Step -1 
Step -2

Step -3(Iterator)
Step -4 (Customize return)
Step -5 (Customize return)









Required some library
redux
react-redux
redux-saga

yarn add redux  react-redux  redux-saga

This is  my folder structure as below;



...............................................................................................................................................................................................................
src/constants/Type.js

Type.js

export const REQUEST_API_DATA = "REQUEST_API_DATA";
export const RECEIVE_API_DATA = "RECEIVE_API_DATA";


......................................................................................................................................................................................................................

src/actions/actionCreator.js

actionCreator.js


import { REQUEST_API_DATA, RECEIVE_API_DATA } from '../constants/Type'

export const requestApiData = () => {
    return {
        type: REQUEST_API_DATA
    }
}
export const receiveApiData = data => {
    return {
        type: RECEIVE_API_DATA,
        data
    }
}
..............................................................................................................................................................................................................................

src/reducers/reducer.js

reducer.js

import { RECEIVE_API_DATA } from '../constants/Type'
const initialState ={
  
}

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case RECEIVE_API_DATA:
      return action.data
    default:
      return state;
  }
};
export default reducer

...................................................................................................................................................................................................................................
src/reducers/index.js

index.js

import { combineReducers } from 'redux'
import reducer from './reducer';

const rootReducer =combineReducers({
    reducer
})

export default rootReducer
............................................................................................................................................................................................................................
src/sagas/dataSaga.js

dataSaga.js

import { call, put, takeLatest } from 'redux-saga/effects'
import { REQUEST_API_DATA } from '../constants/Type'
import { receiveApiData } from '../actions/actionCreator'
import { fetchApi } from '../api/api'


/**worker saga */

function* workerSaga(action) {
    try {
        const response = yield call(fetchApi)
        yield put(receiveApiData(response.data))
    }
    catch (e) {
        console.log(e)
    }
}
/** watcher saga */

function* watcherSaga() {
    yield takeLatest(REQUEST_API_DATA, workerSaga)
}
export default watcherSaga

........................................................................................................................................................................................................................
src/store/store.js

store.js

import { createStore, applyMiddleware } from "redux";
import createSagaMiddleware from "redux-saga";
import rootReducer from "../reducers/index";
import watcherSaga from "../sagas/dataSaga";

const sagaMiddleware = createSagaMiddleware()

const configureStore=()=>{
    const store= createStore(
        rootReducer, applyMiddleware(sagaMiddleware)
    )
    sagaMiddleware.run(watcherSaga)
    return store
}
export default configureStore


.....................................................................................................................................................................................................................
src/components/Home.js

Home.js

import React, { Component } from 'react'
import { connect } from 'react-redux'
import { requestApiData } from '../actions/actionCreator';

class Home extends Component {
    componentDidMount() {
        this.props.requestApiData();
    }

    person = (item, index) =>
        <div key={index}>
            <h1> {item.gender}</h1>
            <h1> {item.name.title}</h1>
            <h1> {item.name.first}</h1>
            <h1>{item.name.last}</h1>
            <img src={item.picture.medium} />
        </div>

    render() {
        const { results = [] } = this.props.hello;
      //  return results.length ? <h1></h1> :    <h1></h1>
        return results.length
            ? <h1>
                {results.map(this.person)}
            </h1>
            : <h1>loading...</h1>;
    }
}

/**
    render() {
        const { results=[]}=this.props.data
        return (
            < div >
                <h1>{results.map(this.person)}</h1>
            </div >

*/





const mapStateToProps = state => {
    return {
        hello: state.reducer
    }
}

const mapDispatchToProps = dispatch => {
    return {
        requestApiData: () => dispatch(requestApiData())
    }
}

const Home1 = connect(mapStateToProps, mapDispatchToProps)(Home)
export default Home1
....................................................................................................................................................................................................................
/
src/App.js

App.js
import React, { Component, } from 'react'
import { Provider} from 'react-redux'

import configureStore from './store/store'

import Home1 from './components/Home'

const store = configureStore()

export default class App extends Component {
  render() {
    return (
      <Provider store={store}>
        <Home1 />
      </Provider>
    )
  }
}
...................................................................................................................................................................................................................................
src/api/api.js

api.js
export const fetchApi = async () => {
    try {
      const response = await fetch("https://randomuser.me/api");
      const data = await response.json();
      return data;
    } catch (e) {
      console.log(e);
    }
  };

bcoz redux-saga,  Each yield in a generator basically represents an asynchronous step in a more synchronous/sequential process — somewhat like await in an async function.

const fetch=()=>{
    return axios({
        method:'get',
        url:'https://randomuser.me/api'
    })
}



...............................................................................................................................................................................................................................

















.........................................................................................................................................................................................................................

Redux Saga | Redux 

export const FETCH_DATA = 'FETCH_DATA';
export const FETCH_DATA_SUCCESS =  'FETCH_DATA_SUCCESS';
..............................................................................................................................................................................................................................
saga.js

import { FETCH_DATA, FETCH_DATA_SUCCESS } from '../constants/actionType'
import { call, put, takeEvery } from 'redux-saga/effects'


function* workerSaga(){
   const data= yield call(()=>
    fetch('https://httpbin.org/get')
    .then((res)=> res.json())
   )
    //yield put({type: FETCH_DATA_SUCCESS, data})
    yield put({type: FETCH_DATA_SUCCESS,  payload:{data}})
}


function* watcherSaga(){
    yield takeEvery(FETCH_DATA, workerSaga)
}

export default watcherSaga

....................................................................................................................................................................................................................................
reducer.js

import { FETCH_DATA, FETCH_DATA_SUCCESS } from '../constants/actionType'
import { combineReducers } from 'redux'
const initialState = {
    data: {}
}

const reducer = (state = initialState, action) => {
    switch (action.type) {
        case FETCH_DATA_SUCCESS:
            return {
                ...state,
                //data:action.data
                 data: action.payload.data 
            }
        default:
            return state
    }
}

const AllReducer = combineReducers({
    nav:reducer
})
export default AllReducer
..................................................................................................................................................................................................................................
Home.js

import React, { Component, useEffect } from 'react'
import { connect } from 'react-redux'
import { FETCH_DATA } from '../constants/actionType'
class Home extends Component {

    componentDidMount() {
        this.props.fetchData()

    }
    render() {
        const {results}=this.props
        return (
            <div>{JSON.stringify(results)}</div>
        )
    }
}

OR
/**
const Home = ({results, fetchData}) => {
    useEffect(() => {
      fetchData();
    },[]);
  
    return (
      <div>
        {JSON.stringify(results)}
      </div>
    );
  };

*/



const mapStateToProps = (state) => {
    return {
        results: state.nav.data
    }
}
const mapDispatchToProps = (dispatch) => {
    return {
        fetchData: () => dispatch({ type: FETCH_DATA })
    }
}
export default connect(mapStateToProps, mapDispatchToProps)(Home)

...........................................................................................................................................................................................................................................
App.js

import React, { Component } from 'react'
import { Provider } from 'react-redux'
import { createStore, applyMiddleware } from 'redux'
import createSagaMiddleware from 'redux-saga';
import Home from './components/Home'
import watcherSaga from './sagas/saga'
import AllReducer from './reducers/reducer'

const sagaMiddleware = createSagaMiddleware()

const store = createStore(AllReducer, applyMiddleware(sagaMiddleware))

export default class App extends Component {
  render() {
    return (
      <Provider store={store}>
        <Home/>
      </Provider>
    )
  }
}
sagaMiddleware.run(watcherSaga)

.................................................................DONE.................................................................................

..................................................................................................................................................................................................................................
import React, { Component } from 'react';
import { View, Text } from 'react-native'

class App extends Component {
  state = {
    todos: {}
  }
  componentDidMount = () => {
    // fetch('http://jsonplaceholder.typicode.com/todos/1')
    fetch('https://jsonplaceholder.typicode.com/users')
      .then(res => res.json())
      .then((data) => {
        console.log(data)
        this.setState({ todos: data })
        console.log(this.state.todos)
      })
      .catch(console.log)
  }
  render() {
    const  users = this.state.todos
    return (
      <View>
        {users.length ? (users.map((item, index) => <Text>{item.name}</Text>)) : (<Text>Loading...</Text>)}
      </View>
    )
  }

}
export default App;
..........................................................................................................................................................................................................................
import React, { Component } from 'react'
import { View, Text, ActivityIndicator } from 'react-native'

class App extends Component {
   constructor(props) {
      super(props)
      this.state = {
         todos: []
      }
   }
 
   componentDidMount() {
      fetch(`https://jsonplaceholder.typicode.com/posts/?id=${1}`,{
         method:'GET'
      })
      .then(res => res.json())
      .then((data) => {
        this.setState({ todos: data })
        console.log(this.state.todos)
      })
      .catch(console.log)
    }

   render() {
      return (
         <View>
            {this.state.todos.map((item, index)=>{
              return(
                <View>
                  <Text>{item.title}</Text>
                </View>
              )
            })}
         </View>
      )
   }
}
export default App

..............................................................................................................................................................................................................................
import React, { Component } from 'react'
import { View, Text, ActivityIndicator } from 'react-native'

class App extends Component{
  constructor(props){
    super(props)
    this.state={
      users:[]
    }
  }
  componentDidMount(){
    fetch('https://jsonplaceholder.typicode.com/users')
    .then(res=>res.json())
    .then(responseJson=>{
      console.log(responseJson)
      this.setState({
        users:responseJson
      })
    })
  }
  render(){
    const user = this.state.users
    return(
      <View>
        {user.length ? (user.map((item, index)=><View key={index.toString()}><Text>{item.name}</Text></View>)):(<ActivityIndicator size='large' color='red'></ActivityIndicator>)}
      </View>
    )
  }
}
export default App

Happy coding :)
..........................................................................................................................................................................................................................

redux-saga with functional component


src\constants\Type.js

export const REQUEST_API_DATA = 'REQUEST_API_DATA'
export const RECEIVE_API_DATA = 'RECEIVE_API_DATA'

src\actions\actionCreators.js

export const requestApiData = () => {
    return {
        type: Type.REQUEST_API_DATA
    }
}

export const receieveApiData = data => {
    return {
        type: Type.RECEIVE_API_DATA,
        payload: data
    }
}
src\reducers\nameReducer.js

import { RECEIVE_API_DATA } from '../constants/Type'
const initialState = {
    data: []
}

const counterReducer = (state = initialState, { type, payload }) => {
    console.log(type)
    console.log(payload)
    switch (type) {
        case RECEIVE_API_DATA:
            return {
                ...state,
                data: payload
            }
        default:
            return state
    }
}
export default counterReducer




src\sagas\counterSaga.js

import { call, put, takeEvery } from 'redux-saga/effects'
import { receieveApiData, } from '../actions/actionCreators'
import { REQUEST_API_DATA } from '../constants/Type'
import axios from 'axios'

const fetchApi = async () => {
    try {
        const response = await fetch('https://randomuser.me/api')
        console.log(response)
        const data = await response.json();
        return data

    } catch (e) {
        console.log(e)
    }
}


// const fetchApi = () => {
//     return axios({
//         method: "GET",
//         url: 'https://randomuser.me/api'
//     }).then(res => res.data)
//         .catch(e => {
//             console.log(e)
//         }
//         )
// }


function* workerSaga() {
    try {
        const dataasas = yield call(fetchApi)
       //  const res = dataasas.results
        yield put(receieveApiData(dataasas.results))
    } catch (e) {
        console.log(e)
    }
}
function* watcherSaga() {
    yield takeEvery(REQUEST_API_DATA, workerSaga)
}
export default watcherSaga

App.js

import React from 'react'
import { Provider } from 'react-redux'
import { createStore, applyMiddleware } from 'redux'
import createSagaMiddleware from 'redux-saga'

import Home from '../src/components/Home'
import counterReducer from '../src/reducers/nameReducer'
import watcherSaga from '../src/sagas/counterSaga'

const sagaMiddleware = createSagaMiddleware()
const middleware = [sagaMiddleware]


const store = createStore(counterReducer, applyMiddleware(...middleware))

const App = () => {
  return (
    <Provider store={store}>
      <Home />
    </Provider>
  )
}
sagaMiddleware.run(watcherSaga)
export default App


Happy coding :)
..........................................................................................................................................................................................................................
Store.js

import { createStore, applyMiddleware, compose } from 'redux';
import createSagaMiddleware from 'redux-saga';

import {rootReducer, rootSaga } from './modules';

const sagaMiddleware = createSagaMiddleware();

var middleware = applyMiddleware(sagaMiddleware);

var composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

export default createStore( rootReducer, {}, composeEnhancers(
    middleware
));
sagaMiddleware.run(rootSaga);

Happy coding :)
..........................................................................................................................................................................................................................
Example - 
export const LOAD_DATA = 'LOAD_DATA'
export const LOAD_DATA_SUCCESS = 'LOAD_DATA_SUCCESS'
......................
import * as Types from './actionTypes'
export const loadData = () => {
    return {
        type: Types.LOAD_DATA
    }}
export const fetchData = data => {
    return {
        type: Types.LOAD_DATA_SUCCESS,
        payload: data
    }}
.............................
import * as Types from './actionTypes'
const initialState = {
    data: []
}
const dataReducer = (state = initialState, action) => {
    switch (action.type) {
        case Types.LOAD_DATA_SUCCESS:
            return {
                ...state,
                data: action.payload
            }
        case Types.LOAD_DATA:
            return {
                ...state
            }
        default:
            return state
    }}
export default dataReducer
.....................

import * as Types from './actionTypes'
import { call, put, takeEvery } from 'redux-saga/effects'
import { fetchData } from './actions'
import axios from 'axios'

const fetchApi = () => {
    return axios({
        method: 'GET',
        url: 'https://jsonplaceholder.typicode.com/users'
    }).then(response => response.data)
        .catch(error => console.log(error))
}

function* watcherSaga() {
    const response = yield call(fetchApi)
    console.log(response)
    yield put(fetchData(response))
}
function* rootSaga() {
    yield takeEvery(Types.LOAD_DATA, watcherSaga)
}
export default rootSaga
.................
App.js

import React from 'react'
import { createStore , compose} from 'redux'
import { Provider } from 'react-redux'
import createSagaMiddleware from 'redux-saga'
import dataReducer from './redux/reducer'

import Home from './redux/Home'
import rootSaga from './redux/saga'
import { applyMiddleware } from 'redux'

const sagaMiddleware = createSagaMiddleware()
const middleware = [sagaMiddleware]
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose

const store = createStore(dataReducer, composeEnhancers(applyMiddleware(...middleware)) )

const App = () => {
  return (
    <Provider store={store}>
      <Home/>
    </Provider>
  )
}

sagaMiddleware.run(rootSaga)
export default App

Happy coding :)
..........................................................................................................................................................................................................................



App.js
// Imports: Dependencies
import React from 'react';
import { Provider } from 'react-redux';
// Imports: Screens
import Counter from './screens/Counter';
// Imports: Redux Store
import { store } from './store/store';
// React Native App
export default function App() {
  return (
    // Redux: Global Store
    <Provider store={store}>
      <Counter />
    </Provider>
  );
}
.............







Counter.js
// Imports: Dependencies
import React, { Component } from 'react';import { Button, Dimensions, SafeAreaView, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import { connect } from 'react-redux';
// Screen Dimensions
const { height, width } = Dimensions.get('window');
// Screen: Counter
class Counter extends React.Component {
  render() {
    return (
      <SafeAreaView style={styles.container}>
        <Text style={styles.counterTitle}>Counter</Text>
        <View style={styles.counterContainer}>
          <TouchableOpacity onPress={this.props.reduxIncreaseCounter}>
            <Text style={styles.buttonText}>+</Text
          </TouchableOpacity>
          <Text style={styles.counterText}>{this.props.counter}</Text>
          <TouchableOpacity onPress={this.props.reduxDecreaseCounter}>
            <Text style={styles.buttonText}>-</Text
          </TouchableOpacity>
        </View>
      </SafeAreaView>
    )
  }
}
// Styles
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  counterContainer: {
    display: 'flex',
    flexDirection: 'row',
    justifyContent: 'center',
    alignItems: 'center',
  },
  counterTitle: {
    fontFamily: 'System',
    fontSize: 32,
    fontWeight: '700',
    color: '#000',
  },
  counterText: {
    fontFamily: 'System',
    fontSize: 36,
    fontWeight: '400',
    color: '#000',
  },
  buttonText: {
    fontFamily: 'System',
    fontSize: 50,
    fontWeight: '300',
    color: '#007AFF',
    marginLeft: 40,
    marginRight: 40,
  },
});
// Map State To Props (Redux Store Passes State To Component)
const mapStateToProps = (state) => {
  console.log('State:');
  console.log(state);
  // Redux Store --> Component
  return {
    counter: state.counter.counter,
  };
};
// Map Dispatch To Props (Dispatch Actions To Reducers. Reducers Then Modify The Data And Assign It To Your Props)
const mapDispatchToProps = (dispatch) => {
  // Action
  return {
    // Increase Counter
    reduxIncreaseCounter: () => dispatch({
      type: 'INCREASE_COUNTER',
      value: 1,
    }),
    // Decrease Counter
    reduxDecreaseCounter: () => dispatch({
      type: 'DECREASE_COUNTER',
      value: 1,
    }),
  };
};
// Exports
export default connect(mapStateToProps, mapDispatchToProps)(Counter);
store.js
// Imports: Dependencies
import { createStore, applyMiddleware } from 'redux';
import { createLogger } from 'redux-logger';
import createSagaMiddleware from 'redux-saga';
// Imports: Redux Root Reducer
import rootReducer from '../reducers/index';
// Imports: Redux Root Saga
import { rootSaga } from '../sagas/index';
// Middleware: Redux Saga
const sagaMiddleware = createSagaMiddleware();
// Redux: Store
const store = createStore(
  rootReducer,
  applyMiddleware(
    sagaMiddleware,
    createLogger(),
  ),
);
// Middleware: Redux Saga
sagaMiddleware.run(rootSaga);
// Exports
export {
  store,
}
index.js (Root Reducer)
// Imports: Dependencies
import { combineReducers } from 'redux';
// Imports: Reducers
import counterReducer from './counterReducer';
// Redux: Root Reducer
const rootReducer = combineReducers({
  counter: counterReducer,
});
// Exports
export default rootReducer;
counterReducer.js
// Initial State
const initialState = {
  counter: 0,
};
// Redux: Counter Reducer
const counterReducer = (state = initialState, action) => {
  switch (action.type) {
    case 'INCREASE_COUNTER_ASYNC': {
      return {
        ...state,
        counter: state.counter + action.value,
      };
    }
    case 'DECREASE_COUNTER': {
      return {
        ...state,
        counter: state.counter - action.value,
      };
    }
    default: {
      return state;
    }
  }
};
// Exports
export default counterReducer;
index.js (Root Saga)
// Imports: Dependencies
import { all, fork} from 'redux-saga/effects';
// Imports: Redux Sagas
import { watchIncreaseCounter, watchDecreaseCounter } from './counterSaga';
// Redux Saga: Root Saga
export function* rootSaga () {
  yield all([
    fork(watchIncreaseCounter),
    fork(watchDecreaseCounter),
  ]);
};
counterSaga.js
// Imports: Dependencies
import { delay, takeEvery, takeLatest, put } from 'redux-saga/effects';
// Worker: Increase Counter Async (Delayed By 4 Seconds)
function* increaseCounterAsync() {
  try {
    // Delay 4 Seconds
    yield delay(4000);
    // Dispatch Action To Redux Store
    yield put({
      type: 'INCREASE_COUNTER_ASYNC',
      value: 1,
    });
  }
  catch (error) {
    console.log(error);
  }
};
// Watcher: Increase Counter Async
export function* watchIncreaseCounter() {
  // Take Last Action Only
  yield takeLatest('INCREASE_COUNTER', increaseCounterAsync);
};
// Worker: Decrease Counter
function* decreaseCounter() {
  try {
    // Dispatch Action To Redux Store
    yield put({
      type: 'DECREASE_COUNTER_ASYNC',
      value: 1,
    });
  }
  catch (error) {
    console.log(error);
  }
};
// Watcher: Decrease Counter
export function* watchDecreaseCounter() {
  // Take Last Action Only
  yield takeLatest('DECREASE_COUNTER', decreaseCounter);
};