如何防止使用 React-Redux 进行批处理
How to prevent batching with React-Redux
我正在尝试解释 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,我无法让反例起作用,因为即使有多个异步操作也会发生批处理,即。数字增加了 2 而不是 1。
有人可以提供一个有效的反例吗?
// 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);
'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. '
我在 CodeSandbox 上使用 React 18。早期版本不会像 React 18 那样进行自动批处理。
(见reference here and here)
我正在尝试解释 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,我无法让反例起作用,因为即使有多个异步操作也会发生批处理,即。数字增加了 2 而不是 1。
有人可以提供一个有效的反例吗?
// 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);
'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. '
我在 CodeSandbox 上使用 React 18。早期版本不会像 React 18 那样进行自动批处理。
(见reference here and here)