Thursday, April 21, 2016

react redux middlewares

I am going to fully demonstrate to you what is Redux and React and how these guys can be used together

I am going to build a book list application that loads books through a get request and it will display them so that a user  can select on a particular book and gets the books details



Below is the  structure of my application



Components
These are the react basic units they generally can receive props and these props can be of  data values of various data types or functions 
Here is a normal React Component 

   Book  that has two properties 
  •    Title 
  • Pages
       <Book title="title_value"  pages="pages_value"/>  
import React from "react";

const Book = (props) => {

    return (
        

Details for:

Title: {props.title}
Pages: {props.pages}
); }; Book.propTypes = { title: React.PropTypes.string.isRequired, pages: React.PropTypes.number.isRequired } export { Book as default }
The above Book component gets all its data from the book details container
BookListComponent
import React from "react";

const BookList = (props) => {

    function renderList(){

        console.log(props.books.map)
        return props.books.map((book) => {
            return (
  • props.selectBook(book)} className="list-group-item"> {book.title}
  • ); }); } return (
      {renderList()}
    ); }; export { BookList as default }

    Containers

    Since we are using Redux these are regarded as cool components since they are able to interact with the redux and can pass to and fro data
    BookDetailContainer
    import React, { Component } from 'react';
    import { connect } from 'react-redux';
    import Book from '../components/Book'
    
    class BookDetail extends Component {
    
    }
    
    function mapStateToProps(state) {
        return {
            title: state.activeBook.title,
            pages: state.activeBook.pages,
        };
    }
    
    export default connect(mapStateToProps)(Book);
    
    
    BookListContainer
      import React, { Component } from 'react';
     import { connect } from 'react-redux';
     import { selectBook } from '../actions/index';
     import { bindActionCreators } from 'redux';
     import BookList from '../components/BooksList'
    
     class BookListContainer extends Component {
     }
    
     function mapStateToProps(state) {
       return {
         books: state.books.books
       };
     }
    
     function mapDispatchToProps(dispatch) {
    
       return bindActionCreators({ selectBook: selectBook }, dispatch);
     }
    
     export default connect(mapStateToProps, mapDispatchToProps)(BookList);
    
    
    Action Creators These are the gate keepers ,they dispatch actions that are being sent to all the reducers An action coontains a type and payload
    import ajaxRequest from './AjaxRequest'
    const ROOT_URL = `/Books.json`;
    export function selectBook(book) {
      // selectBook is an ActionCreator, it needs to return an action,
      // an object with a type property.
      return {
        type: 'BOOK_SELECTED',
        payload: book
      };
    }
    
    
    export function loadBooks(books) {
      return {
        type: 'Fetch_Books',
        payload: books
      };
    }
    
    
    export const fetchBooks = () => {
    
    
      return (dispatch, getState) => {
        const addBooks = (books) => {
    
          dispatch(loadBooks(books))
        }
    
        const onFetchError = (error) => {
          console.log(error)
        }
    
        ajaxRequest(ROOT_URL, "GET", addBooks, onFetchError)
      }
    }
    
    
    Reducers They recieve actions and they do mondify the state
    import { combineReducers } from 'redux';
    import availableBooks from './reducer_books';
    import ActiveBook from './reducer_active_book';
    
    const rootReducer = combineReducers({
      books: availableBooks,
      activeBook: ActiveBook
    });
    
    export default rootReducer;
    
    
    //  Active BOOKS REDUCER
    
    const intialState={
      title:'',
      pages:0,
    
    }
    export default function(state = intialState, action) {
      switch(action.type) {
        case 'BOOK_SELECTED':
          return action.payload;
      }
    
      return state;
    }
    
    // Available BOOKS REDUCER
    
    import R from 'ramda'
    const initialState = {
      books:[]
    
    }
    
    const availableBooks = (state = initialState, action) => {
      switch (action.type) {
    
        case 'Fetch_Books':
    
    
          return R.merge(state, {books:action.payload});
    
        default:
          return state;
      }
    }
    export default availableBooks ;
    
    
    
    
    Middle Wares These reside between the actiomn creators and the reducers .Meaning that they will carry out computations and that results can be added to the payload before the action reaches the reducers Here is our custom ajax request file and index.js
    // AjaxRequests
    export default (url, method, onSuccess, onFailure) => {
      var xmlhttp = new XMLHttpRequest();
      xmlhttp.onreadystatechange = () => {
        if (xmlhttp.readyState == XMLHttpRequest.DONE) {
          if (xmlhttp.status >= 200 && xmlhttp.status < 300) {
            try {
              onSuccess(JSON.parse(xmlhttp.responseText));
            } catch (error) {
              onFailure(error)
            }
          } else {
            onFailure(xmlhttp.error);
          }
        }
      };
      xmlhttp.open(method, url, true);
     
      xmlhttp.send();
    };
    
    // INDEX.JS
    
    import React from 'react';
    import ReactDOM from 'react-dom';
    import { Provider } from 'react-redux';
    import { createStore,applyMiddleware } from 'redux';
    import {fetchBooks} from '../src/actions/index'
    import thunkMiddleware from 'redux-thunk'
    
    import App from './components/app';
    import reducers from './reducers';
    let store = createStore(reducers,applyMiddleware(thunkMiddleware))
    
    ReactDOM.render(
        
          
        
        , document.querySelector('.container'));
    
    store.dispatch(fetchBooks)
    
    
    
    
    

    No comments:

    Post a Comment