SlideShare a Scribd company logo
BY MICHEL PEREZ
REACT + REDUX
REACT
React is a JavaScript Library for building user interfaces.
• Focus on the UI, not a Framework like Angular or Ember
• One-way reactive data flow (no two-way data binding)
• Components
• Virtual DOM
VIRTUAL DOM
Keep track of state in DOM is hard
The DOM API is slow.
Efficient updates to subtrees
VIRTUAL DOM UPDATING
THE HELLO WORLD
import React from 'react'

import ReactDOM from 'react-dom'



const exampleElement = document.getElementById('example')

ReactDOM.render(<h1>Hello, world!</h1>, exampleElement)
<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8" />

<script src="bundle.js"></script>

</head>

<body>

<div id="example"></div>

</body>

</html>
JSX
JSX is a JavaScript syntax extension that looks similar to
XML is used to create React Elements
// Input (JSX):

var app = <h2 color="blue" />

// Output (JS):

var app = React.createElement(h2, {color:"blue"})
STATEFUL COMPONENT
class DeleteLink extends React.Component{

constructor(props){

super()
this.state = {}

this.index = props.index

this.deleteComponentHandler = this.deleteComponentHandler.bind(this) 

}



render(){

return(

<a href="#" className="delete-component" onClick={(e) => {

e.preventDefault()

this.deleteComponentHandler(index)

}}>

<i className="fa fa-trash" aria-hidden="true"></i>

</a>

)

}



deleteComponentHandler(index){

// do something

}

}



export default DeleteLink
COMPONENT LIFECYCLE
class MyComponent extends React.Component {

constructor() {

}

render() { //pure returns the view calling jsx tags

}

getInitialState() { // called before the component is mounted, inits this.state

}

getDefaultProps() { // inits this.props

}

componentWillMount() { called once before the initial render

}

componentDidMount() { // called once after the initial render

}

componentWillReceiveProps() { // called when the props are updated

}

shouldComponentUpdate() { // should update the component in the three?

}

componentWillUpdate() { // do something before an update, not to call
this.setState

}

componentDidUpdate() { // do something when the components have been updated

}

}
STATELESS COMPONENT
import React, {PropTypes} from 'react'



const DeleteLink = ({index}) => {

return (

<a href="#" className="delete-component">

<i className="fa fa-trash" aria-hidden="true"></i>

</a>

)

}



DeleteLink.propTypes = {

index: PropTypes.number.isRequired,

deleteComponentHandler: PropTypes.func.isRequired

}



export default DeleteLink

WHY STATELESS?
▸ Predictable
▸ Functional Programming
▸ Easy to understand
▸ Easy to test
REACT + ?
REDUX
▸ Handles the state of the Application with predictable
behaviour
▸ Takes ideas from ELM
▸ Store: The state
▸ Actions: The intent of changing the state
▸ Reducer: (previousState, action) => newState
▸ Components: The view (Here goes react)
▸ Containers: Components decorators
REDUX ARCHITECTURE
Store
Action
Creators
Reducers
dispatch(action)
(newState)
(state)
(previousState, action)
React
Components
STORE
import React from 'react'

import { render } from 'react-dom'

import { Provider } from 'react-redux'

import { createStore } from 'redux'

import todoApp from './reducers'

import App from './components/App'



let store = createStore(todoApp)



render(

<Provider store={store}>

<App />

</Provider>,

document.getElementById('main')

)
THE APP
import React from 'react'

import AddTodoContainer from '../containers/AddTodoContainer'

import VisibleTodoList from '../containers/VisibleTodoList'



const App = () => (

<div>

<AddTodoContainer />

<VisibleTodoList />

</div>

)



export default App
THE ADD TODO
import React, { PropTypes } from 'react'



let AddTodo = ({ onInputSubmit }) => {

let input



return (

<div>

<form onSubmit={(e) => onInputSubmit(e, input)}>

<input ref={node => input = node } />

<button type="submit">

Add Todo

</button>

</form>

</div>

)

}



AddTodo.propTypes = {

onInputSubmit: PropTypes.func.isRequired

}



export default AddTodo
THE CONTAINER
import React from 'react'

import { connect } from 'react-redux'

import { addTodo } from '../actions'

import AddTodo from '../components/AddTodo'



const mapDispatchToProps = (dispatch) => {

return {

onInputSubmit: (e, input) => {

e.preventDefault()

if (!input.value.trim()) {

return

}

dispatch(addTodo(input.value))

input.value = ''

}

} 

}



const AddTodoContainer = connect(null, mapDispatchToProps)(AddTodo)



export default AddTodoContainer
THE ACTIONS
let nextTodoId = 0


export const addTodo = (text) => {

return {

type: 'ADD_TODO',

id: nextTodoId++,

text

}

}
THE REDUCER
import { combineReducers } from 'redux'

import todos from './todos'



const todoApp = combineReducers({

todos

})

const todos = (state = [], action) => {

switch (action.type) {

case 'ADD_TODO':

return [

…state,
{id: action.id, text: action.text, completed: false}

]

default:

return state

}

}

export default todoApp
THE TODO LIST
import React, { PropTypes } from 'react'

import Todo from './Todo'



const TodoList = ({ todos }) => (

<ul>

{todos.map(todo =>

<Todo

key={todo.id}

{...todo}

/>

)}

</ul>

)



TodoList.propTypes = {

todos: PropTypes.arrayOf(PropTypes.shape({

id: PropTypes.number.isRequired,

completed: PropTypes.bool.isRequired,

text: PropTypes.string.isRequired

}).isRequired).isRequired

}



export default TodoList
THE TODO ITEM
import React, { PropTypes } from 'react'



const Todo = ({ completed, text }) => (

<li>

{text}

</li>

)



Todo.propTypes = {

completed: PropTypes.bool.isRequired,

text: PropTypes.string.isRequired

}



export default Todo
THE TODO LIST CONTAINER
import { connect } from 'react-redux'

import TodoList from '../components/TodoList'



const mapStateToProps = (state) => {

return {

todos: state.todos

}

}



const mapDispatchToProps = (dispatch) => {

return { }

}



const VisibleTodoList = connect(

mapStateToProps,

mapDispatchToProps

)(TodoList)



export default VisibleTodoList
ES6 THE IMMUTABLE
A new array
[

…state,
{id: action.id, text: action.text, completed: true}

]
A new object
return {...image, _destroy: {value: true}}
Immutable.js
https://facebook.github.io/immutable-js/
CONCLUSIONS
CONCLUSIONS II
THANKS

More Related Content

React redux

  • 2. REACT React is a JavaScript Library for building user interfaces. • Focus on the UI, not a Framework like Angular or Ember • One-way reactive data flow (no two-way data binding) • Components • Virtual DOM
  • 3. VIRTUAL DOM Keep track of state in DOM is hard The DOM API is slow. Efficient updates to subtrees
  • 5. THE HELLO WORLD import React from 'react'
 import ReactDOM from 'react-dom'
 
 const exampleElement = document.getElementById('example')
 ReactDOM.render(<h1>Hello, world!</h1>, exampleElement) <!DOCTYPE html>
 <html>
 <head>
 <meta charset="UTF-8" />
 <script src="bundle.js"></script>
 </head>
 <body>
 <div id="example"></div>
 </body>
 </html>
  • 6. JSX JSX is a JavaScript syntax extension that looks similar to XML is used to create React Elements // Input (JSX):
 var app = <h2 color="blue" />
 // Output (JS):
 var app = React.createElement(h2, {color:"blue"})
  • 7. STATEFUL COMPONENT class DeleteLink extends React.Component{
 constructor(props){
 super() this.state = {}
 this.index = props.index
 this.deleteComponentHandler = this.deleteComponentHandler.bind(this) 
 }
 
 render(){
 return(
 <a href="#" className="delete-component" onClick={(e) => {
 e.preventDefault()
 this.deleteComponentHandler(index)
 }}>
 <i className="fa fa-trash" aria-hidden="true"></i>
 </a>
 )
 }
 
 deleteComponentHandler(index){
 // do something
 }
 }
 
 export default DeleteLink
  • 8. COMPONENT LIFECYCLE class MyComponent extends React.Component {
 constructor() {
 }
 render() { //pure returns the view calling jsx tags
 }
 getInitialState() { // called before the component is mounted, inits this.state
 }
 getDefaultProps() { // inits this.props
 }
 componentWillMount() { called once before the initial render
 }
 componentDidMount() { // called once after the initial render
 }
 componentWillReceiveProps() { // called when the props are updated
 }
 shouldComponentUpdate() { // should update the component in the three?
 }
 componentWillUpdate() { // do something before an update, not to call this.setState
 }
 componentDidUpdate() { // do something when the components have been updated
 }
 }
  • 9. STATELESS COMPONENT import React, {PropTypes} from 'react'
 
 const DeleteLink = ({index}) => {
 return (
 <a href="#" className="delete-component">
 <i className="fa fa-trash" aria-hidden="true"></i>
 </a>
 )
 }
 
 DeleteLink.propTypes = {
 index: PropTypes.number.isRequired,
 deleteComponentHandler: PropTypes.func.isRequired
 }
 
 export default DeleteLink

  • 10. WHY STATELESS? ▸ Predictable ▸ Functional Programming ▸ Easy to understand ▸ Easy to test
  • 12. REDUX ▸ Handles the state of the Application with predictable behaviour ▸ Takes ideas from ELM ▸ Store: The state ▸ Actions: The intent of changing the state ▸ Reducer: (previousState, action) => newState ▸ Components: The view (Here goes react) ▸ Containers: Components decorators
  • 14. STORE import React from 'react'
 import { render } from 'react-dom'
 import { Provider } from 'react-redux'
 import { createStore } from 'redux'
 import todoApp from './reducers'
 import App from './components/App'
 
 let store = createStore(todoApp)
 
 render(
 <Provider store={store}>
 <App />
 </Provider>,
 document.getElementById('main')
 )
  • 15. THE APP import React from 'react'
 import AddTodoContainer from '../containers/AddTodoContainer'
 import VisibleTodoList from '../containers/VisibleTodoList'
 
 const App = () => (
 <div>
 <AddTodoContainer />
 <VisibleTodoList />
 </div>
 )
 
 export default App
  • 16. THE ADD TODO import React, { PropTypes } from 'react'
 
 let AddTodo = ({ onInputSubmit }) => {
 let input
 
 return (
 <div>
 <form onSubmit={(e) => onInputSubmit(e, input)}>
 <input ref={node => input = node } />
 <button type="submit">
 Add Todo
 </button>
 </form>
 </div>
 )
 }
 
 AddTodo.propTypes = {
 onInputSubmit: PropTypes.func.isRequired
 }
 
 export default AddTodo
  • 17. THE CONTAINER import React from 'react'
 import { connect } from 'react-redux'
 import { addTodo } from '../actions'
 import AddTodo from '../components/AddTodo'
 
 const mapDispatchToProps = (dispatch) => {
 return {
 onInputSubmit: (e, input) => {
 e.preventDefault()
 if (!input.value.trim()) {
 return
 }
 dispatch(addTodo(input.value))
 input.value = ''
 }
 } 
 }
 
 const AddTodoContainer = connect(null, mapDispatchToProps)(AddTodo)
 
 export default AddTodoContainer
  • 18. THE ACTIONS let nextTodoId = 0 
 export const addTodo = (text) => {
 return {
 type: 'ADD_TODO',
 id: nextTodoId++,
 text
 }
 }
  • 19. THE REDUCER import { combineReducers } from 'redux'
 import todos from './todos'
 
 const todoApp = combineReducers({
 todos
 })
 const todos = (state = [], action) => {
 switch (action.type) {
 case 'ADD_TODO':
 return [
 …state, {id: action.id, text: action.text, completed: false}
 ]
 default:
 return state
 }
 }
 export default todoApp
  • 20. THE TODO LIST import React, { PropTypes } from 'react'
 import Todo from './Todo'
 
 const TodoList = ({ todos }) => (
 <ul>
 {todos.map(todo =>
 <Todo
 key={todo.id}
 {...todo}
 />
 )}
 </ul>
 )
 
 TodoList.propTypes = {
 todos: PropTypes.arrayOf(PropTypes.shape({
 id: PropTypes.number.isRequired,
 completed: PropTypes.bool.isRequired,
 text: PropTypes.string.isRequired
 }).isRequired).isRequired
 }
 
 export default TodoList
  • 21. THE TODO ITEM import React, { PropTypes } from 'react'
 
 const Todo = ({ completed, text }) => (
 <li>
 {text}
 </li>
 )
 
 Todo.propTypes = {
 completed: PropTypes.bool.isRequired,
 text: PropTypes.string.isRequired
 }
 
 export default Todo
  • 22. THE TODO LIST CONTAINER import { connect } from 'react-redux'
 import TodoList from '../components/TodoList'
 
 const mapStateToProps = (state) => {
 return {
 todos: state.todos
 }
 }
 
 const mapDispatchToProps = (dispatch) => {
 return { }
 }
 
 const VisibleTodoList = connect(
 mapStateToProps,
 mapDispatchToProps
 )(TodoList)
 
 export default VisibleTodoList
  • 23. ES6 THE IMMUTABLE A new array [
 …state, {id: action.id, text: action.text, completed: true}
 ] A new object return {...image, _destroy: {value: true}} Immutable.js https://facebook.github.io/immutable-js/