Videos.md 6.5 KB

Video 1: Setting up Webpack

  • React Dev Tools
  • Redux Dev Tools

Video 2: App Layout + Component Setup

Video 3: Create Single and PhotoGrid components

Video 4: Setting up React Router

import { Router, Route, IndexRoute, browserHistory } from 'react-router'

const router = (
    <Router history={browserHistory}>
        <Route path='/' component={Main}>
            <IndexRoute component={} />
            <Route path='/view/:postId' />
        </Route>
    </Router>
)

render(router, document.getElementById('root'))
  • Use <Link to=''>Bla</Link> to create push state links.
  • browserHistory will be replaced later by history which first syncs the browser history with the react store (see next video).

Video 5: Setting up React Store

  • One giant state for all data
  • it is called store

    import { createStore, compose } from 'redux'
    import { syncHistoryWithStore } from 'react-router-redux'
    import { browserHistory } from 'react-router'
    
    import rootReducer from './reducers/index'
    
    const store = createStore(rootReducer, defaultState)
    export const history = syncHistoryWithStore(browserHistory, store)
    export default store
    

Video 6: Redux Actions

  • actions invoke changes of the state (adding, updating, removing data)
  • actions are objects with two elements: type and payload
  • action creators are functions which return actions:

    function increment(index) {
    return {
        type: 'INCREMENT_LIKES',
        index,
    }
    }
    function addComment(postId, author, comment) {
    return {
        type: 'ADD_COMMENT',
        postId,
        author,
        comment
    }
    }
    

Video 7: Redux Reducers

  • reducers handle the data when an action is received
  • use one reducer per components
  • reducers are functions which take
    • the action
    • a copy of the current state
  • reducers return the updated state if there is a change, or the previous state
  • always start like this and then add some conditional functionality:

    function posts(state = [], action) {
    if (...) {
        return nextState
    }
    return state
    }
    
    export default posts
    
  • combine them in a root reducer

    import { combineReducers } from 'redux'
    import { routerReducer } from 'react-router-redux'
    
    import posts from './posts'
    const rootReducer = combineReducers({ posts, ..., routing: routerReducer })
    export default rootReducer
    
  • always add routing: routerReducer at the end to integrate the route changes with other action changes.

  • executes URL changes implicitely

  • https://github.com/reactjs/react-router-redux

Video 8: Integrating our Store with React Router

  • to make the store globally available, put it on top of the routing
  • replace the browserHistory as mentioned before.

    import { Router, Route, IndexRoute, browserHistory } from 'react-router'
    +import { Provider } from 'react-redux'
    +import store, { history } from './store'
    
    const router = (
    +   <Provider store={store}>
    -       <Router history={browserHistory}>
    +       <Router history={history}>
                <Route path='/' component={Main}>
                    <IndexRoute component={} \/>
                    <Route path='/view/:postId' \/>
                <\/Route>
            <\/Router>
    +   </Provider>
    )
    
    render(router, document.getElementById('root'))
    
  • The state is now stored in the store. $r.store.getState()

Video 9: Understanding the Reducer's Job and Dispatching Actions

  • action creators return actions
  • actions invoke state changes
  • reducers change the state
  • the store provides a dispatch function

    // on the console
    $r.store.dispatch({type: 'INCREMENT', index: 1})
    
  • The dispatcher sends the action to every reducer

  • Therefore, the reducer needs to have some conditional logic.

Video 10: Accessing dispatch and state with Redux

  • in regular React, the state or parts of it are propagated via props
  • in Redux, connect injects the data in the components that need it
  • for that, we wrap the main component with one that has the state and dispatcher propagated

    import { bindActionCreators } from 'redux'
    import { connect } from 'react-redux'
    import * as actionCreators from './actions/actionCreators'
    import Main from './Main'
    
    function mapStateToProps(state) {
        return {
            posts: state.posts,
            comments: state.comments,
        }
    }
    
    function mapDispatchToProps(dispatch) {
        return bindActionCreators(actionCreators, dispatch)
    }
    
    const App = connect(mapStateToProps, mapDispatchToProps)(Main)
    export default App
    
  • because Main ist just JSX, connect injects standardized props into it and makes the state and dispatcher available.

  • You can still propagate data down with props

Video 11: Displaying Redux State inside our Components

  • Creating React components

Video 12: Updating State with Reducers

  • Once you propagate the reducer function to the component, this is how you pass arguments to the function call

    • Remember that <button onClick={this.props.function(argument)} ...> would call the function at document load!

      <button onClick={this.props.function.bind(null, argument)} ...>
      
  • Use pure functions to manipulate state. So the same inputs (previous state, action) always gives the same output (next state).

    • Makes testing easier.
    • Enables Redux dev tools, time travel etc.
  • Do the same as in React state handling: Copy, modify, return copy:

    function posts(state = [], action) {
        switch(action.type) {
            const i = action.index
            case 'INCREMENT_LIKES' :
                return [
                    ...state.slice(0, i),
                    { ...state[i], likes: state[i].likes + 1 },
                    ...state.slice(i + 1)
                ]
            default:
                return state
        }
    }
    

Video 13: Displaying the Single Photo Component

  • Polyfills are new ES6 functions cross compiled for old browsers through Babel. [Example for findIndex()][1]
  • You can use findIndex() to get a certain element of an array

    render () {
        const { postId } = this.props.params
        const i = this.props.posts.findIndex((post) => post.code === postId)
        const post = this.props.posts[i]
        const comments = this.props.comments[postId] || []
        ...
    }
    

    1

Video 14: Displaying and Adding Comments