Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Building React Native app with Redux (Binar Con...

Building React Native app with Redux (Binar Connect #3 2017)

In this slide you will learn the basic of Redux, accompanied with a simple todo app: https://github.com/untungs/todo-redux

Avatar for Untung Suryono

Untung Suryono

September 30, 2017
Tweet

Other Decks in Programming

Transcript

  1. var numbers = [0, 1, 2, 3]; var result =

    numbers.reduce((acc, val) => acc + val); console.log(result); // 6 Array.reduce() var numbers = [0, 1, 2, 3]; var result = numbers.reduce((acc, val) => acc + val); console.log(result); // 6
  2. Redux Parts Store – Action Reducer – Plain JS Object

    Function to create new state Holds application state
  3. Redux Data Flow Store Action Reducer State Component create action

    (event / user interaction) dispatch action subscribe Reducer Reducer
  4. Action • Describes something that happened (event/user interaction) • The

    only source of information for the store • Must be plain JavaScript object • Must have a type property { type: 'ADD_TODO', text: 'Build my first Redux app' }
  5. Reducer • Creates a new state based on previous state

    and an action (previousState, action) => newState (acc, val) => acc
  6. Reducer • Must be a pure function (no side effects,

    non-pure functions) • Consider the state as immutable (don’t mutate the state) function todos(state = [], action) { if (action.type === 'ADD_TODO') { const newState = state newState.push({ text: action.text, completed: false }) return newState } return state } BAD
  7. State Mutation const state = [{}, {}] const newState =

    state [{}, {}, {}] state newState newState.push({})
  8. const state = [{}, {}] const newState = state [{},

    {}, {}] state newState newState === state ? newState.push({}) Something changed, update the view! Nothing happened! State Mutation false true
  9. const state = [{}, {}] const newState = state [{},

    {}, {}] state newState newState === state ? newState.push({}) Something changed, update the view! Nothing happened! State Mutation Something changed, update the view! true
  10. Reducer • Must be a pure function (no side effects,

    non-pure functions) • Consider the state as immutable (don’t mutate the state) function todos(state = [], action) { if (action.type === 'ADD_TODO') { const newState = state newState.push({ text: action.text, completed: false }) return newState } return state } BAD
  11. Reducer • Must be a pure function (no side effects,

    non-pure functions) • Consider the state as immutable (don’t mutate the state) function todos(state = [], action) { if (action.type === 'ADD_TODO') { return [ ...state, { text: action.text, completed: false } ] } return state }
  12. Reducer function todos(state = [], action) { switch (action.type) {

    case 'ADD_TODO': return [ ...state, { text: action.text, completed: false} ] case 'TOGGLE_TODO': return state.map((todo, index) => { if (index === action.index) { return { ...todo, completed: !todo.completed } } return todo }) default: return state } }
  13. Reducer function todos(state = [], action) { switch (action.type) {

    case 'ADD_TODO': return [ ...state, { text: action.text, completed: false} ] case 'TOGGLE_TODO': return state.map((todo, index) => { if (index === action.index) { return { ...todo, completed: !todo.completed } } return todo }) default: return state } } function todos(state = [], action) { switch (action.type) { case 'ADD_TODO': return [ ...state, { text: action.text, completed: false} ] case 'TOGGLE_TODO': return state.map((todo, index) => { if (index === action.index) { return { ...todo, completed: !todo.completed } } return todo }) default: return state } }
  14. Reducer • Can be combined // SHOW_ALL, SHOW_COMPLETED, SHOW_ACTIVE function

    visibilityFilter(state = 'SHOW_ALL', action) { switch (action.type) { case 'SET_VISIBILITY_FILTER': return action.filter default: return state } } import { combineReducers } from 'redux' const todoApp = combineReducers({ visibilityFilter, todos }) function todos(state = [], action) { switch (action.type) { case 'ADD_TODO': return [ ...state, { text: action.text, completed: false} ] case 'TOGGLE_TODO': return state.map((todo, index) => { if (index === action.index) { return { ...todo, completed: !todo.completed } } return todo }) default: return state } }
  15. Store • Holds application state • Allows access to state

    via store.getState() • Allows state to be updated via store.dispatch(action) • Registers listeners via store.subscribe(listener) • It returns a function to unsubscribe the listener
  16. Store import { combineReducers, createStore } from 'redux' const todoApp

    = combineReducers({ visibilityFilter, todos }) const store = createStore(todoApp) store.dispatch({ type: 'ADD_TODO', text: 'Consider using Redux' }) store.dispatch({ type: 'ADD_TODO', text: 'Keep all state in a single tree' }) store.dispatch({ type: 'TOGGLE_TODO', index: 0 }) store.getState()
  17. Store import { combineReducers, createStore } from 'redux' const todoApp

    = combineReducers({ visibilityFilter, todos }) const addTodo = (text) => ({ type: 'ADD_TODO', text }) const toggleTodo = (index) => ({ type: 'TOGGLE_TODO', index }) const store = createStore(todoApp) store.dispatch(addTodo('Consider using Redux')) store.dispatch(addTodo('Keep all state in a single tree')) store.dispatch(toggleTodo(0)) store.getState()
  18. Store { visibilityFilter: 'SHOW_ALL', todos: [ { text: 'Consider using

    Redux', completed: true, }, { text: 'Keep all state in a single tree', completed: false } ] } import { combineReducers, createStore } from 'redux' const todoApp = combineReducers({ visibilityFilter, todos }) const addTodo = (text) => ({ type: 'ADD_TODO', text }) const toggleTodo = (index) => ({ type: 'TOGGLE_TODO', index }) const store = createStore(todoApp) store.dispatch(addTodo('Consider using Redux')) store.dispatch(addTodo('Keep all state in a single tree')) store.dispatch(toggleTodo(0)) store.getState()
  19. Provider Component • Provides store to child components import {

    createStore } from 'redux' import { Provider } from 'react-redux' const store = createStore(todoApp) render() { return ( <Provider store={store}> <App /> </Provider> ) }
  20. Connect function • Provides state object and dispatch method to

    wrapped component import { connect } from 'react-redux' mapStateToProps = state => ({ todos: state.todos }) mapDispatchToProps = dispatch => ({ onTodoClick: id => { dispatch(toggleTodo(id)) } }) const ConnectedTodoList = connect( mapStateToProps, mapDispatchToProps )(TodoList) export default ConnectedTodoList // inside TodoList component renderTodo = ({ item: todo }) => ( <Todo text={todo.text} completed={todo.completed} onClick={() => { this.props.onTodoClick(todo.id) }} /> ) render() { return ( <FlatList data={this.props.todos} renderItem={this.renderTodo} /> ) }
  21. More Libraries/Utilities • redux-logger • redux-thunk • redux-persist • reselect

    • normalizr • many more: http://redux.js.org/docs/introduction/Ecosystem.html
  22. Q&A