Redux: Serie de screencasts de Redux en Egghead

Creado en 24 nov. 2015  ·  69Comentarios  ·  Fuente: reduxjs/redux

Si está siguiendo el repositorio de Redux pero aún no se ha sumergido en él, o está confundido acerca de algunos de sus aspectos fundamentales, le alegrará saber que Egghead acaba de publicar mi serie Primeros pasos con Redux .

Cubre los mismos temas que la parte "Básicos" de los documentos, pero con suerte profundiza un poco más y asegura que _realmente_ comprenda los fundamentos de Redux.

Planeo crear más contenido sobre Redux en Egghead, esta vez, solo para suscriptores. Contará con temas más avanzados. Si tiene sugerencias particulares, por favor hágamelo saber en este hilo!

feedback wanted

Comentario más útil

@markerikson gracias por

Nota: Por conveniencia, voy a usar thunk para representar un enfoque de middleware arbitrario para asíncrono, ya sea redux-thunk o redux-promise, o lo que sea.

Su capa de interfaz de usuario solo conecta las interacciones del usuario con los controladores. Cuando alguien hace clic en un botón, su interfaz de usuario está configurada para llamar a _some_ handler. A menudo, el componente recibe estos controladores como accesorios, tal vez un creador de acciones vinculadas, por ejemplo. La interfaz de usuario no sabe lo que sucede cuando llama a un controlador, simplemente lo llama.

No hace ninguna diferencia para la capa de la interfaz de usuario si el "controlador" envía una función (para ser manejada por el middleware) o si ejecuta una llamada asíncrona y _luego_ envía una acción simple --- la interfaz de usuario es completamente agnóstica (o al menos, _puede_ ser agnóstico)

Una gran parte de su "aplicación" está en estos "controladores", ya sea que esté usando thunks o no. En una aplicación típica de reacción/redux, estos "controladores" suelen ser creadores de acciones de algún tipo. Podría escribir todas sus cosas asincrónicas como thunks y enviarlas. O bien, podría escribir todas sus cosas asincrónicas como funciones que aceptan dispatch como argumento. Desde la perspectiva del componente, es someHandler(dispatch) OR dispatch(someHandler()) , o en el caso de creadores de acciones vinculadas transmitidos desde arriba, es solo someHandler() en ambos casos. Podría crear una versión de bindActionCreators que ocultaría por completo esta diferencia de la capa de la interfaz de usuario.

Si me das una aplicación de reacción/redux escrita con creadores de acciones que usan redux-thunk, podría cambiar por completo redux-thunk y usar un enfoque sin middleware sin cambiar _fundamentalmente_ ninguna de las capas de la interfaz de usuario. (nota: estoy pasando por alto dónde/cómo inyecta getState , pero _creo_ que es un detalle menor aquí).

Por lo tanto, tengo problemas para aceptar que la distinción entre "interior" y "exterior" es "nivel de aplicación" o "nivel de interfaz de usuario".

Agradezco la discusión, y espero no parecer negativo.

Todos 69 comentarios

:+1:

  1. Estado del componente local frente al estado global
  2. Acción manejada por múltiples reductores vs. relación acción-reductor 1 a 1
  3. Manejo de cadenas de acción (especialmente las asíncronas), cuando la segunda acción debe activarse justo después de que finalice la primera.
  4. Técnicas de optimización para evitar reinicios innecesarios (acciones de dosificación, reselección, etc.).

:+1:

Acabo de ver los primeros 16 episodios de la serie y creo que son un excelente recurso que probablemente usaremos para la capacitación interna en la empresa para la que trabajo. Sin embargo, el hecho de que solo haya usado objetos planos y congelados para su árbol de estado, y nunca use o se refiera a bibliotecas inmutables como

Sería genial saber tu opinión sobre esto.

Lanzar Immutable a la mezcla confundiría a los principiantes que necesitarían aprender a diferenciar entre Redux e Immutable API, puede asumir que se requiere Immutable, etc. ¡Sin embargo, es una buena idea para un par de lecciones avanzadas!

Lanzar Immutable a la mezcla confundiría a los principiantes que necesitarían aprender a diferenciar entre Redux e Immutable API, puede asumir que se requiere Immutable, etc. ¡Sin embargo, es una buena idea para un par de lecciones avanzadas!

Está bien, tiene sentido. Es bueno saber lo que piensas detrás de esta decisión :-).

Lo que dijo @smashercosmo :+1:

Examen de la unidad. TDD.

Lo que dijo @cateland :+1:

Debo decir que estoy muy impresionado por su conjunto de habilidades, pudiendo crear excelentes bibliotecas js con documentación extensa y tutoriales concisos de esta manera.

Después de ver todos los videos, tengo un montón de comentarios sobre los videos específicos que enviaré por correo. Sin embargo, la conclusión es que esto es mucho más que una introducción a Redux. Cubre las prácticas de código y la arquitectura de componentes y más. Es realmente impresionante y muy pedagógico. Sin embargo, creo que los videos se pueden dividir en tres grupos. Redux básico, redux entre bastidores y redux con reaccionar.

Para los próximos videos, me gustaría ver menos conceptos específicos de reacción y más sobre acciones y pruebas asincrónicas.

Extraordinariamente bien hecho, ¡sigue así! :)

En el video 21, observa que el componente TodoApp ya no necesita ser una clase, puede ser una función. Sería genial si pudiera explicar cómo se dio cuenta de esto: ¿por qué es un candidato adecuado para ser un componente funcional y qué beneficio brinda?

Esto es tan bueno.

El artículo 3 en la lista de @smashercosmo es algo que también me gustaría saber.

lo que dijo @wpannell ! Pruebas unitarias/TDD!

También me encantaría ver videos sobre los temas tratados en los documentos avanzados.

¿Qué le interesa específicamente con respecto a las pruebas unitarias?
Las lecciones 5, 11, 12 dan una idea de cómo probar unitariamente los reductores.

...buena pregunta. ¿Cambiaría mucho el proceso cuando son pruebas de moca?

Realmente no. Pero supongo que es un buen tema para una serie de lecciones avanzadas. Reductores de pruebas unitarias, creadores de acciones, componentes, etc.

En primer lugar, excelentes videos. Ya entiendo redux pero fue refrescante.
Si está creando videos más avanzados, ¿puedo sugerir acciones asincrónicas/middleware?
No crea que las pruebas unitarias realmente necesitan cobertura. ¿Puede simplemente llamar a sus funciones reductoras y afirmarlas?

Sí, supongo que en realidad no es mucho más que envolver los expect en pruebas de moca. :Pulgares hacia arriba:

¡Afortunadamente todo es tan simple!

Inmutabilidad con hash de ID de objeto (por ejemplo, [post._id]: {...post} ).

Me encuentro confiando demasiado en una función reduce para tomar una matriz de entidades API y producir un hash de ID con ella. Sé que normalizr se encargará de algo de esto, pero me gustaría videos similares a los videos de EggheadIO donde nos lleva del punto A al B. No es solo una cosa basada en Redux, sino que está muy entrelazada.

@raquelxmoss

En el video 21, observa que el componente TodoApp ya no necesita ser una clase, puede ser una función. Sería genial si pudiera explicar cómo se dio cuenta de esto: ¿por qué es un candidato adecuado para ser un componente funcional y qué beneficio brinda?

Eso fue en realidad una planificación de lecciones descuidada de mi parte. No me di cuenta hasta demasiado tarde de que podría haberlo convertido en un componente funcional desde el principio. El beneficio de usar funciones sobre clases es la simplicidad, así que hazlo cada vez que puedas. Básicamente, si no necesita ganchos de ciclo de vida como componentDidMount o estado, use componentes funcionales.

Encontraría una lección sobre cómo podemos dividir estas piezas de código en una estructura de directorio real para ser útil. Sé que mientras todo esté allí, probablemente funcionará, pero tal vez las convenciones recomendadas para nombrar carpetas (componente / contenedor / tienda / reductor, etc.), qué tipo de archivos van en qué carpeta, y así sucesivamente sería bueno.

También me gustaría una composición reductora avanzada.

Reutilizar componentes complejos (que se componen de un reductor o reductores múltiples, un conjunto de acciones, creadores de acciones, tal vez accediendo a alguna API del lado del servidor, varios componentes de React, como redux-form, pero más específicos de la aplicación real). Esto también incluye organizar la estructura de directorio modular.

Lo vi todo, muy bueno! Aprecié el uso de la sintaxis ES6/7 ( Object.assign -like), los componentes de la función React 0.14 y evitar las cosas inmutables.

Tal vez un video que explique la arquitectura de código recomendada.

¿Y actualizar el documento para usar sintaxis ES6/7? (¿Son las relaciones públicas bienvenidas en esa dirección?)

Pruebas unitarias, creación de API Middleware, OAuth/algún tipo de autenticación de usuario con Redux, uso de Immutable con redux (cómo configurarlo, mejores prácticas, etc.)

Esta serie sirve como una excelente introducción a Redux, el estado de un solo átomo y las filosofías relacionadas. Pensé que hiciste un buen trabajo al enfocarte en los principios básicos mientras evitabas inducir una sobrecarga cognitiva. El entorno en el que trabajó también es fácilmente replicable, lo que hace que la parte práctica sea aún más accesible.

@gaearon ¿Qué opinas de estructurar acciones en los videos de ejemplo como { type: string, payload: Object } estándar aspirante desde el principio? Estoy hablando del ejemplo de la lista de contadores, donde la carga útil se coloca en el objeto de acción en sí; { type: string, index: number } . Esto me parece un anti-patrón.

¿Qué piensas de la estructuración de acciones en los videos de ejemplo como un aspirante a estándar { type: string, payload: Object } desde el principio? Estoy hablando del ejemplo de la lista de contadores, donde la carga útil se coloca en el objeto de acción en sí; { tipo: cadena, índice: número }. Esto me parece un anti-patrón.

No es un anti-patrón de ninguna manera. Es un objeto de acción normal. FSA está bien pero es una _convención_. Nada en Redux en sí mismo depende o se beneficia de esta convención, por lo que no queremos aplicarla.

La gente solía pensar todo tipo de cosas mágicas sobre payload , source en la documentación original de Flux. Copiaron ciegamente estas cosas sin entender por qué existen y evaluaron cuidadosamente si las necesitaban. Más tarde se quejaron de que Flux era complejo y detallado, cuando en realidad en muchos casos ellos mismos copiaron las partes detalladas (pero no esenciales).

En estas lecciones solo enseño las partes esenciales de Redux. Tenga en cuenta que no introduzco constantes, porque las personas se concentran demasiado en ellas y pasan por alto que en realidad no importan. Es más probable que comprenda los beneficios de las constantes después de cometer algunos errores tipográficos en las cadenas, en lugar de incluirlos en los videos tutoriales desde el principio. Creo que lo mismo ocurre con otras convenciones como la FSA: por supuesto, utilícela si lo encuentra conveniente, pero no la predicaré si las lecciones no lo exigen.

@gaearon OK, estoy contigo entonces, con la esperanza de que aquellos que se acostumbraron al enfoque simple no estructurado no hagan que las aplicaciones más grandes sean inmanejables al no aplicar ninguna convención.

@sompylasar

Creo que los ejemplos muestran las convenciones mejor que los tutoriales en video. Los ejemplos son la tierra obstinada de "así es como voy a estructurar un código en torno a esos principios", y los videos son sobre esos principios en sí mismos. Es por eso que verá diferentes convenciones en diferentes ejemplos, y antes de comenzar un proyecto, la mayoría de las personas revisan diferentes ejemplos para probar las diferentes formas de hacerlo.

Además, no hay absolutamente nada desestructurado en no seguir la FSA. { type: 'STUFF', id: 1 } no es inherentemente peor que { type: 'STUFF', payload: { id: 1 } } . Es solo una cuestión de gusto y (a veces) convención de herramientas. Mantener los objetos de acción payload menos no hace que sea más difícil trabajar con ellos.

Tenemos un puñado de lecciones de prueba de unidad redux que saldrán pronto en egghead 😄

Retrasamos CUALQUIER lección de Redux durante un tiempo para que Dan tuviera el primer crack. Vale la pena la espera, y algo más.

"Crear una aplicación con Idiomatic Redux" sería un maravilloso curso avanzado 👍

@joelhooks, ¡ ambos suenan increíbles!

Me gustaría verte configurar un proyecto usando webpack y recarga en caliente en lugar de usar jsbin. Lleva esto al mundo real. Sé que no es específico de redux, pero creo que encajaría bien y eres el hombre adecuado para enseñar esto :)

@kevinrenskers que no es una serie de videos, pero si usted se siente como la disección de algo, no son unos muy grandes boilerplates ejemplo, puede hacer referencia!

Aquellos que han pedido una estructura de proyecto para el ejemplo de Dan y la configuración de Webpack.

Consulte esto https://github.com/urbanvikingr/todo.

Me comprometí a actualizar Redux con React doc para alinearme con el código de Dan de los videos. Estará listo dentro de las próximas dos semanas - mi proyecto de vacaciones :) - estad atentos.

Mi lista de deseos para los videos de Egghead.io:
prueba de acción / reductor con Jasmine
profundizar en el middleware (thunk/promises)

Los screencasts son una introducción muy útil a Redux. Lo que me gustaría escuchar es la forma Redux de hacer enrutamiento y renderizado del lado del servidor

@grigio Puede interesarle esta discusión https://github.com/rackt/redux/issues/1145 sobre enrutamiento

@urbanvikingr gracias, suscrito. La encuesta parece cerrada, pero hubiera votado #1168

Las lecciones son bastante buenas, pero distrae que cuando dices "almacenar", suene como "tarea".

Todo el mundo aquí se ha dado cuenta y se ha distraído por ello. Son demasiado políticamente correctos para mencionarlo. Así que sí, decidí ser _ese_ tipo, en caso de que nadie más lo hiciera :)

Con el tiempo mejoraré hablando inglés. Por ahora esto es lo mejor que puedo hacer ;-)

@gaearon Has hecho un muy buen trabajo al explicar Redux. Felicitaciones a usted y sus logros de código abierto.

Increíble conjunto de lecciones. Me gustó especialmente cómo reimplementó cada una de las funciones principales de Redux desde cero en una forma de "leer la fuente". Apoyar a alguien más que quedó impresionado por lo claros que son los tutoriales y toda la documentación para Redux. Hasta ahora, como alguien que se puso al día con dos años de avances en la interfaz, los conceptos han sido difíciles de entender, pero los documentos han sido increíblemente útiles para hacerlo. ¡Sigan así, y gracias!

(Además, no escuches a @jugimaster , no todos se distrajeron con tu acento y fueron "demasiado políticamente correctos para mencionarlo", o incluso les importó que tuvieras acento).

@ianstormtaylor
No es un acento, por cierto :)

A mí tampoco me "importaba", ¡pero seguro que estaba distraído!

Pero, por otro lado, como alguien que ha estudiado seis idiomas extranjeros, siempre me he preocupado por hablar correctamente un idioma y, por ese motivo, agradezco personalmente que alguien me señale mis errores.

Hola @gaearon ,

Me encantó tu curso. ¡Buen trabajo! Fue muy útil.

Agregué tres lecciones en video de prueba de Redux a mi curso reciente de Egghead:
https://egghead.io/series/react-testing-cookbook

¡Espero que sean complementarios a todo el increíble trabajo que ha realizado!

Curso sólido!

¡Mejora no solo el conocimiento de Redux sino también el conocimiento de las prácticas modernas en general! Sigue haciendo cosas tan buenas :+1: :tada:

oye, me acabo de dar cuenta de que no hay un enlace/referencia al código en los videos. Tal vez obvio, y tal vez, los usuarios lo suficientemente simples podrían simplemente copiar los videos; pero creo que mucha gente podría beneficiarse de un repositorio con el código exacto en los videos, ¿por qué no?

Los fragmentos de código para cada lección están disponibles para los suscriptores de Egghead. :-)
Los videos son gratuitos, pero la plataforma debe ganar dinero para poder invertir en más cursos, enviar equipos a los instructores, alojar los videos, mejorar el sitio web, etc.

Dicho esto, tenemos una carpeta examples/todos que coincide bastante con el curso.

... genial, me lo estoy perdiendo entonces? Buscando enlace(s)...

@gaearon se disculpa, solo

Por cierto, algunas personas se quejaron de que las transcripciones son inexactas.
Envíe relaciones públicas para solucionarlos: https://github.com/eggheadio/egghead-redux-transcripts

@gaearon Decidí usar redux y luego encontré los videos de redux en egghead. Los videos realmente me ayudaron a comenzar a aprender redux. En el futuro, sería genial ver más ejemplos del mundo real.

Entonces, mi sugerencia para el entrenamiento de video redux en el futuro sería una composición avanzada, una inmersión más profunda en la refactorización y, definitivamente, cómo usar la reselección. Parece tener una intuición sobre cuándo refactorizar. Entonces, dado que la programación funcional está tan íntimamente ligada a redux, sería realmente útil obtener algunos consejos sobre cuándo refactorizar y cómo identificar una función que hace una cosa bien.

En la aplicación que estoy creando, tengo varias colecciones de datos grandes y necesito ponerlas en tablas y hacer cosas como ordenar y paginar los datos. Tengo dificultades para decidir cuándo usar los selectores y cuándo usar las acciones de creación. Actualmente tengo la acción USERS_SORT_TABLE y la acción SORT_TABLE porque tengo la tienda de usuarios "heredando" algún estado de la tabla. Hice esto porque no quería que la tienda de usuarios ordenara una acción SORT_TABLE en una tienda de tareas pendientes.

Sé que mi solución no es SECA, pero no estoy seguro de cómo hacerlo correctamente. Tal como está, tendré que crear una acción "SOMETHING"_SORT_TABLE para cada tienda en la que quiera completar una tabla, lo cual sé que está mal, pero no sé cómo hacerlo. Otro efecto secundario es que el nombre de mi acción se vuelve enorme porque tengo que separar las diferentes tiendas anteponiendo su nombre a la acción. Esto no puede estar bien.

Aquí hay un código de ejemplo:

/* actions.js */
// ...
export const USER_MOVE_COLUMN = 'USER_MOVE_COLUMN'

export function userMoveColumn (columnIndex, moveToIndex) {
  return {
    type: USER_MOVE_COLUMN,
    columnIndex,
    moveToIndex
  }
}

export const DATA_TABLE_MOVE_COLUMN = 'DATA_TABLE_MOVE_COLUMN'
// ...

/* reducers.js */
// ...
export default function user (state=userInitialState, action) {
  switch (action.type) {
    // ...
    case USER_MOVE_COLUMN:
      return dataTable(state, assign(
        action,
        {type: DATA_TABLE_MOVE_COLUMN}
      ))
    // ...
    default:
      return state
  }
}
// ...
export default function dataTable (
  state=dataTableInitialState,
  action,
  key='dataTable')
{
  switch (action.type) {
    // ...
    case DATA_TABLE_MOVE_COLUMN:
      return {
        ...state,
        [key]: {
          ...state[key],
          columns: move(
            state[key].columns, action.columnIndex, action.moveToIndex
          )
        }
      }
    // ...
    default:
      return state
  }
}

Entonces puede ver que creé una dependencia entre la tabla y la tienda "modelo" que no debería tener (la tienda modelo debe usar la clave de colección para su matriz de objetos). Y la tabla de datos manipula el estado del reductor "principal", lo que no debería hacer. Se me ocurrió que necesito usar un selector allí, pero en el momento en que escribí esto, estaba tratando de evitar duplicar una tienda grande solo para cambiar lo que estaba visible en la interfaz de usuario.

Así que actualmente estoy luchando por aprender a reseleccionar para resolver algunos de estos problemas y técnicas de refactorización para resolver algunos de los otros. El primer curso de Redux fue suficiente para hacerme peligroso. Ahora me gustaría aprender a hacerlo bien. :)

Espero que haya sido útil y no demasiado detallado. Tratando de dar una retroalimentación clara y honesta.

Para cualquier persona amable que pueda ayudarme, ya encontré /examples/real-world/reducers de otro de los comentarios de Dan y actualmente estoy reelaborando algunos de los problemas que describí anteriormente. No quería que perdieras el tiempo tratando de ayudar si hubiera encontrado una solución.

Gracias por la advertencia :)

integrar redux-devtools dentro de mi proyecto fue un gran dolor para mí... hubiera apreciado (y aún lo haré) una serie intelectual que describa lo que hay y cómo/cuándo usarlo. Leí el PR donde describe cuándo usar qué ... pero me confundí tanto que hay tantas cosas por ahí hmr, transform 3, redux hot reloader es diferente de react hot reloader, etc.

Para cualquier otra persona que tenga problemas con algunos de los problemas que describí anteriormente, creé un proyecto que le permite eliminar la mayoría, si no todos, los repetitivos en Redux, así como las acciones del espacio de nombres. mira eso aqui

@granteagon ¿No es este par de reductores a creadores de acción? Uno de los principios básicos de diseño en Redux es que los _reductores deben desacoplarse de las acciones_. Cualquier reductor puede escuchar cualquier acción. No hay mapeo 1:1 entre ellos. De lo contrario, es difícil que diferentes partes del árbol de estados cambien de forma independiente su estado en respuesta a las mismas acciones.

He notado que la mayoría de las personas que crean envoltorios o abstracciones además de la creación de acciones/reductores tienden a asumir que siempre estarán directamente acoplados. Es cierto que, en mi aplicación, hasta ahora _la mayoría_ de mis acciones tienen exactamente una porción correspondiente de lógica de manejo, pero definitivamente ha habido varias en las que es necesario actualizar varias partes del árbol.

@gaearon @markerikson Hace par de reductores a creadores de acción. Sin embargo, el 90% de las veces, está bien o incluso se desea. El otro 10% del tiempo aún puede usar un enfoque codificado a mano. Sin embargo, pensaré en lo que has dicho y lo consideraré para el desarrollo futuro.

@granteagon @gaearon

Habiendo usado una abstracción local que es similar a reduxr, diría que no hay ningún acoplamiento adicional aquí. Nada fuerza el mapeo 1:1 entre acciones y reductores. Todavía puedes tener dos reductores en dos rebanadas diferentes escuchando la misma acción:

const counterReducersA = {
  // this counter increments by 1 each time
  increment: (state, action) => state + 1
}

const counterReducersB = {
  // this counter increments by 2 each time
  increment: (state, action) => state + 2
}

const counterA = reduxr(counterReducersA, 0);
const counterB = reduxr(counterReducersB, 0);

const rootReducer = combineReducers({
  counterA: counterA.reducer,
  counterB: counterB.reducer
});

store.dispatch(counterA.action.increment());  // increments both counters

Por supuesto, si tiene más de una función "reductora" con el mismo nombre (es decir, respondiendo a la misma acción), implícitamente ambas deben "esperar" que la carga útil de la acción tenga una forma determinada, lo cual es completamente análogo. a tener dos reductores en vanilla redux, ambos manejando la misma constante type --- ambos tienen que esperar la misma forma de acción.

¿Quizás entendí mal lo que quieres decir con @gaearon ?

Creo que mostrar un flujo asíncrono sin middleware antes de mostrar la implementación del procesador podría ser útil.

Algo relacionado, pero si bien la documentación ha sido increíblemente útil, esta declaración en la página de flujos asíncronos realmente me desconcertó en retrospectiva: "Sin middleware, la tienda Redux solo admite el flujo de datos síncronos".

@bataile : eso es porque es verdad :) Sin middleware, cualquier asincronía tiene que ocurrir completamente fuera de Redux (por lo tanto, muy probablemente en su capa de interfaz de usuario, como los componentes de React). Cada vez que llame a store.dispatch , la acción irá directamente a la función de reducción, no pase Go, no cobre $200, no haga paradas en el camino para las llamadas AJAX.

Los potenciadores de la tienda le permiten completar funciones como dispatch con su propia versión, por lo que applyMiddleware proporciona la abstracción de una "canalización de middleware" antes de que algo llegue a la función dispatch la tienda real . Básicamente, eso proporciona una escapatoria en la que puede saltar y hacer cualquier cosa asíncrona que desee, _dentro_ del flujo estándar de Redux.

Entonces, sin el middleware, todavía podrías hacer cosas asincrónicas... todo tendría que suceder completamente separado de cualquier cosa realmente relacionada con Redux.

eso es porque es verdad :)

No dije que fuera falso, dije que me desconcertó :)

Solo quería hacer algo como lo siguiente, lo que parecía implicar que no podía:

const mapDispatchToProps = (dispatch) => ({
  onclick(searchTerm) {
    dispatch(actions.requestOrders(searchTerm));

    return fetch('http://localhost:49984/Order/Search?search=' + searchTerm)
      .then(response => response.json()).then(response => {
        dispatch(actions.receiveOrders(searchTerm, response));
      })
      .catch((err) => {
        dispatch(actions.receiveOrdersError('An error occurred during search: ' + err.message));
      });
  },
});

Me doy cuenta de que esto podría ponerse feo fácilmente, pero conceptualmente creo que es útil verlo. O al menos lo fue en mi caso.

Acepto que "Sin middleware, la tienda Redux solo admite el flujo de datos síncrono". es engañosa.

Técnicamente, si desea establecer una distinción entre "adentro" y "afuera", la declaración podría ser cierta, pero si lleva a las personas a creer que la única manera de hacer async es agregando middleware, tal vez podamos reformularlo o dar más detalles. eso.

Sí, la diferencia es que el comportamiento asíncrono técnicamente ocurre más a nivel de componente, en lugar de "dentro" de dispatch . Una distinción menor, pero válida.

No creo que nadie esté argumentando que la declaración no es técnicamente correcta.

@markerikson Solo tiene curiosidad si tiene algún ejemplo concreto en el que la distinción entre el interior y el exterior sea importante.

Un ejemplo podría ser si desea que el middleware en la cadena _antes_ de su middleware asíncrono pueda ver su procesador enviado (o promesa, etc.). No estoy seguro de qué haría ese middleware, pero supongo que es factible querer tal cosa.

Mmm... no estoy seguro de los ejemplos "concretos" específicamente. En general, la distinción entre "afuera" e "adentro" es una cuestión de si sucede _antes_ de llamar a dispatch la primera vez, o _después_. Si está "afuera" y "antes", entonces toda su asincronía y lógica están más ligadas a la capa de vista, ya sea React, Angular u otra cosa. Si es "dentro" y "después", entonces su asincronía y lógica están en el nivel de la tienda y _no_ están vinculadas a la capa de visualización.

En realidad, esto es gran parte del punto que estaba tratando de hacer en una discusión de Reddit hoy: https://www.reddit.com/r/reactjs/comments/4spbip/has_anyone_inserted_a_controllerpresenter_layer/ .

La pregunta de "¿qué acciones despacho y cuándo las despacho?" es una parte central de su lógica comercial, y la otra mitad es "¿cómo actualizo mi estado en respuesta a esas acciones?". Si la gestión de acciones está en thunks y sagas y demás, entonces realmente no importa si ese código fue iniciado por un componente React, un controlador angular, un controlador de clic jQuery, una instancia de componente Vue o algo más. Su lógica central está fuera de la capa de la interfaz de usuario, y la capa de la interfaz de usuario es realmente responsable de extraer los datos que necesita de la tienda, mostrarlos y convertir las entradas del usuario en una llamada de función lógica de la aplicación.

Entonces, en ese sentido, diría que la cuestión de "adentro" versus "afuera" sí importa, porque es una distinción conceptual entre si su lógica vive en el nivel de la aplicación o en el nivel de la interfaz de usuario.

@markerikson gracias por

Nota: Por conveniencia, voy a usar thunk para representar un enfoque de middleware arbitrario para asíncrono, ya sea redux-thunk o redux-promise, o lo que sea.

Su capa de interfaz de usuario solo conecta las interacciones del usuario con los controladores. Cuando alguien hace clic en un botón, su interfaz de usuario está configurada para llamar a _some_ handler. A menudo, el componente recibe estos controladores como accesorios, tal vez un creador de acciones vinculadas, por ejemplo. La interfaz de usuario no sabe lo que sucede cuando llama a un controlador, simplemente lo llama.

No hace ninguna diferencia para la capa de la interfaz de usuario si el "controlador" envía una función (para ser manejada por el middleware) o si ejecuta una llamada asíncrona y _luego_ envía una acción simple --- la interfaz de usuario es completamente agnóstica (o al menos, _puede_ ser agnóstico)

Una gran parte de su "aplicación" está en estos "controladores", ya sea que esté usando thunks o no. En una aplicación típica de reacción/redux, estos "controladores" suelen ser creadores de acciones de algún tipo. Podría escribir todas sus cosas asincrónicas como thunks y enviarlas. O bien, podría escribir todas sus cosas asincrónicas como funciones que aceptan dispatch como argumento. Desde la perspectiva del componente, es someHandler(dispatch) OR dispatch(someHandler()) , o en el caso de creadores de acciones vinculadas transmitidos desde arriba, es solo someHandler() en ambos casos. Podría crear una versión de bindActionCreators que ocultaría por completo esta diferencia de la capa de la interfaz de usuario.

Si me das una aplicación de reacción/redux escrita con creadores de acciones que usan redux-thunk, podría cambiar por completo redux-thunk y usar un enfoque sin middleware sin cambiar _fundamentalmente_ ninguna de las capas de la interfaz de usuario. (nota: estoy pasando por alto dónde/cómo inyecta getState , pero _creo_ que es un detalle menor aquí).

Por lo tanto, tengo problemas para aceptar que la distinción entre "interior" y "exterior" es "nivel de aplicación" o "nivel de interfaz de usuario".

Agradezco la discusión, y espero no parecer negativo.

Este curso es genial. Cerrando esto para que las personas puedan dirigir sus comentarios al repositorio de notas de la comunidad para el curso: https://github.com/tayiorbeii/egghead.io_redux_course_notes

Además, ¡asegúrate de ver la próxima serie que Dan preparó! https://egghead.io/courses/building-react-applications-with-idiomatic-redux

¿Fue útil esta página
0 / 5 - 0 calificaciones