Implementación de la arquitectura Redux en MobX. Parte 1: "Ubicaciones de problemas de Redux"

Esta parte del artículo tratará sobre la comprensión de los ingredientes de Redux. ¿Son tan necesarios, cuál es su análogo? También se propondrá una alternativa más conveniente al gancho useReducer.





En realidad, no reproduciré Redux. En cambio, la siguiente parte describirá cómo diseñar una mejor arquitectura usando MobX. La siguiente parte es principalmente para aquellos cuyos proyectos en MobX resultaron ser confusos, con cambios incontrolados.





En esta parte del artículo, quiero mostrar que:





  • los reductores son análogos de las funciones puras ordinarias para obtener un nuevo estado.





  • los selectores son análogos a las funciones memorizadas regulares que devuelven datos.





  • Los creadores de envío + acción + acción son análogos a las llamadas de función regulares, y la división en creadores de envío, acción y acción a menudo es innecesaria y se usa fuera de lugar.





El artículo no cubrirá el kit de herramientas de Redux y otras bibliotecas para reducir el texto estándar. Justo de la forma en que se usó originalmente Redux. Tenga en cuenta que una estructura similar del código de la tienda, a la que llegaron los desarrolladores de la biblioteca Redux, existía antes de la aparición de Redux Toolkit en una forma más fácil de usar en otros administradores estatales, como MobX, Vuex (a veces lo mencionaré , porque es similar a MobX, y estoy un poco familiarizado con él).





Contenido de la primera parte





Un almacenamiento (tienda) frente a varios almacenamientos

El enfoque unilateral tiene ventajas y desventajas. Pero los proyectos de Vuex y MobX funcionan muy bien con varias tiendas. Más aún, la presencia de tiendas en el proyecto es opcional. Pero separar los datos y la lógica para trabajar con ellos del resto del programa, así como separar los datos de la lógica, brinda oportunidades y conveniencia adicionales durante el desarrollo.





" " , . , ( , localStorage/sessionStorage, ) , . Redux , , .





Reducer vs . SOLID

- , , Redux, . , , , () - .





- ugly switch O(n), actions . O(n) , 60 . – . swith - [actionNameKey][function] .





- , , , , .





3 SOLID GRASP

, . , / / . . . " SOLID" " ". : " , SOLID, , , ". . - , /. , , , .





" ". , ,  . .





single-responsibility principle (SRP)

,   . . , . "" -. - , .





, - . . actions. actions. , . , combineReducers.





/

/ , :





  • : , .





  • : , , .





, .





action , . . ( JS ), . , action-.





, . , , Redux - actions , , , . , actions .





LSP - , , , .





https://medium.com/webbdev/solid-4ffc018077da - , : " , , ."





, . , LSP, . , . " ..." , .





. , , , switch, , action -.





.





(High Cohesion) GRASP

( /) - , . ", ." , , .





, switch, . , . . action.type. , case . / /. - , .





SRP SOLID. . , actions, . , action, .





. . , .





. , – . , - action, . - . - , , . :





case 'todos/todoAdded': {
  return {
    ...state,
    todos: [
      ...state.todos,
      action.paylod.newTodo
    ]
  }
}
      
      



:





function todoAdded(state, newTodo) {
  return {
    ...state,
    todos: [
      ...state.todos,
      newTodo
    ]
  }
}
      
      



- , . type action, Redux, . - . , , / : todoStore['todoAdded'].





vs ,

Redux - . , - . .





MobX (computed values). , , JS . . , Vuex - .





Redux, , middleware. . MobX .





- MobX vs - middleware's

Redux - , , .





Vuex MobX , action API -. Vuex - . , . -, ( ). MVC .   MVC wikipedia - MVC, . , Vuex MobX - MVVM, MVC.





, , . , . , , AngularJS 1.x. , .





- . 2 (, api ), . – ,   . , .





, - , , , . () .





Action creators, actions, dispatch VS

  Redux - .   .





, , - . Redux pub/sub (-).





Pub/sub ( ) , .





, , :





  • . , ( ) .





  • , - , . , . - React . , .. react-.





Redux action-? :





  1. , middleware;





  2. middleware, ;





  3. , , .





? . , - , . actions - . 3- actions . 3 actions ( ).





1. middleware- ( ). , ?





Action, middleware, . .





. dispatch middleware-? -, . , .. . , middleware- middleware .





-, .





2. Middleware . . action ? . , .





3. actions . actions action , . .





- useReducer?

, - , .





useReducer , . . actions, .. , . useReducer - .





La funcionalidad similar a useReducer se puede realizar manualmente a través de useState, pero esto es largo e inconveniente. Pero no puedes hacerlo cada vez, sino sacarlo por separado, lo cual hice. Escribí un gancho useStateWithUpdaters para escribir código más legible y utilizable. A continuación se muestra un ejemplo de su uso:





const updaters = {
  subtract: (prevState, value) => (
    { ...prevState, count: prevState.count - value }
  ),
  add: (prevState, value) => (
    { ...prevState, count: prevState.count + value }
  ),
};

const MyComponent = () => {
  const [{ count }, {add, subtract}] = 
        useStateWithUpdaters({ count: 0 }, updaters);
  return (
    <div>
      Count: {count}
      <button onClick={() => subtract(1)}>-</button>
      <button onClick={() => add(1)}>+</button>
    </div>
  );
};
      
      



Puede encontrar su implementación en cuestión .

Hay una versión de TypeScript .





También puede mejorarlo un poco: combine el nuevo estado con el anterior en la implementación del propio gancho, de modo que no tenga que escribir constantemente "... prevState".








All Articles