From a3f30e484b02c1db873769b412ea1428f318ace8 Mon Sep 17 00:00:00 2001 From: KancerEzeroglu Date: Tue, 24 Oct 2017 12:09:27 +0300 Subject: [PATCH 1/3] React with Redux --- src/components/app.js | 6 +++++- src/containers/book-list.js | 30 ++++++++++++++++++++++++++++++ src/reducers/index.js | 3 ++- src/reducers/reducer_books.js | 8 ++++++++ 4 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 src/containers/book-list.js create mode 100644 src/reducers/reducer_books.js diff --git a/src/components/app.js b/src/components/app.js index 58614b02cf..b01559051a 100644 --- a/src/components/app.js +++ b/src/components/app.js @@ -1,9 +1,13 @@ import React, { Component } from 'react'; +import BookList from '../containers/book-list'; + export default class App extends Component { render() { return ( -
React simple starter
+
+ +
); } } diff --git a/src/containers/book-list.js b/src/containers/book-list.js new file mode 100644 index 0000000000..31fcc9431f --- /dev/null +++ b/src/containers/book-list.js @@ -0,0 +1,30 @@ +import React, {Component} from 'react'; +import { connect } from 'react-redux'; + +class BookList extends Component { + renderList(){ + return this.props.books.map((book) => { + return( +
  • {book.title}
  • + ); + }); + } + + render (){ + return ( + + ); + } +} + +function mapStateToProps(state) { + //Whatever is returned will show up as props inside of BookList + + return { + books: state.books + }; +} + +export default connect(mapStateToProps)(BookList); \ No newline at end of file diff --git a/src/reducers/index.js b/src/reducers/index.js index d12506f382..a14d6da23c 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -1,7 +1,8 @@ import { combineReducers } from 'redux'; +import BooksReducer from './reducer_books'; const rootReducer = combineReducers({ - state: (state = {}) => state + books: BooksReducer }); export default rootReducer; diff --git a/src/reducers/reducer_books.js b/src/reducers/reducer_books.js new file mode 100644 index 0000000000..8a71e6972d --- /dev/null +++ b/src/reducers/reducer_books.js @@ -0,0 +1,8 @@ +export default function () { + return [ + {title: 'javascript: The Good Parts'}, + {title: 'Harry Potter'}, + {title: 'The Dark Tower'}, + {title: 'Eloquent Ruby'} + ] +} \ No newline at end of file From ee3e687c3c2274f88a2e15e74fc0d9062760f2fd Mon Sep 17 00:00:00 2001 From: KancerEzeroglu Date: Tue, 24 Oct 2017 13:18:08 +0300 Subject: [PATCH 2/3] Variable names have been changed to be more understandable. --- src/containers/book-list.js | 4 ++-- src/reducers/index.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/containers/book-list.js b/src/containers/book-list.js index 31fcc9431f..b1af5ceb46 100644 --- a/src/containers/book-list.js +++ b/src/containers/book-list.js @@ -3,7 +3,7 @@ import { connect } from 'react-redux'; class BookList extends Component { renderList(){ - return this.props.books.map((book) => { + return this.props.books_prop.map((book) => { return(
  • {book.title}
  • ); @@ -23,7 +23,7 @@ function mapStateToProps(state) { //Whatever is returned will show up as props inside of BookList return { - books: state.books + books_prop: state.booksReducer }; } diff --git a/src/reducers/index.js b/src/reducers/index.js index a14d6da23c..96701eba00 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -2,7 +2,7 @@ import { combineReducers } from 'redux'; import BooksReducer from './reducer_books'; const rootReducer = combineReducers({ - books: BooksReducer + booksReducer: BooksReducer }); export default rootReducer; From b5c33b0e58cdf1c28c40cb17db3dc9f69d50b402 Mon Sep 17 00:00:00 2001 From: KancerEzeroglu Date: Tue, 24 Oct 2017 15:46:14 +0300 Subject: [PATCH 3/3] Added the action --- src/actions/index.js | 9 +++++++++ src/components/app.js | 2 ++ src/containers/book-detail.js | 27 +++++++++++++++++++++++++++ src/containers/book-list.js | 15 +++++++++++++-- src/reducers/index.js | 4 +++- src/reducers/reducer_active_book.js | 8 ++++++++ src/reducers/reducer_books.js | 8 ++++---- 7 files changed, 66 insertions(+), 7 deletions(-) create mode 100644 src/containers/book-detail.js create mode 100644 src/reducers/reducer_active_book.js diff --git a/src/actions/index.js b/src/actions/index.js index e69de29bb2..03b6268c12 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -0,0 +1,9 @@ +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 + }; +} \ No newline at end of file diff --git a/src/components/app.js b/src/components/app.js index b01559051a..bf7464da1c 100644 --- a/src/components/app.js +++ b/src/components/app.js @@ -1,12 +1,14 @@ import React, { Component } from 'react'; import BookList from '../containers/book-list'; +import BookDetail from '../containers/book-detail'; export default class App extends Component { render() { return (
    +
    ); } diff --git a/src/containers/book-detail.js b/src/containers/book-detail.js new file mode 100644 index 0000000000..437fb57761 --- /dev/null +++ b/src/containers/book-detail.js @@ -0,0 +1,27 @@ +import React, { Component } from 'react'; +import {connect} from 'react-redux'; + +class BookDetail extends Component{ + + render(){ + + if(!this.props.book){ + return
    Select a book to get started.
    ; + } + return( +
    +

    Details for:

    +
    Title: {this.props.book.title}
    +
    Pages: {this.props.book.pages}
    +
    + ); + } +} + +function mapStateToProps(state) { + return { + book: state.activeBookReducer + }; +} + +export default connect(mapStateToProps)(BookDetail); \ No newline at end of file diff --git a/src/containers/book-list.js b/src/containers/book-list.js index b1af5ceb46..51e0ab43ca 100644 --- a/src/containers/book-list.js +++ b/src/containers/book-list.js @@ -1,11 +1,15 @@ import React, {Component} from 'react'; import { connect } from 'react-redux'; +import { selectBook } from "../actions/index"; +import { bindActionCreators } from 'redux'; class BookList extends Component { renderList(){ return this.props.books_prop.map((book) => { return( -
  • {book.title}
  • +
  • this.props.selectBook_prop(book)} + className="list-group-item"> {book.title}
  • ); }); } @@ -27,4 +31,11 @@ function mapStateToProps(state) { }; } -export default connect(mapStateToProps)(BookList); \ No newline at end of file +//Anything returned from this function will end up as props on the BookList container +function mapDispatchToProps(dispatch){ + //Whenever selectBook is called, the result should be passed to all of our reducers + return bindActionCreators({selectBook_prop: selectBook}, dispatch); +} +//Promote BookList from a component to a container - it needs to know about this dispatch method, selectBook. +//Make it available as a prop. +export default connect(mapStateToProps, mapDispatchToProps)(BookList); \ No newline at end of file diff --git a/src/reducers/index.js b/src/reducers/index.js index 96701eba00..a3b0bb516f 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -1,8 +1,10 @@ import { combineReducers } from 'redux'; import BooksReducer from './reducer_books'; +import ActiveBook from './reducer_active_book'; const rootReducer = combineReducers({ - booksReducer: BooksReducer + booksReducer: BooksReducer, + activeBookReducer: ActiveBook }); export default rootReducer; diff --git a/src/reducers/reducer_active_book.js b/src/reducers/reducer_active_book.js new file mode 100644 index 0000000000..881a3dfc54 --- /dev/null +++ b/src/reducers/reducer_active_book.js @@ -0,0 +1,8 @@ +//State argument is not application state, only the state this reducer is responsible for +export default function (state = null, action) { + switch (action.type){ + case 'BOOK_SELECTED': + return action.payload; + } + return state; +} \ No newline at end of file diff --git a/src/reducers/reducer_books.js b/src/reducers/reducer_books.js index 8a71e6972d..45ed22517e 100644 --- a/src/reducers/reducer_books.js +++ b/src/reducers/reducer_books.js @@ -1,8 +1,8 @@ export default function () { return [ - {title: 'javascript: The Good Parts'}, - {title: 'Harry Potter'}, - {title: 'The Dark Tower'}, - {title: 'Eloquent Ruby'} + {title: 'javascript: The Good Parts', pages: 101}, + {title: 'Harry Potter', pages: 39}, + {title: 'The Dark Tower', pages: 85}, + {title: 'Eloquent Ruby', pages: 1} ] } \ No newline at end of file