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

Organización de código con React y Redux

Organización de código con React y Redux

Algunas reflexiones sobre cómo organizar código.

Avatar for Elías Alonso

Elías Alonso

May 20, 2016
Tweet

Other Decks in Technology

Transcript

  1. ¿De qué va esto? • ¿Qué significa "organización de código?"

    • ¿Puedes seguir mis consejos ciégamente? • ¿Qué pasa si no estás de acuerdo? • ¿Están las diapos online?
  2. A vista de pájaro • Componentes: Presentación • Store: Estado

    • Reducers: Transformaciones del estado • Action builders: Lo que metemos bajo la alfombra
  3. ¿En qué se diferencian estos cuatro grupos? • A todos

    nos gusta esa clasificación • Vamos a pensar un segundo sobre... • ¿Qué hace que sean buenas categorías? • ¿Hay ideas generales por detrás? • ¿Podemos aplicarlas al resto de nuestro código?
  4. ¿En qué se diferencian estos cuatro grupos? • ¿Están agrupados

    por... • entidades o dominio? NO • jerarquía o tamaño? NO • ruta o proximidad? NO
  5. Para freír un huevo Sitúate en el centro de la

    concina, gira 30 grados a la izquierda, avanza 500mm en línea recta, después gira 45 grados al aderecha. Eleva tu mano derecha hasta que el brazo quede horizontal al suelo y extiéndela despacio hasta que choques con el mango de la puerta de la nevera. Ciérrala y retrae el brazo con firmeza. Ahora abre la otra mano...
  6. Para freír un huevo Necesitas: un huevo, una sartén, aceite,

    sal. 1. Cubre el fondo de la sarten con 5mm de aceite 2. Cuando esté muy caliente, casca el huevo encima 3. Saca una cerveza del frigorífico. 4. Bébetela deseando saber cocinar mejor. 5. ....
  7. Algunos consejos para escribir recetas 1. Habla desde el nivel

    de abstracción adecuado. 2. Completa el mensaje. 3. No cambies de tema.
  8. Algunos consejos para escribir recetas 1. Habla desde el nivel

    de abstracción adecuado. 2. Completa el mensaje. 3. No cambies de tema. 4. ¡Se coherente! (no mezcles)
  9. Algunos consejos para escribir código 1. Habla desde el nivel

    de abstracción adecuado. 2. Completa el mensaje. 3. No cambies de tema. 4. ¡Se coherente! (no mezcles)
  10. class Toggle extends Component { constructor (props) { super(props) this.state

    = {checked: false} } onChange () { this.setState({ checked: !this.state.checked }) } render () { return (<input type="checkbox" checked={this.state.checked} onChange={this.onChange.bind(this)} />) } }
  11. const Tabbed = (tabs) => (Component) => { return class

    Tabbed extends Component { constructor (props) { /* ... */ } getKeys () { /* ... */ } getActiveContent () { /* ... */ } changeTab = (key) => { /* ... */ } render () { return <Component keys={this.getKeys()} activeContent={this.getActiveContent()} changeTab={this.changeTab} {...this.props} /> } } }
  12. function Tabs (props) { return ( <div> ... </div> )

    } exports default tabbed([ {label: 'home', content: HomeContent}, {label: 'profile', content: ProfileContent}, {label: 'settings', content: SettingsContent} ])(Tabs)
  13. Una proeza de expresión • Interacción y presentación son abstracciones

    diferentes. • ROLES diferentes. • Se coherente... ¡no mezcles!. • ¿Qué otros roles hay (en el Reino de React)?
  14. Para freír un huevo Necesitas: un huevo, una sartén, aceite,

    sal. 1. Vierte 5mm de aceite en la sartén y caliéntalo. 2. Cuando esté muy caliente, casca el huevo y échalo. 3. Espera a que la clara se ponga blanca. 4. En ese momento puedes sacar el huevo. 5. Comer mientras está caliente.
  15. Para freír un huevo Necesitas: un huevo, una sartén, aceite,

    sal. 1. Vierte 5mm de aceite en la sartén y caliéntalo. 2. Cuando esté muy caliente, casca el huevo y échalo. 3. Espera a que la clara se ponga blanca. 4. En ese momento puedes sacar el huevo. 5. Comer mientras está caliente.
  16. Algunos consejos para escribir código 1. Habla desde el nivel

    de abstracción adecuado. 2. Completa el mensaje. 3. No cambies de tema. 4. Encuentra los mecanismos de combinación. 5. ¡Se coherente! (no mezcles)
  17. function Tabs (props) { return ( <div> ... </div> )

    } exports default tabbed([ {label: 'home', content: HomeContent}, {label: 'profile', content: ProfileContent}, {label: 'settings', content: SettingsContent} ])(Tabs)
  18. Una proeza de expresión • tabbed habla sobre interacción •

    Tabs habla sobre presentación composición • HomeContent habla sobre presentación
  19. Una proeza de expresión • Interacción cómo manejar eventos tabbed,

    ... • Composición proximidad y anidamiento Tabs, ... • Presentación qué pinta tiene HomeContent, ...
  20. Una proeza de expresión • Interacción cómo manejar eventos tabbed,

    ... • Composición proximidad y anidamiento Tabs, ... • Presentación qué pinta tiene HomeContent, ... • Contextualización conectar con datos específicos
  21. Sobre SMART vs. DUMB • Contextualización Casi siempre conectado. •

    Interacción Tal vez conectado, pero en aislamiento. • Composición No conectado. • Presentación NUNCA JAMÁS conectado. Ni de coña.
  22. Sobre carpetas y tal • Agrupa por ROL Todos los

    ficheros en una carpeta deberían ser coherentes en abstracción y variar en tema. • NO agrupes por dominio Dominio no es uno de los Cuatro. Es un concepto extraño al Reino de React. • La nomenclatura no es tan importante Siempre y cuando sea consistente y no sea una locura total.
  23. Sobre carpetas y tal components/ ├── composition │ └── AdminLayout.jsx

    ├── interaction │ ├── Tabbed.jsx │ └── TableListing.jsx ├── context │ ├── LoggedHeader.jsx │ └── UserListing.jsx └── presentation └── UserRow.jsx
  24. Sobre carpetas y tal components/ ├── composition ├── context ├──

    interaction ├── presentation └── pages └── UsersIndex ├── index.jsx ├── composition ├── context ├── interaction └── presentation
  25. Alt: sobre carpetas y tal components/ ├── layouts (composition) ├──

    connected (context) ├── controllers (interaction) ├── views (presentation) └── pages └── UsersIndex ├── index.jsx ├── layouts ├── connected ├── controllers └── views
  26. Alt: sobre carpetas y tal components/ ├── molecules (composition) ├──

    ecosystems (context) ├── organisms (interaction) ├── atoms (presentation) └── environments └── UsersIndex ├── index.jsx ├── molecules ├── ecosystems ├── organisms └── atoms
  27. la República de Redux • Lógica de negocio = No

    se puede generalizar • Cada caso tiene sus puntos óptimos de corte • Pero casi todas las webs tiene cosas en común... • ¿Podríamos extraer patrones generales?
  28. Consejos Sobregeneralizados 1. Agrupa por función 2. Una única "fuente

    de verdad" 3. Explícito > Implícito 4. Normaliza tus datos 5. Dominio es un parámetro
  29. Agrupa por FUNCIÓN • /src/modules/ Funcionalidad general. Toda la maquinaria

    redux. • /src/services/ Para procesos específicos. Sobre todo action creators. • /src/policies/ Permisos, reglas de acceso, etc... Ajeno a redux.
  30. src/ ├── modules │ ├── entities │ │ ├── actionTypes.js

    │ │ ├── actions.js │ │ ├── reducer.js │ │ └── selectors.js │ ├── crud │ │ └── ... │ └── session │ └── ... ├── policies │ ├── lite.js │ └── premium.js └── services ├── login.js ├── payWithPaypal.js └── validateCaptcha.js
  31. Si necesita reducer, (tal vez) es un módulo. . Si

    no, (a lo mejor) es un servicio. . Pero quién sabe...
  32. Agrupa por FUNCIÓN { entities: { users: { 1: {id:

    1, name: "John", likesRedux: false}, 2: {id: 2, name: "Mary", likesRedux: true}, } }, pagination: { users: {page: 2, results: [1, 2, 3, 4]} }, session: { token: '000' } }
  33. Dominio como parámetro • El dominio puede ser un parámetro

    la mayoría de las veces. { type: actionTypes.GO_TO_PAGE, payload: {page: 2}, domain: 'users' } • Agrupar por función ayuda a ser consistente en nivel de abstracción y tema.
  34. Una sola "source of truth" • Nunca guardes un mismo

    dato en dos lugares • ¡Denormaliza! • Los selectors son tus aliados • El store es tu aliado • this.state no es tu aliado
  35. We can solve any problem by introducing an extra level

    of indirection. — Fundamental theorem of software engineering (David J. Wheeler)
  36. Si tienes problemas programando algo, piensa.. 1. ¿Qué estoy intentando

    expresar aquí? 2. ¿En qué nivel de abstracción? 3. ¿Qué combinadores puedo usar? 4. ¿Tengo todo el vocabulario que necesito? 5. ¿Estoy hablando de más de un tema?
  37. Normaliza tus datos • Usa esquemas de datos • Almacena

    denormalizado en el store • Valida los datos externos • normalizr es tu aliado