La documentación de redux, al recomendar las mejores prácticas para reducer, menciona la refactorización de declaraciones de cambio y su reemplazo con un diccionario/mapa de acción para el controlador, por lo que en lugar de:
switch(action) { case 'action1': doAction1(payload); case 'action2': doActions2(payload); }tendrías algo como:
var handlers = { 'action1': doAction1, 'action2': doAction2, } handlers[action](payload);(consulte https://redux.js.org/usage/structuring-reducers/refactoring-reducer-example )
Puedo ver que el enfoque del diccionario es más limpio de leer. Me pregunto si esta es la única razón por la que se prefiere. ¿O el diccionario también supera al interruptor?
Absolutamente no importa en absoluto para el rendimiento en cualquier aplicación real.
Dicho esto, tampoco debería estar en condiciones de pensar en ello, sino que use el kit de herramientas oficial de Redux, que es la forma oficialmente recomendada de escribir Redux desde hace dos años, y allí solo usaría la función createSlice , que tomaría un mapa de reducción de casos, envuélvalos en immer y haga muchas otras cosas convenientes para usted.
Para obtener una descripción general rápida de Redux Toolkit, consultehttps://redux.js.org/tutorials/fundamentals/part-8-modern-redux
Para obtener un tutorial completo sobre "Redux moderno", consulte https://redux.js.org/tutorials/essentials/part-1-overview-concepts
Algunas personas tienen objeciones ideológicas para cambiar declaraciones, en parte debido a la posibilidad de perder declaraciones de break accidentalmente y tener casos fallidos. En el caso de un reductor redux, eso no es un problema ya que cada caso devuelve el nuevo estado, por lo que personalmente no tengo ningún problema con el cambio aquí, y ni siquiera estoy seguro de estar de acuerdo en que el diccionario sea 'limpio'.
Rendimiento de WRT, preferiría la opción estilísticamente preferida porque en el 99,9 % de los casos de redux, no actualizará el estado con la frecuencia suficiente para que estas diferencias menores importen. Pero está bien, chupémoslo y veamos cuál funciona más rápido:
const keys = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']; let count = 0; const increment = () => ++count; // just do something on each action console.time("switch"); for (let i = 0; i < 10000000; i++) { const k = keys[Math.floor(Math.random() * keys.length)]; switch (k) { case 'a': increment(); break; case 'b': increment(); break; case 'c': increment(); break; case 'd': increment(); break; case 'e': increment(); break; case 'f': increment(); break; case 'g': increment(); break; case 'h': increment(); break; case 'i': increment(); break; case 'j': increment(); break; case 'k': increment(); break; case 'l': increment(); break; case 'm': increment(); break; case 'n': increment(); break; case 'o': increment(); break; case 'p': increment(); break; case 'q': increment(); break; case 'r': increment(); break; case 's': increment(); break; case 't': increment(); break; case 'u': increment(); break; case 'v': increment(); break; case 'w': increment(); break; case 'x': increment(); break; case 'y': increment(); break; case 'z': increment(); break; } } console.timeEnd('switch'); console.time('map'); const map = keys.reduce((a, b) => { a[b] = increment; return a; }, {}); for (let i = 0; i < 10000000; i++) { const k = keys[Math.floor(Math.random() * keys.length)]; map[k](); } console.timeEnd('map'); // switch: 529.752ms // map: 737.213msAsí que el cambio gana, por un margen significativo, aunque no enorme. Sin embargo, nunca lo notará en la práctica, así que elija el que prefiera desde una perspectiva de legibilidad.
Esto es lo que veo ejecutando su código exacto en Chrome en 2022:
switch: 304.3369140625 ms map: 187.68896484375 msTambién estás incluyendo la construcción del mapa en tu tiempo. En este caso, no es significativo porque su ciclo es muy grande, pero es un poco engañoso.
Depende de sus casos de uso, pero un mapa a menudo será más rápido para grandes conjuntos de condiciones. Las diferencias serán más evidentes para diferentes situaciones; puede ser muy importante para algunos y no para otros. En C ++, esto también es completamente diferente, porque el compilador puede optimizar las declaraciones de cambio (en algunos casos creará búsquedas binarias de sus claves), así que tenga cuidado con las generalizaciones.
En los casos de sentencias de cambio más pequeñas, la diferencia casi seguramente será insignificante. En reaccionar, estoy más preocupado por la cantidad de declaraciones de cambio que se visitan para diferentes secciones de subestado. Parece que dado que Redux no sabe qué tipos de acción están asociados con un reductor en particular, ejecuta todos los reductores posibles para un estado dado. es decir, si hay 20 reductores, tal vez solo 3 respondan a un tipo de acción en particular, pero todos se evalúan. Si, en cambio, mapeó esto por tipo de acción a través de un mapa, podría ser una búsqueda de un solo mapa que produzca los 3 reductores relevantes. Tal vez haya una forma inteligente de optimizar esto en Redux/React, pero en realidad no es culpa del interruptor, sino de la arquitectura (y quizás el uso excesivo del reductor, que podría ser un problema de diseño con la aplicación en particular).