Thursday, June 6, 2019

Thunk

Redux Thunk in React and React Native



store.subscribe(()=>{console.log(store.getState())}) // log details
store.dispatch(fetchData())   // useEffect()

So before doing any code, how does redux middleware works?

Redux middleware is how you would handle asynchronous operations. Since redux operates synchronously, you would need middleware to handle asynchronous operations since you would handling promises, callbacks and async and await. 

Install these dependencies
yarn add redux redux-thunk react-redux axios This is project structure


...................................................................................................................................................................................................................................
Step -1
constants/index.js

export const GET_PEOPLE = 'GET_PEOPLE';
export const GET_PEOPLE_FULFILLED = 'GET_PEOPLE_FULFILLED';
export const GET_PEOPLE_REJECTED = 'GET_PEOPLE_REJECTED';

Step -2
actions/index.js

import {GET_PEOPLE, GET_PEOPLE_FULFILLED, GET_PEOPLE_REJECTED } from '../constants/index'
import axios from 'axios'

export const fetchData = (bool) => {
    return {
        type: GET_PEOPLE,
        payload: bool,
    };
}

export const fetchDataFulfilled = (data) => {
    return {
        type: GET_PEOPLE_FULFILLED,
        payload: data,
        loading: false,
    };
}
/** API for thunk*/

export const fetchDataRejected = (error) => {
        return {
        type: GET_PEOPLE_REJECTED,
        payload: error,
        loading: false,
    };
}
export const getPeople = () => {
    return dispatch => {
        dispatch(fetchData(true));
        axios.get('https://swapi.co/api/people').then(res => {
            dispatch(fetchDataFulfilled(res.data.results));
            
        }).catch(err => dispatch(fetchDataRejected(err)));
    }
}

or
/**
export const dataThunk=(dispatch)=>{
    return dispatch=> {
        dispatch(requestApiData())
        //axios.get('https://randomuser.me/api')
        axios.get('https://jsonplaceholder.typicode.com/users')
       .then((res)=> dispatch(receiveApiData({results:res.data})))
    }

}
*/
...................................................................................................................................................................................................................................
Step -3
thunk/reducer/peoplesReducer.js

import { GET_PEOPLE, GET_PEOPLE_FULFILLED, GET_PEOPLE_REJECTED } from '../constants/index'



const initialState = {

    people: [],

    loading: false,

    error: ''

}

const peoplesReducer = (state = initialState, action) => {

    switch (action.type) {

        case GET_PEOPLE:

            return {

                ...state,

                loading: action.payload,

            }



        case GET_PEOPLE_FULFILLED:

            return {

                ...state,

                people: action.payload,

                loading: action.loading,

                

            }



        case GET_PEOPLE_REJECTED:

            return {

                ...state,

                error: action.payload,

                loading: action.loading

            }
            default:
                return state
    }
}
export default peoplesReducer
...................................................................................................................................................................................................................................
Step -4
thunk/components/peopleList.js

import React, { Component } from 'react'

import { View, Text } from 'react-native'

import { connect } from 'react-redux'

import { getPeople } from '../actions/index'



class PeopleList extends Component {

    componentDidMount() {

        this.props.getPeople()

    }

    render() {

        const { people, loading } = this.props;

        if (!loading) {

            return (

                <View>

                    {people.length ? people.map((person, i) => <Text key={i}>{person.name}</Text>) : <Text>No People</Text>}

                </View>

            );

        } else {

            return (

                <View>

                    <Text style={{ fontSize: 30, color: 'red' }}>Loading...</Text>

                </View>

            )

        }

    }



}



const mapStateToProps = state => ({
    people: state.people,
    loading: state.loading,
})

const mapDispatchToProps = {
    // return {
    //     getPeople:()=>dispatch(getPeople())
    // }
    //or
//call thunk API
    getPeople
}

export default connect(mapStateToProps, mapDispatchToProps)(PeopleList);
...................................................................................................................................................................................................................................
Step -5
import React, { Component } from 'react'
import { Provider } from 'react-redux'
import { createStore, applyMiddleware } from 'redux'
import thunk from 'redux-thunk'
import PeopleList from './thunk/components/peopleList'
import peoplesReducer from './thunk/reducer/peoplesReducer'


const store = createStore(peoplesReducer, applyMiddleware(thunk))

export default class App extends Component {
    render() {
        return (
            <Provider store={store}>
                <PeopleList />

            </Provider>
        )
    }
}

Step -6

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


Happy Coding :)
.......................................................................................................................................................................................................................................
Example -2
Install
 axios  - Request to an API end points
redux-thunk  - standard way define async action creations

CODE
...........................................................................................................................................................................................................................................
App.js

import React from 'react'
import axios from 'axios'
import { createStore, applyMiddleware } from 'redux'
import { Provider } from 'react-redux'
import reduxThunk from 'redux-thunk'

const FETCH_USERS_REQUEST = 'FETCH_USERS_REQUEST'
const FETCH_USERS_SUCCESS = 'FETCH_USERS_SUCCESS'
const FETCH_USERS_FAILURE = 'FETCH_USERS_FAILURE'

const fetchUserRequest=()=>{
  return{
    type: FETCH_USERS_REQUEST
  }
}

const fetchUserSuccess = (data) => {
  return {
    type: FETCH_USERS_SUCCESS,
    payload: data
  }
}

const fetchUserFailure = (error) => {
  return {
    type: FETCH_USERS_FAILURE,
    payload: error
  }
}

//Reducer
const initialState = {
  loading: false,
  data: [],
  error: ''
}

const userReducers = (state = initialState, action) => {
  switch (action.type) {
    case FETCH_USERS_REQUEST:
      return {
        ...state,    //<-- copy of the existing state
        loading: true
      }
    case FETCH_USERS_SUCCESS:
      return {
        loading: false,
        data: action.payload,
        error: ''
      }
    case FETCH_USERS_FAILURE:
      return {
        loading: false,
        data: [],
        error: action.payload
      }
  }
}

//Thunk
const fetchUserDate = () => {
  return (dispatch)=>{
    dispatch(fetchUserRequest());
    axios.get('https://jsonplaceholder.typicode.com/users')
      .then(response => {
       // const users = response.data
        //console.log(users)
        const users = response.data.map(user=>user.id)
        dispatch(fetchUserSuccess(users))
      }).catch(error => {
        dispatch(fetchUserFailure(error.message))
      })
  }
}

const store = createStore(userReducers, applyMiddleware(reduxThunk))
store.subscribe(()=>console.log(store.getState()))
store.dispatch(fetchUserDate())

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



Error 





Happy Coding :)
..............................................................................................................................................................................................................................
Example : #3 [How to update the state]
Actions
export const update = (data) => {
    return {
        type:'UPDATE',
        payload:data
    }

}
.................................................................................................................................................................................................................................
reducer
const initialState = {
    animals: 'dog'
}

const updateReducers = (state = initialState, action) => {
    switch (action.type) {
        case 'UPDATE':
            return {
                ...state,
                animals: action.payload
            }
        default:
            return state
    }

}
export default updateReducers
.....................................................................................................................................................................................................................
Component

import React, { Component } from 'react'
import { View, Text, TextInput, Button } from 'react-native'
import { connect } from 'react-redux'
import { update} from '../actions/actionCreator'

class Update extends Component {
    constructor(props){
        super(props)
        this.state={
myFavorite: this.props.Hello

        }
    }
    Submit=(e)=>{
        e.preventDefault(),
    this.props.Up(this.state.myFavorite)
    this.setState({myFavorite:''})
   
     
    }

    render() {
        return (
            <View>
                <Text>{this.props.Hello}</Text>
                <TextInput
                placeholder='Enter Favorite Animals'
                value={this.state.myFavorite}
                onChangeText={(text)=>this.setState({myFavorite:text})}
                />
                <Button title='UPDATE' onPress={this.Submit}/>
            </View>
        )
    }
}
const mapStateToProps = state => {
    return {
        Hello: state.All.animals
    }
}
const mapDispatchToProps = dispatch => {
    return {
        Up: (text) => dispatch(update(text))
    }
}
export default connect(mapStateToProps, mapDispatchToProps)(Update)

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

import React from 'react'
import { View, Text } from 'react-native'
import { Provider } from 'react-redux'
import { createStore, combineReducers } from 'redux'
import updateReducers from './src/reducers/updateReducer'
import Update from './src/components/Update'
const AllReducers = combineReducers({
  All: updateReducers
})

const store = createStore(AllReducers)

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

  )
}
export default App







Happy Coding.
.................................................................................................................................................................................................................................
Example : #4
constants/Type.js

export const INCREMENT ='INCREMENT'
export const DECREMENT ='DECREMENT'
...................................................................................................................................................................................................................

actions/actionsCreator.js

import { INCREMENT, DECREMENT } from '../constants/Type'

export const Increment =()=>{
    return {
        type: 'INCREMENT'
    }
}

export const Decrement =()=>{
    return{
        type: 'DECREMENT'
    }
}
...................................................................................................................................................................................................................
src/reducers/counterReducer.js

import { DECREMENT, INCREMENT } from '../constants/Type'
const initialState = {
    count: 0
}
const counterReducer = (state = initialState, action) => {
    if (action.type === 'INCREMENT'){
        return {
            ...state,
            count: state.count + 1
        }
    }
    else if (action.type === 'DECREMENT') {
        return {
            ...state,
            count: state.count - 1
        }
    }
    //default:\
    return state
}
export default counterReducer
.........................................................................................................................................................................................................................
src/reducers/index.js

import { combineReducers } from 'redux'
import counterReducer from './counterReducer'

const rootReducer =combineReducers({
    nav: counterReducer
})

export default rootReducer
.............................................................................................................................................................................................................................

src/components/Counter.js

import React, { Component } from 'react'
import { View, Text, Button } from 'react-native'
import { connect } from 'react-redux'
import { Decrement, Increment } from '../actions/actionsCreator'

class Counter extends Component {
    render() {
        const { results, Inc, Dec } = this.props
        return (
            <View>
                <Text style={{fontSize:30}}>{results}</Text>
                <Button title="Increment " onPress={() => Inc()}></Button>
                <Button title="Decrement" onPress={() => Dec()}></Button>
            </View>
        )
    }
}
const mapStateToProps = state => {
    return {
        results: state.nav.count
    }
}
const mapDispatchToProps = dispatch => {
    return {
        Inc: () => dispatch(Increment(10)),
        Dec: () => dispatch(Decrement())
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(Counter)
.........................................................................................................................................................................................................................
App.js

import React, { Component } from 'react'
import { View, Text } from 'react-native'
import { createStore, applyMiddleware } from 'redux'
import { Provider } from 'react-redux'
import rootReducer from './src/reducers/index'
import Counter from './src/components/Counter'

const store = createStore(rootReducer,
  window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()

 or

window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__() || compose

)
export default class App extends Component {
  render() {
    return (
      <Provider store={store}>
        <Counter />
      </Provider>
    )
  }
}
Happy Coding :)
.................................................................................................................................................................................................................................
Example : #5 [ React Native debugger ]
Step : #1
https://github.com/jhen0409/react-native-debugger

Step : #2
Just need to scroll down and click the  release page.
Step : #3


Step : #4 download  Extract and run the applications.


Code for App.js
import thunk from 'redux-thunk'
const middleware = [thunk]

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

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


ERROR vsc




"javascript.validate.enable": false






Happy Coding :)
.................................................................................................................................................................................................................................





Example : #1
npm install --save redux
npm install --save react-redux
or one line commands
npm install --save redux react-redux

Basic structure of redux.




Step -I
actions
    |__actionType.js
    |__actionCreator.js

actionType.js

export const GET_REST = 'GET_REST'

actionCreator.js

import { GET_REST } from './actionType'
import dataEmp from '../api/emp.json'

export const getFetch = ()=>{
    return{
        type: GET_REST,
        payload: dataEmp
    }

}
_____________________________________________________________________________

Step -II

reducers
    |__appReducer.js
    |__Root.js

appReducer.js

import { GET_REST } from '../actions/actionType'

const initialState ={}
const appReducer = ( state=initialState, action)=>{
    switch(action.type){
        case 'GET_REST':
        return action.payload
  
    default:
    return state 
}
}

export default appReducer


Root.js

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

const Root = combineReducers({
    nav: appReducer
})



export default Root

______________________________________________________________________________

Step -III

Store
   |___store.js

store.js

import { createStore } from 'redux'
import Root from '../reducers/Root';

const store = createStore(Root)

export default store


________________________________________________________________________________

Step -IV
component 
   |___Home.js

import React, { Component } from 'react'
import  { View, Text } from 'react-native'
import { connect } from 'react-redux'
import { getFetch} from '../actions/actionCreator'

class Home extends Component {
componentDidMount(){
    this.props.getFetch()
}
    render(){
        return(
         <View>
            <Text>{this.props.data.name}</Text>
            <Text>{this.props.data.job}</Text>
        </View>
        )
}
}


const mapStateToProps = (state) =>{
    return{
        data: state.nav
    }

}



export default connect (mapStateToProps,{getFetch})(Home)

__________________________________________________________________________

Step -V

App.js

import React, { Component } from 'react'
import { Provider } from 'react-redux'
import store from './demo/stores/store';
import Home from './demo/components/Home';


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

}
________________________________________________________________________

api
 |__emp.json

emp.json

{
    "name":"Sapan Kumar Das",
    "job" : "IT"

}




................................................................................................................................................................................................................................
Example : # 2 Using (json-server)

npm install -g json-server

Step : # 1
npm init -y
yarn add json-server
create a file name with json extension like (db.json)
Start JSON Server

json-server --watch db.json
or
json-server --watch  -p 5000 db.json
....................................................................................................................................................................................................................................

db.json

{
    "users": [
      {
        "id": 1,
        "firstName": "John",
        "lastName": "Doe",
        "active": true,
        "posts": 10,
        "messages": 570
      },

      {
        "id": 2,
        "firstName": "Clay",
        "lastName": "Chung",
        "active": true,
        "posts": 8,
        "messages": 10
      },
      {
        "id": 3,
        "firstName": "Sapan",
        "lastName": "Das",
        "active": true,
        "posts": 8,
        "messages": 25
      },{
        "id": 4,
        "firstName": "Mickel",
        "lastName": "Singh",
        "active": true,
        "posts": 8,
        "messages": 100
      },{
        "id": 5,
        "firstName": "Mohan lal",
        "lastName": "Singh",
        "active": true,
        "posts": 8,
        "messages": 100
      }
    ]
   }

.................................................................................................................................................................................................................................
Api.js

const API_BASE_ADDRESS = 'http://localhost:5000';

export default class Api {
   static getUsers() {
       const uri = API_BASE_ADDRESS + "/users";
       return fetch(uri, {
           method: 'GET'
       });
   }
}



.................................................................................................................................................................................................................................
constants/Constant.js

export const LOAD_USERS_LOADING = 'REDUX_THUNK_LOAD_USERS_LOADING';
export const LOAD_USERS_SUCCESS = 'REDUX_THUNK_LOAD_USERS_SUCCESS';
export const LOAD_USERS_ERROR = 'REDUX_THUNK_LOAD_USERS_ERROR';


   
...............................................................................................................................................................................................................................
actions/actionCreator.js

import * as Types from '../constants/Constant'
import Api from '../Api';

export const load = () => {
    return {
        type: Types.LOAD_USERS_LOADING
    }
}
export const success = (data) => {
    return {
        type: Types.LOAD_USERS_SUCCESS,
        payload:data
    }
}

export const error = (error) => {
    return {
        type: Types.LOAD_USERS_SUCCESS,
        payload:error

    }
}

// All function call here
export const loadUsers = () => dispatch => {
    dispatch(load());
    Api.getUsers()
        .then(response => response.json())
        .then(
            data => dispatch(success(data)),
            error => dispatch(error(error))
        )
};

...............................................................................................................................................................................................................................
reducers/reducer.js 

import { LOAD_USERS_LOADING, LOAD_USERS_SUCCESS, LOAD_USERS_ERROR } from '../constants/Constant'

const initialState = {
    data: [],
    loading: false,
    error: ''
};
const reduxThunkReducer = (state = initialState, action) => {
    switch (action.type) {
        case LOAD_USERS_LOADING:
            return {
                ...state,
                loading: true,
                error: ''
            };
   
        case LOAD_USERS_SUCCESS:
            return {
                ...state,
                data: action.payload,
                loading: false
            }
   
        case LOAD_USERS_ERROR:
            return {
                ...state,
                loading: false,
                error: action.payload
            };
   
        default:
            return state;
    }
}

export default reduxThunkReducer

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

stores/configureStore.js 

import { applyMiddleware, compose, createStore, combineReducers } from 'redux';
import thunk from 'redux-thunk';
import reduxThunkReducer from '../reducers/reducer';
const AllReducer =combineReducers({
    reduxThunk: reduxThunkReducer
})

 export const configureStore=()=> {

    const middleware = [thunk];
    const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
    const store = createStore(AllReducer, composeEnhancers(applyMiddleware(...middleware)));
    return store;
}


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

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

import { configureStore } from './stores/configureStore'
import Home from './components/Home'
const store = configureStore()

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


export default App
...............................................................................................................................................................................................................................




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

Example : #3 [ without json-server]

data/db.json
{
    "users": [
      {
        "id": 1,
        "firstName": "John",
        "lastName": "Doe",
        "active": true,
        "posts": 10,
        "messages": 570
      },
    
      {
        "id": 2,
        "firstName": "Clay",
        "lastName": "Chung",
        "active": true,
        "posts": 8,
        "messages": 10
      },
      {
        "id": 3,
        "firstName": "Sapan",
        "lastName": "Das",
        "active": true,
        "posts": 8,
        "messages": 25
      },{
        "id": 4,
        "firstName": "Mickel",
        "lastName": "Singh",
        "active": true,
        "posts": 8,
        "messages": 100
      },{
        "id": 5,
        "firstName": "Mohan lal",
        "lastName": "Singh",
        "active": true,
        "posts": 8,
        "messages": 100
      }
    ]
   }

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

constants/Constant.js

export const EMP_JSON_DATA = 'EMP_JSON_DATA'
...............................................................................................................................................................................................................................

actions/actionCreator.js

import * as Types from '../constants/Constant'
import empData from '../data/db.json'

export const getData =()=>{
    return{
        type : Types.EMP_JSON_DATA,
        payload: empData
    }


}

...............................................................................................................................................................................................................................
reducers/reducer.js

import * as Types from '../constants/Constant'

const initialState = {
data:[]
}
const Reducer = (state = initialState, action) => {
    switch (action.type) {
        case Types.EMP_JSON_DATA:
            return {
                ...state,
                data: action.payload
            }
        default:
            return state
    }
}
export default Reducer

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

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

class Home extends Component {
    componentDidMount() {
        this.props.getData();
        console.log(getData())
    };

    render() {
        const {users=[]}= this.props.data
        return (
            <table border='1'>
                <thead>
                    <tr>
                        <th>First Name</th>
                        <th>Last Name</th>
                        <th>Active?</th>
                        <th>Posts</th>
                        <th>Messages</th>
                    </tr>
                </thead>
                <tbody>
                    {users.map(u =>
                        <tr key={u.id}>
                            <td>{u.firstName}</td>
                            <td>{u.lastName}</td>
                            <td>{u.active ? 'Yes' : 'No'}</td>
                            <td>{u.posts}</td>
                            <td>{u.messages}</td>
                        </tr>
                    )}
                </tbody>
            </table>
        );
    }
}
const mapStateToProps = state => ({
    data: state.ALL.data
});

export default connect(
    mapStateToProps,{getData})(Home);

...............................................................................................................................................................................................................................
App.js
import React, { Component } from 'react'
import { Provider } from 'react-redux'
import { createStore, combineReducers } from 'redux'
import Reducer from './reducers/reducer'
import Home from './components/Home'

const Root = combineReducers({
  ALL:Reducer
})
const store = createStore(Root)

export default class App extends Component {
  render() {
    return (
      <Provider store={store}>
        <Home />
      </Provider>
    )
  }
}
...............................................................................................................................................................................................................................
Example : #4

constants/Type
export const UPDATE_DATA = 'UPDATE_DATA'


import * as Type from '../constants/Type'

export const update_data = () => {
   return dispatch=>{
    fetch('https://reqres.in/api/users')
    .then(res => res.json())
    .then(resJson => console.log(dispatch({ type: Type.UPDATE_DATA, payload: resJson.data })))

   }
class App extends Component {
  render() {
    return (
      <Provider store={store}>
        <UserComponent />
      </Provider>
    )
  }
}
export default App

import React from 'react'
import { View, Text, Button } from 'react-native'
import { connect } from 'react-redux'
import { update_name } from '../actions/userActions'
import { update_data } from '../actions/dataActions'

const UserComponent = (props) => {
    return (
        <View>
            <Text> WelCome</Text>
            <Text>{props.name.name}</Text>
            <Button title="update" onPress={() => props.update_name_person()}>
            </Button>
            <Button title='update4' onPress={() => props.update_datas()}></Button>

            {props.data.length === 0 ? <Text>no users found</Text>
                :
                props.data.map(item => <Text>{item.id} {item.email}</Text>)

            }

        </View>

    )

}

const mapStateToProps = state => {
    return {
        name: state.user,
        data: state.datas.data
    }
}
const mapDispatchToProps = dispatch => {
    return {
        update_name_person: () => { dispatch(update_name()) },
        update_datas: () => { dispatch(update_data())}
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(UserComponent)

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

src\constants\dataType.js
export const UPDATE_DATA='UPDATE_DATA'

src\actions\actionData.js

import * as Type from '../constants/dataType'

export const dataUpdate = () => {
    return dispatch => {
        fetch('https://reqres.in/api/users')
            .then((res) => res.json())
            .then((responseData) =>
                dispatch({
                    type: Type.UPDATE_DATA,
                    payload: responseData.data
                }))
    }
}




src\reducers\dataReducer.js
import * as Type from '../constants/dataType'
const initialState = {
    data: []
}

const dataReducer = (state = initialState, { type, payload }) => {
    switch (type) {
        case Type.UPDATE_DATA:
            return {
                ...state,
                data: payload
            }
        default:
            return state
    }
}

export default dataReducer


src\reducers\index.js
import { combineReducers } from 'redux'
import dataReducer from './dataReducer'

const AllReducers  = combineReducers({
All : dataReducer

})
export default AllReducers


src\components\dataComponent.js
import React, { Component } from 'react'
import { View, Text, Button } from 'react-native'
import { connect } from 'react-redux'
import { dataUpdate } from '../actions/actionData'

const DataComponent = (props) => {
    return (
        <View>
            <Button title='Update Data' onPress={() => props.data_Update()}></Button>
            {props.data.length === 0 ? <Text>No users found...</Text>
                :
                props.data.map(item => <Text>{item.id} {item.email}</Text>)
 //props.data.map(item => <Text>{`${item.id} ${item.email}`}------>{item.id} {item.email}</Text>)
            }

        </View>
    )
}
const mapStateToProps = state => {
    return {
        data: state.All.data
    }
}

const mapDispatchToProps = dispatch => {
    return {
        data_Update: () => { dispatch(dataUpdate()) }
    }
}
export default connect(mapStateToProps, mapDispatchToProps)(DataComponent)

App.js

import React, { Component } from 'react'
import { View, Text } from 'react-native'
import { Provider } from 'react-redux'
import { createStore, applyMiddleware, compose } from 'redux'
import thunk from 'redux-thunk'
import DataComponent from './src/components/dataComponent'
import AllReducers from './src/reducers/index'
const middleware = [thunk]

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(AllReducers, composeEnhancers(applyMiddleware(...middleware)))

class App extends Component {
  render() {
    return (
      <Provider store={store}>
        <DataComponent />
      </Provider>
    )
  }
}
export default App

Happy Coding :)
...........................................................................................................................................................................................................................
TIPS


................................................................................................................................................................................................................................
Example :#6
src\constants\Type.js

export const FETCH_API_DATA = 'FETCH_API_DATA'



src\actions\actionCreators.js
import * as Type from '../constants/Type'

export const fetchApiData = () => {
    return dispatch => {
        fetch('https://randomuser.me/api')
            .then(res => res.json())
            .then(response => console.log(dispatch({
                type: Type.FETCH_API_DATA,
                payload: response.results
            })))
    }
}

 [Too much clean code] 
import * as Type from '../constants/Type'
export const fetchApiData = () => dispatch =>{
        fetch('https://randomuser.me/api')
            .then(res => res.json())
            .then(response => console.log(dispatch({
                type: Type.FETCH_API_DATA,
                payload: response.results
            })))
    

}


src\reducers\counterReducer.js

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

const counterReducer = (state = initialState, action) => {
    switch (action.type) {
        case Type.FETCH_API_DATA:
            return {
                ...state,
                data: action.payload
            }
        default:
            return state
    }
}
export default counterReducer

src\components\Home.js
import React from 'react'
import { connect } from 'react-redux'
import { fetchApiData } from '../actions/actionCreators'

const Person = (item) => (
    <div>
        <h2>{item.gender}:{item.name.first} </h2>
        <img src={item.picture.large} />
    </div>
)

const Home = ({ data, fetchApiData }) => {
     // useEffect(()=>{
    //     fetchApiData()
    // },[])


    return (
        <div>
            {data.length ? data.map(Person) : <h2>Loading...</h2>}
            <button onClick={fetchApiData}>Feth Data</button>
        </div>
    )
}

const mapStateToProps = state => {
    return {
        data: state.All.data
    }
}

const mapDispatchToProps = dispatch => {
    return {
        fetchApiData:()=>dispatch(fetchApiData())
    }
}
export default connect(mapStateToProps, mapDispatchToProps)(Home)
//export default connect(mapStateToProps,{fetchApiData})(Home)

App.js
import React from 'react'
import { Provider } from 'react-redux'
import thunk from 'redux-thunk'
import { createStore, applyMiddleware, combineReducers } from 'redux'

import counterReducer from '../src/reducers/counterReducer'
import Home from '../src/components/Home'
const middleware = [thunk]


const AllReducer = combineReducers({
  All: counterReducer
})

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

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

export default App

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

Example :#7







Keep Learning :)
.......................................................................................................................................................................................................................
Example :#9  [ SELECTOR ]

import React from 'react'
import { Provider, connect } from 'react-redux'
import { createStore } from 'redux'

const initialState = {
  user: {
    first: 'Sapan',
    last: 'Das',
    gender: 'Male',
    maritalStatus: 'Single',
    address: {
      street: 12345,
      city: 'Mumbai',
      state: 'Maharashtra',
      pincode: 400612
    }
  },
  session: {
    isLogin: 'login In',
    language: 'EN'
  }
}

const reducer = (state = initialState, action) => {
  return state
}

const Home = ({ use }) => {
  return (
    <>
      <h1>{use.first}</h1>
    </>
  )
}
const mapStateToProps = ({user}) => {
  return {
    use: user
  }
}

OR
// const Home = ({ user }) => {
//   return (
//     <>
//       <h1>{user.first}</h1>
//     </>
//   )
// }
// const mapStateToProps = ({user}) => {
//   return {
//      user

//   }
// }

OR
// const Home = ({ first, last }) => {
//   return (
//     <>
//       <p>{first}{last}</p>

//     </>
//   )
// }
// const mapStateToProps = ({ user: { first, last } }) => {
//   return {
//     first,
//     last,
//   }

// }





const Home1 = connect(mapStateToProps)(Home)
const store = createStore(reducer)

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

export default App
.....................................................
import React from 'react'
import { Provider, connect } from 'react-redux'
import { createStore } from 'redux'

const initialState = {
  user: {
    first: 'Sapan Kumar ',
    last: 'Das',
    gender: 'Male',
    maritalStatus: 'single',
    address: {
      street: 12345,
      city: 'Mumbai',
      state: 'Maharashtra',
      pincode: 400612
    }
  },
  session: {
    isLogin: 'login In',
    language: 'EN'
  }
}

const reducer = (state = initialState, action) => {
  return state

}
const Home = ({ first, last, address, gender, maritalStatus }) => {
  return (
    <>
    <h1>
  {gender === 'Female' ?
     maritalStatus === 'Married' ? "Mrs. " : 'Ms. ':"Mr. "}

      {first}{last}</h1>
     <h1>{address.street}</h1>
     <h1>{address.city}</h1>
     <h1>{address.state}</h1>
     <h1>{address.pincode}</h1>
    </>
  )
}
const mapStateToProps = ({ user: { first, last,address,gender, maritalStatus } }) => {
  return {
    first,
    last,
    address,
    gender,
    maritalStatus
  }
}


const Home1 = connect(mapStateToProps)(Home)
const store = createStore(reducer)

const App = () => {
  return (
    <Provider store={store}>
      <Home1 />
    </Provider>
  )
}
export default App

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










Keep Learning :)
.......................................................................................................................................................................................................................
Example :#10

 const authTypes = {
    SELECT_CURRENT_USER: 'SELECT_CURRENT_USER'
}

export default authTypes
.......................................
import authTypes from './authTypes'

export const selectCurrentUser = user => {
    return {
        type: authTypes.SELECT_CURRENT_USER,
        payload:user
    }
}
..............................................................
const initialState = {
    userName: 'Sapan'
}

const authReducer =(state=initialState)=>{
    return state
}
export default authReducer
.................................................................
import { combineReducers } from 'redux'
import authReducer from './authReducer'
const rootReducer = combineReducers({
    auth: authReducer
})
export default rootReducer
.................................................................


import React from 'react'
import { createStore, applyMiddleware } from 'redux'
import { logger } from 'redux-logger'
import { composeWithDevTools } from 'redux-devtools-extension'
import rootReducer from './rootReducer'

const middlewares = [logger]
const store = createStore(rootReducer, composeWithDevTools(applyMiddleware(...middlewares)))

export default store
...................................................................
import React, { Component } from 'react'
import { Provider, connect } from 'react-redux'
import store from './redux/auth/reducer/store'

const Home = ({ currentUser }) => {
  console.log(currentUser)
  return (
    <>
      <h1>{currentUser}</h1>
    </>
  )
}

const mapStateToProps = ({auth})=> {

  return {
    currentUser: auth.userName
  }
}
const Home1 = connect(mapStateToProps)(Home)


class App extends Component {

  render() {
    return (
      <Provider store={store}>
        <Home1/>
      </Provider>
    )
  }
}
export default App

Keep Learning :)
.......................................................................................................................................................................................................................
Example :#11

import React, { Component } from 'react'
import { Provider, connect } from 'react-redux'
import { createStore, combineReducers } from 'redux'


const ADD_VALUE = 'ADD_VALUE'
const SUB_VALUE = 'SUB_VALUE'


const addValue = (value) => {
  return {
    type: ADD_VALUE,
    payload: value
  }
}
const subValue = (value) => {
  return {
    type: SUB_VALUE,
    payload: value
  }
}

const initialState = {
  count: 0
}
const counterReducer = (state = initialState, action) => {
  switch (action.type) {
    case 'ADD_VALUE':
      return {
        ...state,
        count: state.count + action.payload
      }
    case 'SUB_VALUE':
      return {
        ...state,
        count: state.count - action.payload
      }
    default:
      return state
  }
}

const Home = (props) => {
  return (
    <>
      <h1>{props.count1.count}</h1>
      <button onClick={() => props.addValue(5)}>Increment</button>
      <button onClick={() => props.subValue(5)}>Decrement</button>
    </>
  )
}
const mapStateToProps = state => {
  return {
    count1: state.counterReducer
  }
}

const mapDispatchToProps = { addValue, subValue }
const Home1 = connect(mapStateToProps, mapDispatchToProps)(Home)


const AllReducer = combineReducers({
  counterReducer: counterReducer
})


const store = createStore(AllReducer)
class App extends Component {
  render() {
    return (
      <Provider store={store}>
        <Home1 />
      </Provider>
    )
  }
}
export default App

Keep Learning :)
.......................................................................................................................................................................................................................
Example :#12 [ INCREMENT DECREMENT ]

export const INCREMENT = 'INCREMENT'
export const DECREMENT = 'DECREMENT'
export const RESET = 'RESET'

export const Increment = (payload) => {
    return {
        type: Types.INCREMENT,
        payload
    }
}
export const Decrement = (payload) => {
    return {
        type: Types.DECREMENT,
        payload
    }
}
export const reset = (payload) => {
    return {
        type: Types.RESET,
        payload

    }
}


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

import * as Types from './actionTypes'
const initialState = {
    data: [],
    count: 0
}

const dataReducer = (state = initialState, action) => {
    switch (action.type) {
        case Types.INCREMENT:
            return {
                ...state,
                count: state.count + action.payload
            }
        case Types.DECREMENT:
            return {
                ...state,
                count: state.count - action.payload
            }
            case Types.RESET :
                return{
                    ...state,
                    count: action.payload
                }
        default:
            return state
    }
}
export default dataReducer
.............................
import React from 'react'
import { connect } from 'react-redux'
import { Increment, Decrement, reset } from './actions'

const Home = ({ countValue, Inc, Dec, reset }) => {
    return (
        <>
            <h1>{countValue}</h1>
            <button onClick={Inc}>Increment</button>
            <button onClick={Dec}> decrement </button>
            <button onClick={reset}> reset </button>
        </>
    )
}
const mapStateToProps = state => {
    return {
        countValue: state.count
    }
}
const mapDispatchToProps = dispatch => {
    return {
        Inc: () => dispatch(Increment(5)),
        Dec: () => dispatch(Decrement(5)),
        reset :()=> dispatch(reset(0))
    }
}
export default connect(mapStateToProps, mapDispatchToProps)(Home)
.....................
import React from 'react'
import {createStore} from 'redux'
import { Provider } from 'react-redux'
import dataReducer from './redux/reducer'
import Home from './redux/Home'

const store = createStore(dataReducer)

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

}
export default App

Keep Learning :)
.......................................................................................................................................................................................................................
Example :#13  [ Fetch Data from Json ]

Install Dependencies
In your project root, run

npm install --save redux
npm install --save react-redux
npm install --save redux-thunk

..............................................
instructions.json 

{
    "instructions": [
      {
        "title": "Create React Native Project",
        "description": "react-native init ReactReduxBoilerPlate"
      },
      {
        "title": "Install Dependencies",
        "description": "In your project root, run npm install --save react-redux \nnpm install —save redux \nnpm install —save redux-thunk"
      },
      {
        "title": "Create Folder Structure",
        "description": "In your project root create an 'app' folder. In the app folder create an 'actions' folder , a 'reducers' folder and a 'components' folder."
      },
      {
        "title": "Create your first action",
        "description": "The action is a basic function called from the component whenever we want the whole state of the app to be changed. Our action creator is a simple function returning an object (the action itself)with a type attribute expressing what happened with the app.\nIn your actions folder create a js file 'index.js'"
      },
      {
        "title": "Create your first reducer",
        "description": "Reducers are the ones in charge of updating the state of the app. Redux will automatically pass the current state of the app and the action occurred. It’s up to the reducer to realize if it needs to modify the state or not based on the action.type.\nIn your reducers folder create a js file 'index.js'"
      },
      {
        "title": "Create your component",
        "description": "In your components folder create a js file 'home.js'"
      },
      {
        "title": "Create Store",
        "description": "In the app folder, create a js file 'store.js'"
      },
      {
        "title": "Link it all together",
        "description": "Redux needs to inject a store holding the app state into the app. To do so, it requires a ‘Provider’ wrapping the whole app.In the app folder, create a js file 'setup.js'"
      },
      {
        "title": "Update your main files",
        "description": "Update index.ios.js and index.android.js"
      }
    ]
  }

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

export const DATA_AVAILABLE = 'DATA_AVAILABLE';

import Data from '../../src/instructions.json';

export const getData = () => {
    return (dispatch) => {
        setTimeout(() => {
            const data = Data.instructions;
            dispatch({
                type: DATA_AVAILABLE,
                data: data
            });
        }, 2000);

    };

}
............................
import { combineReducers } from 'redux';
import { DATA_AVAILABLE } from '../actions/dataActions'

let initialState = {
    data: [],
    loading: true
};

const dataReducer = (state = initialState, action) => {
    switch (action.type) {
        case DATA_AVAILABLE:
            return {
                ...state,
                data: action.data,
                loading: false
            }
        default:
            return state;
    }
};


const rootReducer = combineReducers({
    dataReducer
})
export default rootReducer;
.........................................
store.js
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import reducers from './reducers/dataReducer'; //Import the reducer

export default createStore(reducers, applyMiddleware(thunk));

........................
Home.js
import React, { Component } from 'react';
import { StyleSheet, FlatList, View, Text, ActivityIndicator } from 'react-native';
import { connect } from 'react-redux';
import { getData } from '../actions/dataActions'

class Home extends Component {
    constructor(props) {
        super(props);
        this.state = {
        };

    }
    componentDidMount() {
        this.props.getData(); 
    }


    renderItem({ item, index }) {
        return (
            <View style={styles.row}>
                <Text style={styles.title}>
                    {(parseInt(index) + 1)}{". "}{item.title}
                </Text>
                <Text style={styles.description}>
                    {item.description}
                </Text>
            </View>
        )
    }


    render() {
        if (this.props.loading) {
            return (
                <View style={styles.activityIndicatorContainer}>
                    <ActivityIndicator animating={true} size={"large"} />
                </View>
            );
        } else {
            return (
                <View style={{ flex: 1, backgroundColor: '#F5F5F5', paddingTop: 30 }}>
                    <FlatList
                        ref='listRef'
                        data={this.props.data}
                        renderItem={this.renderItem}
                        keyExtractor={(item, index) => index.toString()} />
                </View>
            );
        }
    }

};

const mapStateToProps = (state) => {
    return {
        loading: state.dataReducer.loading,
        data: state.dataReducer.data
    }
}

const mapDispatchToProps = (dispatch) => {
    return {
        getData: () => dispatch(getData())
    }
}
    export default connect(mapStateToProps, mapDispatchToProps)(Home);



    const styles = StyleSheet.create({
        activityIndicatorContainer: {
            backgroundColor: "#fff",
            alignItems: 'center',
            justifyContent: 'center',
            flex: 1,
        },

        row: {
            borderBottomWidth: 1,
            borderColor: "#ccc",
            padding: 10
        },

        title: {
            fontSize: 15,
            fontWeight: "600"
        },

        description: {
            marginTop: 5,
            fontSize: 14,
        }
    });
.............................
App.js
import React, { Component } from 'react';
import { Provider } from 'react-redux';

import store from './src/store';
import Home from './src/components/data_component'

export default class App extends Component {
  render() {
    return (
      <Provider store={store}>
        <Home />
      </Provider>
    );
  }
}








Keep Learning :)
.......................................................................................................................................................................................................................
Example :#14 [ Hooks + useDispatch, useSelector]

export const DATA_AVAILABLE = 'DATA_AVAILABLE';

export const addData = (data) => {
    return {
        type: DATA_AVAILABLE,
        data
    }
}

...............................
import { combineReducers } from 'redux';
import { DATA_AVAILABLE } from '../actions/dataActions'

const dataState = {
    data: []
};

const dataReducer = (state = dataState, action) => {
    switch (action.type) {
        case DATA_AVAILABLE:
            return {
                ...state,
                data: action.data
            };
        default:
            return state;
    }
};


const rootReducer = combineReducers({
    dataReducer
})

export default rootReducer;
......................
import React, { useEffect, useState } from 'react';
import { FlatList, StyleSheet, View, Text, ActivityIndicator } from 'react-native';
import { useDispatch, useSelector } from 'react-redux';
//import axios from 'axios';

import { addData } from "../actions/dataActions";
import Data from '../../src/instructions.json';

const Home = () => {
    const dispatch = useDispatch();

    //1 - DECLARE VARIABLES
    const [isFetching, setIsFetching] = useState(false);

    //Access Redux Store State
    const dataReducer = useSelector((state) => state.dataReducer);
    const { data } = dataReducer;

    //==================================================================================================

    //2 - MAIN CODE BEGINS HERE
    useEffect(() => getData(), []);

    //==================================================================================================

    //3 - GET FLATLIST DATA
    const getData = () => {
        setIsFetching(true);
        setTimeout(() => {
            const data = Data.instructions;
            dispatch(addData(data));
            setIsFetching(false);
        }, 2000);

        //OPTION 2 - API CALL
        // let url = "https://my-json-server.typicode.com/mesandigital/demo/instructions";
        // axios.get(url)
        //     .then(res => res.data)
        //     .then((data) => dispatch(addData(data)))
        //     .catch(error => alert(error.message))
        //     .finally(() => setIsFetching(false));
    };


    //==================================================================================================

    //4 - RENDER FLATLIST ITEM
    const renderItem = ({ item, index }) => {
        return (
            <View style={styles.row}>
                <Text style={styles.title}>
                    {(parseInt(index) + 1)}{". "}{item.title}
                </Text>
                <Text style={styles.description}>
                    {item.description}
                </Text>
            </View>
        )
    };

    //==================================================================================================

    //5 - RENDER
    if (isFetching) {
        return (
            <View style={styles.activityIndicatorContainer}>
                <ActivityIndicator animating={true} />
            </View>
        );
    } else {
        return (
            <View style={{ flex: 1, backgroundColor: '#F5F5F5', paddingTop: 20 }}>
                <FlatList
                    data={data}
                    renderItem={renderItem}
                    keyExtractor={(item, index) => `flat_${index}`} />
            </View>
        );
    }
};

const styles = StyleSheet.create({
    activityIndicatorContainer: {
        backgroundColor: "#fff",
        alignItems: 'center',
        justifyContent: 'center',
        flex: 1,
    },

    row: {
        borderBottomWidth: 1,
        borderColor: "#ccc",
        padding: 10
    },

    title: {
        fontSize: 15,
        fontWeight: "600"
    },

    description: {
        marginTop: 5,
        fontSize: 14,
    }
});
export default Home
............
store.js
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';

import reducers from './reducers/dataReducer'
export default createStore(reducers, applyMiddleware(thunk));
...............
App.js
import React, { Component } from 'react';
import { Provider } from 'react-redux';

import store from './src/store';
import Home from './src/components/data_component'

export default class App extends Component {
  render() {
    return (
      <Provider store={store}>
        <Home />
      </Provider>
    );
  }
}










Keep Learning :)
.......................................................................................................................................................................................................................
Example :#15
import React, { Component } from 'react';
import { View, Image, Text } from 'react-native';

const MovieRow = ({moviesData}) => {
        return (
            <>
            <Text> {moviesData.title}</Text>
            <Image source={{uri: moviesData.thumbnailUrl}} style={{width:50, height:50}}/>
            </>
        )
}
export default MovieRow




......................................................
import React, { Component } from 'react';
import { View, Text, FlatList } from 'react-native';
import Search from './MovieApi';
import MovieRow from '../components/MovieRow'
class Home extends Component {
    constructor(props) {
        super(props)
        this.state = {
            movie: []
        }
    }
    async componentDidMount() {
        const response = await fetch('https://jsonplaceholder.typicode.com/photos?_limit=5')
        const data = await response.json()
        this.setState({
            movie: data
        })
    }
    render() {
        const { movie } = this.state
        return (
            <FlatList
                data={movie}
                keyExtractor={(index) => index}
                renderItem={({ item }) =><MovieRow moviesData={item}/> }
            >
            </FlatList>
        )
    }
}
export default Home

Keep Learning :)
.......................................................................................................................................................................................................................
Example :#16


Keep Learning :)
.......................................................................................................................................................................................................................
Example :#17


Keep Learning :)































No comments:

Post a Comment