我有一个简单的响应工作示例,它显示了 “应用程序渲染器:2 ',但控制台日志只显示计算的渲染计数为1,但我不知道为什么。
通过日志查看钩子也不能告诉我渲染计数何时达到2,以及为什么渲染计数达到2。
下面链接指向codesandbox上的工作示例以及代码和控制台输出:
working example is also here
代码:
-应用程序. js-
import React, { useState, useCallback } from "react";
import { useBetween } from "use-between";
const useRenderCounts = () => {
const [appRenderCnt, setAppRenderCnt] = useState(0);
const bumpAppRenderCnt = () => {
console.log(
"bumpAppRenderCnt -> before setAppRenderCnt - appRenderCnt: ",
appRenderCnt
);
setAppRenderCnt((prevRenderCnt) => {
let newRenderCnt = prevRenderCnt + 1;
console.log(
"setAppRenderCnt old: ",
prevRenderCnt,
"new: ",
newRenderCnt,
"current appRenderCnt: ",
appRenderCnt
);
return newRenderCnt;
});
console.log(
"bumpAppRenderCnt -> after setAppRenderCnt - appRenderCnt: ",
appRenderCnt
);
};
return {
appRenderCnt: appRenderCnt,
bumpAppRenderCnt: bumpAppRenderCnt
};
};
const useCounters = () => {
const [sharedCnt, setSharedCnt] = useState(0);
const incSharedCnt = useCallback(() => {
setSharedCnt((sc) => sc + 1);
}, []);
const decSharedCnt = useCallback(() => {
setSharedCnt((sc) => sc - 1);
}, []);
const [cnt1, setCnt1] = useState(0);
const incCnt1 = useCallback(() => {
setCnt1((c1) => c1 + 1);
incSharedCnt();
}, [incSharedCnt]);
const decCnt1 = useCallback(() => {
setCnt1((c1) => c1 - 1);
decSharedCnt();
}, [decSharedCnt]);
const [cnt2, setCnt2] = useState(0);
const incCnt2 = useCallback(() => {
setCnt2((c2) => c2 + 1);
incSharedCnt();
}, [incSharedCnt]);
const decCnt2 = useCallback(() => {
setCnt2((c2) => c2 - 1);
decSharedCnt();
}, [decSharedCnt]);
return {
cnt1: cnt1,
incCnt1: incCnt1,
decCnt1: decCnt1,
cnt2: cnt2,
incCnt2: incCnt2,
decCnt2: decCnt2,
sharedCnt: sharedCnt
};
};
const useSharedCounters = () => useBetween(useCounters);
const useSharedAppRenderCounters = () => useBetween(useRenderCounts);
const Renders = () => {
const { appRenderCnt } = useSharedAppRenderCounters();
return (
<div>
<p>App Renders: {appRenderCnt}</p>
</div>
);
};
const Counts = () => {
const { cnt1, cnt2, sharedCnt } = useSharedCounters();
return (
<div>
<p>Shared Count: {sharedCnt}</p>
<p>Count 1: {cnt1}</p>
<p>Count 2: {cnt2}</p>
</div>
);
};
const Buttons1 = () => {
const { incCnt1, decCnt1 } = useSharedCounters();
return (
<>
<button onClick={incCnt1}>+ Count 1</button>
<button onClick={decCnt1}>- Count 1</button>
</>
);
};
const Buttons2 = () => {
const { incCnt2, decCnt2 } = useSharedCounters();
return (
<>
<button onClick={incCnt2}>+ Count 2</button>
<button onClick={decCnt2}>- Count 2</button>
</>
);
};
const App = () => {
const { appRenderCnt, bumpAppRenderCnt } = useSharedAppRenderCounters();
console.log("App is rendering; before bump: ", appRenderCnt);
bumpAppRenderCnt();
console.log("App is rendering; after bump: ", appRenderCnt);
return (
<>
<div>
<Renders />
<Counts />
</div>
<div>
<h5>Buttons 1</h5>
<Buttons1 />
</div>
<div>
<h5>Buttons 2</h5>
<Buttons2 />
</div>
</>
);
};
export default App;
-索引. js-
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
const rootElement = document.getElementById("root");
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
rootElement
);
控制台日志如下:
> App is rendering; before bump: 0
> bumpAppRenderCnt -> before setAppRenderCnt - appRenderCnt: 0
> setAppRenderCnt old: 0
> new: 1
> current appRenderCnt: 0
> bumpAppRenderCnt -> after setAppRenderCnt - appRenderCnt: 0
> App is rendering; after bump: 0
2条答案
按热度按时间k4ymrczo1#
这个问题与
<React.StrictMode>...</React.StrictMode>
标记有关。或者,更一般地说,据我所知,React在严格模式/开发模式下进行了额外的渲染。移除这些标记会将渲染计数减少为1,正如预期的那样。
mnemlml82#
你好!
在React的StrictMode中重新调用Render是调试新并发模式的一种方法。这对于React 17和18也是不同的。https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects
要支持React 18的StrictMode,请使用useBetween版本1.3.4
大大的谢了!