Plan the timing of dispatch in the reducer

While solutions like redux thunk exist for dispatching actions asynchronously, I recently encountered a situation like the one below:

import {store} from "./store";

const initialState = {
  todos: []
}
​
function todoApp(state = initialState, action) {    
​  
  if(action.type == "ACTION_A"){
    // 1. do something with state
    // 2. do something with state, and then... schedule a dispatch, for example using setTimeout:
    setTimeout(()=>store.dispatch({type:"ACTION_B", payload:1}), 2000);  
    return state;
  }// check other actions e.g. ACTION_B etc.

  return state;     
}

In this example, ACTION_B is not meant to be dispatched from elsewhere as an async action, but rather is a part of the logic within ACTION_A.

So, how should such situations be handled in redux?

Some recommend using middleware as a solution, however, comments from Mark Erikson (Redux maintainer) on a blog post suggest that it might not be the right approach. He seems to recommend using redux-loop in such cases.

So, what are the correct ways to deal with such situations in redux? Are there other solutions besides redux-loop? And can redux-thunk still be used to resolve this issue?

Answer №1

Here's a great scenario where a thunk would be beneficial:

const actionA = () = ({ dispatch, getState }) => {
   dispatch(actionA1) // execute another action that will alter the state

   setTimeout(()=> {
       const { data } = getState();
       dispatch({type:"ACTION_B", payload: data });
   }, 2000);
}

Alternatively, you could create a custom middleware that schedules the timeout but still allows actionA to reach the reducer and change the state synchronously:

const middleware = ({ dispatch, getState }) = next => action => {
   if(action.type == "ACTION_A"){ //
       setTimeout(()=> {
           const { data } = getState();
           dispatch({type:"ACTION_B", payload: data });
       }, 2000);
   }

   next(action);
}

It's important for reducers to be pure functions, meaning they should not have side effects such as scheduling or dispatching actions. If an action requires something beyond altering the state, it should utilize a middleware (like a thunk) instead.

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

Convenient ways to connect data between a database and Firebase authentication system

After beginning a basic app using Firebase 3 and Angular 1, I implemented an authentication system through Firebase for user registration and login. Currently, I am storing message data in the Firebase database. My main question is: how can I connect user ...

Migrating from jQuery to Vue: Resolving Uncaught TypeError - n.getClientRects is not a valid function

How do I convert this jquery code into Vue.js format? // Scale the cell item. $(document).on('click','.cell-item a', function(event) { event.preventDefault() var $this = $(this) console.log($this) // [a] - correct v ...

Issues with the visibility of React Bootstrap components

I'm troubleshooting an issue with the carousel on my website. When I try to load the page, the carousel appears blank. To set up the carousel, I used npm to install react-bootstrap. The carousel code can be found at . Upon checking the web console, ...

The functionality of the code in a stack snippet may differ from that in a standalone HTML file

My code works perfectly on a stack snippet, but when I insert it into my server or an .html file, the refresh button shrinks! I have copied and pasted the code exactly as it is. Are there any specific snippet features that need to be added for it to work, ...

Access rejected due to X-Frame-Options: "http://test.test.net/Feedback/Create?appId=TestApp" prohibits cross-origin framing in MVC5

Currently, I am developing a website that is hosted on my company's internal network and can only be accessed from within the network. As a result, cross-domain requests are not a concern for me. As part of this website, I have included a "Provide Fe ...

The latest pathway fails to refresh in NextJs

I've implemented a search bar at the top of my app which directs to /search/[searchId].js page: <Link href={`/search/${search}`}> <button type='submit' className='btn-cta btn-3'>SEARCH</button> < ...

Is there a viable substitute for websockets that can be utilized on shared hosting platforms?

Are there any viable alternatives for websockets that can be used with shared hosting? While I'm aware of node.js, socket.io, and Express.js, I'm unable to use them in a shared hosting environment. If there are other options available for creatin ...

JavaScript makes it simple to display student names based on their ID numbers

Here is my JavaScript code: <script language="Javascript"> var data = { 7: "Jack Black", 8: "John Smith" }; var id = document.getElementById("id"), emp = document.getElementById("name"); id.addEventListener("keyup", function() { emp.value ...

Page freezing due to JQuery scroll event

I successfully implemented a trigger that checks if an element is within the visible viewport and added it to the scroll event. While this works smoothly on some pages, I noticed that on larger pages it causes the page to freeze. In Firefox, I experienced ...

Passing data as a parameter from the view to the controller using AngularJS

I am attempting to retrieve data from a view, which must be passed as a parameter in a function in order to populate an array in the controller. However, I am not receiving any objects in return. Here is what I have tried: VIEW <div ng-repeat="cssfram ...

Rerender not occurring after array splice with React hooks setter

My parent component structure is as follows: import React from "react"; import Test from "./Test"; function App() { const [configs, setConfigs] = React.useState([1, 2, 3]) return ( <div> ...

Turn off and then reinstall Image when clicked

function show(){ alert("i am pixel"); } function disableImgClick(){ $(".Dicon").unbind('click'); } $(document).ready(function(){ $("#turnoff_btn").click(function (e){ e.preventDefault(); disableImgClick(); }); }); i have a group of ima ...

Whenever I add a new Task in React.js, the date is not visible to me

I'm currently deepening my understanding of React, and I've encountered a roadblock. The issue arises when I attempt to create a Tracking Task - the task is successfully created from the form inputs but the date associated with the new task isn&a ...

Issue with Hover Effect on Safari Browser

Encountering a peculiar issue exclusively in Safari - when hovering over a link in the header, the links to the right of the hovered-over link alter their size (appearing smaller) during the hover animation. Once the animation concludes, these links revert ...

Creating a process to produce a random number and send it directly to an automated email

I'm currently utilizing a form builder from jqueryform.com to construct a registration form. My goal is to have each registered user assigned with a unique account number, which will be a randomly generated 6-digit number. Additionally, I want the pro ...

How can I transfer form data to a PHP variable using an AJAX request?

Encountering some difficulties, any insights? I have included only the necessary parts of the code. Essentially, I have an HTML form where I aim to extract the value from a field before submission, trigger an ajax call, and fill in another field. It seems ...

What is the best way to implement JQuery Ajax in order to invoke a PHP file on the server side, which will then execute returned javascripts?

I am currently working on a client website that requires a cross-domain JQuery Ajax call to a PHP file on my server. The purpose of this call is to query the database for various stored JavaScripts, which will then be returned to the client and executed on ...

jquery logic for iterating through all elements in a select menu encountering issues

In search of a solution to iterate through all options in a dropdown list using code, comparing each to a variable. When a match is found, I aim to set that particular value as the selected item in the dropdown and then exit the loop. Here's what I&ap ...

Guide to making a reusable AJAX function in JavaScript

Currently, I'm working on developing a function that utilizes AJAX to call data from another server and then processes the returned data using a callback. My goal is to be able to make multiple calls to different URLs and use the distinct responses in ...

The v-select function organizes data based on the content of "item-text"

I created a v-select component using Vuetify, and I am wondering how I can sort the names of the items from largest to smallest within this v-select? <v-select v-model="selectedFruits" :items="fruits" label="Favorite Fruit ...