R&R

Motivación

 

Redux

 

Redux + UI (React)

Motivación

UIs complejas

No determinísticas

 

Estados cambiantes

Vista

BIDIRECCIONALIDAD

Modelo

Modelo

Modelo

Vista

Vista

Vista

Redux

Actions

 

State

Reducers

 

Store

Actions

¿qué ocurre?

function searchUser(text) {
  return {
    type: 'SEARCH_USER',
    text
  }
}
dispatch(searchUser('foo bar'))
{
  type: 'SEARCH_USER',
  text: 'foo bar'
}

State

¿Cómo es?

{
  users: [{
    _id: 'uid1',
    name: 'foo'
  }, {
    _id: 'uid109',
    name: 'bar'
  }],
  searchText: 'foo bar'
}

Reducers

¿Cómo cambio?

 

function nubicoApp(state = initialState, action) {
  switch (action.type) {
    case 'ADD_USER':
      return Object.assign({}, state, {
        users: [
           ...state.users,
           {
             _id: action.id,
             name: action.name
           }
        ]
      })
    default:
      return state
  }
}
Array.prototype.reduce(function (state, action) {
  //Return a new state created by an action
}, initialValue)

Reducers (2) - Reducer Composition

function users(state = [], action) {
  switch (action.type) {
    case ADD_USER:
      return [
        ...state,
        {
          _id: action.id,
          name: action.name
        }
      ]
    case RENAME_USER:
      return state.map((user, index) => {
        if (index === action.index) {
          return Object.assign({}, user, {
            name: action.name
          })
        }
        return user
      })
    default:
      return state
  }
}

//Main reducer
function nubicoApp(state = {}, action) {
  return {
    users: users(state.users, action),
    books: books(state.books, action)
  }
}

Reducers (3), less boilerplate

import { combineReducers } from 'redux'
import users from './users'
import books from './books'

const nubicoApp = combineReducers({
  users,
  books
})

export default nubicoApp

Store
Orquesta

import nubicoApp from './reducers'

const store = createStore(nubicoApp)
store.dispatch({
  type: ADD_USER,
  name: 'pepito',
  _id: 'uid1'
})
//This will call the reducers and emit state updates
store.getState()
//Listen to state update
let unsubscribe = store.subscribe(cb)
//Remove listener
unsubscribe()

Estado global (1 solo store)

Acciones

Funciones puras

UI

REACT

react-redux bindings

Componentes de presentación + Componentes contenedores

var NubicoApp = React.createClass({
  getInitialState: function() {
    return {users: [], name: ''};
  },
  onChange: function(e) {
    this.setState({name: e.target.value});
  },
  handleSubmit: function(e) {
    e.preventDefault();
    var nextItems = this.state.users.concat([{name: this.state.name, id: Date.now()}]);
    var nextText = '';
    this.setState({users: nextItems, name: nextText});
  },
  render: function() {
    return (
      <div>
        <h3>Users</h3>
        <UsersList users={this.state.users} />
        <form onSubmit={this.handleSubmit}>
          <input onChange={this.onChange} value={this.state.name} />
          <button>{'Add #' + (this.state.users.length + 1)}</button>
        </form>
      </div>
    );
  }
});

ReactDOM.render(<NubicoApp />, mountNode);

Demo

THE END

resources

https://blog.andyet.com/2015/08/06/what-the-flux-lets-redux/

 

http://likethemammal.github.io/reacttalk/

 

https://www.youtube.com/watch?v=Nl7vV6xxcKk

 

Made with Slides.com