How to prevent batching with React-Redux

3k views Asked by At

I am trying to explain the React-Redux batch() function on my website. In order to do so, I need a counterexample without using batch() so that the reader can see the difference. However, as you can see here on CodeSandbox, I couldn't get the counterexample to work, as batching occurred even with multiple asynchronous operations, ie. the number is incremented by two instead of one.

Could someone provide a working counterexample?

// index.js
import React from "react";
import { createRoot } from "react-dom/client";
import { createStore, applyMiddleware } from "redux";
import { Provider } from "react-redux";
import thunk from "redux-thunk";
import reducer from "./reducer";
import App from "./App";

const store = createStore(reducer, 0, applyMiddleware(thunk));

const root = createRoot(document.getElementById("root"));

root.render(
  <Provider store={store}>
    <App />
  </Provider>
);

...

// reducer.js
export default function (state, action) {
  // a reducer
  if (typeof state === "undefined") return 0;
  switch (action.type) {
    case "INCREMENT":
      return state + 1;
    case "DECREMENT":
      return state - 1;
    default:
      return state;
  }
}

...

// App.js
import { batch, connect } from "react-redux";

function delay(sec) {
  // an asynchronous operation
  return new Promise((resolve) => {
    setTimeout(resolve, sec * 1000);
  });
}
function delayed_increment(sec) {
  // a thunk
  return function (dispatch, getState) {
    delay(sec)
      .then(() => dispatch({ type: "INCREMENT" }))
      .then(delay(sec))
      .then(() => dispatch({ type: "INCREMENT" }));
  };
}
const App = ({ v, dispatch }) => {
  console.log("rendering...", v);
  return (
    <div>
      <span>{v}</span>
      <button
        onClick={() => {
          dispatch(delayed_increment(3));
        }}
      >
        +
      </button>
    </div>
  );
};

const mapStateToProps = (state) => {
  console.log("mapStateToProps() invoked");
  return { v: state };
};

export default connect(mapStateToProps)(App);
1

There are 1 answers

0
Chong Lip Phang On BEST ANSWER

'React 18 adds out-of-the-box performance improvements by doing more batching by default, removing the need to manually batch updates in application or library code. '

I was using React 18 on CodeSandbox. Earlier versions do not do automatic batching like React 18.

(see reference here and here)