Files
freeCodeCamp/curriculum/challenges/espanol/03-front-end-development-libraries/redux/use-middleware-to-handle-asynchronous-actions.md
Shaun Hamilton c2a11ad00d feat: add 'back/front end' in curriculum (#42596)
* chore: rename APIs and Microservices to include "Backend" (#42515)

* fix typo

* fix typo

* undo change

* Corrected grammar mistake

Corrected a grammar mistake by removing a comma.

* change APIs and Microservices cert title

* update title

* Change APIs and Microservices certi title

* Update translations.json

* update title

* feat(curriculum): rename apis and microservices cert

* rename folder structure

* rename certificate

* rename learn Markdown

* apis-and-microservices -> back-end-development-and-apis

* update backend meta

* update i18n langs and cypress test

Co-authored-by: Shaun Hamilton <shauhami020@gmail.com>

* fix: add development to front-end libraries (#42512)

* fix: added-the-word-Development-to-front-end-libraries

* fix/added-the-word-Development-to-front-end-libraries

* fix/added-word-development-to-front-end-libraries-in-other-related-files

* fix/added-the-word-Development-to-front-end-and-all-related-files

* fix/removed-typos-from-last-commit-in-index.md

* fix/reverted-changes-that-i-made-to-dependecies

* fix/removed xvfg

* fix/reverted changes that i made to package.json

* remove unwanted changes

* front-end-development-libraries changes

* rename backend certSlug and README

* update i18n folder names and keys

* test: add legacy path redirect tests

This uses serve.json from the client-config repo, since we currently use
that in production

* fix: create public dir before moving serve.json

* fix: add missing script

* refactor: collect redirect tests

* test: convert to cy.location for stricter tests

* rename certificate folder to 00-certificates

* change crowdin config to recognise new certificates location

* allow translations to be used

Co-authored-by: Nicholas Carrigan (he/him) <nhcarrigan@gmail.com>

* add forwards slashes to path redirects

* fix cypress path tests again

* plese cypress

* fix: test different challenge

Okay so I literally have no idea why this one particular challenge
fails in Cypress Firefox ONLY. Tom and I paired and spun a full build
instance and confirmed in Firefox the page loads and redirects as
expected. Changing to another bootstrap challenge passes Cypress firefox
locally. Absolutely boggled by this.

AAAAAAAAAAAAAAA

* fix: separate the test

Okay apparently the test does not work unless we separate it into
a different `it` statement.

>:( >:( >:( >:(

Co-authored-by: Sujal Gupta <55016909+heysujal@users.noreply.github.com>
Co-authored-by: Noor Fakhry <65724923+NoorFakhry@users.noreply.github.com>
Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
Co-authored-by: Nicholas Carrigan (he/him) <nhcarrigan@gmail.com>
2021-08-13 21:57:13 -05:00

5.3 KiB

id, title, challengeType, forumTopicId, dashedName
id title challengeType forumTopicId dashedName
5a24c314108439a4d4036156 Usa middleware para manejar acciones asíncronas 6 301451 use-middleware-to-handle-asynchronous-actions

--description--

Hasta ahora hemos evitado hablar de las acciones asíncronas, pero son una parte inevitable del desarrollo web. En algún momento necesitarás llamar a endpoints asíncronos en tu aplicación Redux, así que ¿cómo manejas este tipo de peticiones? Redux proporciona un middleware diseñado específicamente para este propósito, llamado Redux Thunk middleware. Aquí hay una breve descripción de cómo usar esto con Redux.

Para incluir el Redux Thunk middleware, lo pasas como argumento a Redux.applyMiddleware(). Esta declaración se proporciona entonces como un segundo parámetro opcional a la función createStore(). Echa un vistazo al código en la parte inferior del editor para ver esto. Entonces, para crear una acción asíncrona, se devuelve una función en el creador de acción que toma dispatch como argumento. Dentro de esta función, se pueden enviar acciones y realizar peticiones asíncronas.

En este ejemplo, se simula una petición asíncrona con una llamada setTimeout(). Es común enviar una acción antes de iniciar cualquier comportamiento asíncrono para que el estado de tu aplicación sepa que se están solicitando algunos datos (este estado podría mostrar un icono de carga, por ejemplo). Luego, una vez que recibes los datos, envía otra acción que lleva los datos como carga útil junto con la información de que la acción se ha completado.

Recuerda que estás pasando dispatch como parámetro a este creador de acciones especiales. Esto es lo que usarás para enviar tus acciones, simplemente pasas la acción directamente a dispatch y el middleware se encarga del resto.

--instructions--

Escribe ambos envíos en el creador de acción handleAsync(). Envía requestingData() antes del setTimeout() (la llamada a la API simulada). A continuación, después de recibir los datos (fingidos), envía la acción receivedData(), pasando estos datos. Ahora ya sabes cómo manejar las acciones asíncronas en Redux. Todo lo demás sigue comportándose como antes.

--hints--

El creador de acción requestingData debe devolver un objeto de tipo igual al valor de REQUESTING_DATA.

assert(requestingData().type === REQUESTING_DATA);

El creador de acción receivedData debe devolver un objeto de tipo igual al valor de RECEIVED_DATA.

assert(receivedData('data').type === RECEIVED_DATA);

asyncDataReducer debe ser una función.

assert(typeof asyncDataReducer === 'function');

Enviar el creador de acción requestingData debe actualizar la propiedad store state de fetching a true.

assert(
  (function () {
    const initialState = store.getState();
    store.dispatch(requestingData());
    const reqState = store.getState();
    return initialState.fetching === false && reqState.fetching === true;
  })()
);

El envío de handleAsync debe enviar la acción de solicitud de datos y luego enviar la acción de datos recibidos después de un retraso.

assert(
  (function () {
    const noWhiteSpace = __helpers.removeWhiteSpace(handleAsync.toString());
    return (
      noWhiteSpace.includes('dispatch(requestingData())') === true &&
      noWhiteSpace.includes('dispatch(receivedData(data))') === true
    );
  })()
);

--seed--

--seed-contents--

const REQUESTING_DATA = 'REQUESTING_DATA'
const RECEIVED_DATA = 'RECEIVED_DATA'

const requestingData = () => { return {type: REQUESTING_DATA} }
const receivedData = (data) => { return {type: RECEIVED_DATA, users: data.users} }

const handleAsync = () => {
  return function(dispatch) {
    // Dispatch request action here

    setTimeout(function() {
      let data = {
        users: ['Jeff', 'William', 'Alice']
      }
      // Dispatch received data action here

    }, 2500);
  }
};

const defaultState = {
  fetching: false,
  users: []
};

const asyncDataReducer = (state = defaultState, action) => {
  switch(action.type) {
    case REQUESTING_DATA:
      return {
        fetching: true,
        users: []
      }
    case RECEIVED_DATA:
      return {
        fetching: false,
        users: action.users
      }
    default:
      return state;
  }
};

const store = Redux.createStore(
  asyncDataReducer,
  Redux.applyMiddleware(ReduxThunk.default)
);

--solutions--

const REQUESTING_DATA = 'REQUESTING_DATA'
const RECEIVED_DATA = 'RECEIVED_DATA'

const requestingData = () => { return {type: REQUESTING_DATA} }
const receivedData = (data) => { return {type: RECEIVED_DATA, users: data.users} }

const handleAsync = () => {
  return function(dispatch) {
    dispatch(requestingData());
    setTimeout(function() {
      let data = {
        users: ['Jeff', 'William', 'Alice']
      }
      dispatch(receivedData(data));
    }, 2500);
  }
};

const defaultState = {
  fetching: false,
  users: []
};

const asyncDataReducer = (state = defaultState, action) => {
  switch(action.type) {
    case REQUESTING_DATA:
      return {
        fetching: true,
        users: []
      }
    case RECEIVED_DATA:
      return {
        fetching: false,
        users: action.users
      }
    default:
      return state;
  }
};

const store = Redux.createStore(
  asyncDataReducer,
  Redux.applyMiddleware(ReduxThunk.default)
);