Design of Redux middleware with focus on return values

I just finished learning about redux middleware, and it seems really useful. However, I have a question regarding the return values of middleware.

I understand that some middleware return values (such as redux-promise), while others like logging do not - they simply return the result of next(action).

My concern is what happens if I want to use two middleware that both return values - won't they interfere with each other and only provide the output of the outermost middleware?

express/connect middleware deals with this by allowing middleware to write their "results" to the req and res objects, but what is the solution in the context of redux?

EDIT

Let me give you a specific example of my dilemma:

I am using two pieces of middleware:

  1. A middleware that delays all dispatched actions by 3 seconds. This middleware returns a function that can be used to cancel the dispatch.
  2. Another middleware that simply returns the number 5 for a specific purpose.

Depending on how I chain these two middleware components, the output of my dispatch(action) will either be the cancellation function or the number 5. But is there a way to obtain both of these results simultaneously?

Answer №1

Below is a fully executable script that showcases the issue I am attempting (and struggling) to articulate. It also presents a potential resolution (utilizing a middleware wrapper). I'm open to discovering more refined solutions if they exist...

const { createStore, applyMiddleware } = require("redux");
let dispatchResult;

// The genesis function creates an object to pass through the middleware chain, gathering results along the way
const genesis = _store => next => action => {
    next(action);
    return {};
};

// Middleware wrapper function encapsulates the logic of extracting and appending results 
const wrapper = (key, mware) => store => next => action => {

    let extractedResult;
    function modifiedNext(action) {
        extractedResult = next(action);
        return extractedResult;
    }

    let newResult = mware(store)(modifiedNext)(action);
    extractedResult[key] = newResult;
    return extractedResult;
};

// Logging middleware for standard logging
const logger = store => next => action => {
    let result = next(action);
    console.log(`The value is: ${store.getState()}.`);
    return result;
};

// Middleware function that returns a number
const gimme = val => _store => next => action => {
    next(action);
    return val;
};

// Reducer function for a simple counter incrementer
function reducer(state = 0, action) {
    if (action.type === "INC")
        return state + 1;
    return state;
}

// Running without the wrapper first:
dispatchResult = createStore(reducer, applyMiddleware(
    gimme(4),
    logger,
    gimme(5)
)).dispatch({ type: "INC" });

// Output will be only 4 (result of outermost middleware)
// The result from gimme(5) middleware is lost
console.log(dispatchResult);

// Including the middleware wrapper and genesis middleware
dispatchResult = createStore(reducer, applyMiddleware(
    wrapper("g4", gimme(4)),
    logger,
    wrapper("g5", gimme(5)),
    genesis
)).dispatch({ type: "INC" });

// Now we get { g4: 4, g5: 5 }
// Both middleware results are preserved
console.log(dispatchResult);

Answer №2

Learn more about the concept of applyMiddleware by checking out the documentation. It emphasizes how middlewares should be designed to seamlessly integrate into a chain of actions, allowing them to function independently without being affected by what comes before or after:

One of the main benefits of middleware is its composability. Different middleware can be combined together with each one not needing any prior knowledge of the others in the sequence.

The documentation provides thorough insight into the parameters required for middleware and the expected output returned by it.

https://redux.js.org/api/applyMiddleware

Answer №3

The true essence of Middleware lies in its role as a conduit for processing and executing actions. The focus is on the flow of data rather than individual return values.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

In AngularJS, I've created a collection of checkboxes with a submit button ready to go

One of my goals is to make the cancel button available only when at least one job is selected. Below is my HTML View <table> <tr ng-repeat="x in jobs" ng-class-odd="'odd'" ng-class-even="'even'"> <td style="widt ...

Stopping an AngularJS timeout from running

I have a multi-platform app created using AngularJS and Onsen/Monaca UI. In my app, I have a feature that detects button clicks and after a certain number of clicks, the user is directed to a confirmation screen. However, if the user takes too long to mak ...

Combining React with a jQuery plugin

Utilizing the jQuery nestable plugin in my React App has been a lifesaver for meeting my business needs. Despite being aware of the potential complications that arise from mixing jQuery with React, I couldn't find the exact functionality I required in ...

Create a nested array of subcategories within an array object

Currently, I am working on integrating Django Rest and Angular. The JSON array received from the server includes category and subcategory values. My goal is to organize the data such that each category has its related subcategories stored as an array withi ...

Retrieving QueryString from Request or JavaScript

On my aspx page, I am dealing with a query string - www.mysite.com/enter.aspx?dest=#. After clicking "enter," the page navigates to main.aspx. I am looking for a way to extract this "?dest=#" from the query string in main.aspx using either request.querystr ...

Using jQuery, retrieve the "select" element within a specific row of a

I am working on a table row that has the following HTML structure: When the user interacts with the "Name" field, I trigger the "select" event and pass it to the nameDropChanged function. Once I have a reference to this select element, I need to change th ...

Is there a different method I can utilize to create a conditional statement for assigning a value in JavaScript?

I have this code snippet that seems a bit unclear to me: if (!app.config.admin.examStatusId) { app.config.admin.examStatusId = exam.examStatus.dataPlus[0].id; } Do you have any suggestions on how I could rewrite this more clearly without using an if s ...

Refreshing a Nested Component Within a Parent Component in React

Currently, I am in the final stage of a small project where a Higher Order Component (HOC) is being utilized to display a basic Tinder-like application. The internal component is a class-based component containing its own fetch() call that presents user d ...

Adding graphs dynamically to Dygraphs allows for real-time updates and interactive data

I recently started using Dygraphs for one of my projects and I am still learning how to work with it. After reading through the documentation and looking at a few examples, I noticed that the constructor for Dygraphs requires a div element where the graph ...

Implementing automatic redirection upon clicking using React without the need for manual clicking

I'm experiencing an issue where the page seems to automatically navigate to another page without clicking on the div. Can anyone explain why this is happening? Here's the code snippet for reference: import React, { Component } from "react&q ...

What is the proper way to type a collection and put it into action?

I am looking for a way to create an object that mimics a set. Specifically, I want the transaction id to act as a key and the transaction details as the value. To achieve this, I created the following: type TransactionDetail = { [key: TransactionId]: Tra ...

Error: The property 'create' of undefined cannot be read (Material UI/enzyme)

When I mount a component, I encounter an error that does not occur when using shallow rendering. The specific error is: TypeError: Cannot read property 'create' of undefined at stylesOrCreator (node_modules/@material-ui/core/CircularProgress/C ...

Tips for incorporating confidence intervals into a line graph using (React) ApexCharts

How can I utilize React-ApexCharts to produce a mean line with a shaded region to visually represent the uncertainty of an estimate, such as quantiles or confidence intervals? I am looking to achieve a result similar to: ...

`There is a delay in rendering the background image on Chrome`

Once I apply a class to my button element using JavaScript, the background image (.gif) that is supposed to display afterwards takes an unusually long time to render. The button serves as a form submission. Upon being clicked, a class of "clicked" is dyna ...

AngularJS Currency Converter - Converting Currencies with Ease

I have a question regarding the most efficient way to handle currency conversion on a webpage. Currently, I have multiple input fields displaying different currencies. When a user clicks on the currency conversion button, a modal popup appears. After the ...

What is the best way to remove text from a box when a user clicks on it?

After successfully placing G in the selected box upon clicking it, I now want to work on removing it when clicked again. I'm encountering an issue with my current code - can anyone help me identify what's wrong and suggest a solution? Below is ...

The Viadeo Social Toolbox seems to be encountering technical difficulties at the moment

I attempted to utilize a Viadeo Social Toolbox, specifically the Viadeo Share Button, but it seems to be malfunctioning in certain browsers? I came across some outdated viadeo share URLs like this: http://www.viadeo.com/shareit/share/?url=${url}&title ...

Unable to find '/images/img-2.jpg' in the directory 'E:React eact-demosrc'

My code is giving me trouble when trying to add an image background-image: url('/images/img-2.jpg'); An error occurred during compilation. ./src/App.css (./node_modules/css-loader/dist/cjs.js??ref--5-oneOf-4-1!./node_modules/postcss-loader/src?? ...

Choose all checkboxes across the entire webpage

Given the code below: <input type="checkbox" name="categories[9507]"> Is there a way to write a JavaScript command that can automatically select all checkboxes with similar naming structures on the entire page? The only difference in the names is t ...

Exploring the use of jQuery/JS for parsing and working with JSON

Hi everyone, I need some assistance with displaying data from an array created by a PHP file using JS/jQuery. Currently, I am working on implementing a points system for ZetaBoards which you can check out here. The points will be shown below the user' ...