带有StrictMode的ReactJS吞下一些日志消息



我在升级react版本时发现了一个奇怪的现象:当将react从16.8.6升级到17.0.1时,新应用程序吞噬了一些日志消息,尽管在网页上呈现的结果仍然完全相同。有人能帮我解释一下吗?

详细说明:

这是我的组件:

let componentCount = 0;
let returnCount = 0;
let useSelectorCount = 0;
let useEffectCount = 0;
const Comp04ClickButtonPage = (): JSX.Element => {
    componentCount++;
    console.log(`[${componentCount}] component - START ----------------------`);
    // useSelector
    const stringValueState = useSelector((rootState: RootState): string => {
        useSelectorCount++;
        console.log(`[${componentCount}] selectorCount: ${useSelectorCount}`);
        const result = rootState.comp04ClickButtonSlice.stringValue;
        return result;
    });
    console.log(`[${componentCount}] component - after useSelectorCount`);
    // useEffect
    const dispatch = useDispatch();
    useEffect(() => {
        useEffectCount++;
        console.log(`[${componentCount}] effectCount: ${useEffectCount}.`);
        dispatch(thunkComp04ClickButton(`${new Date().getTime()}`));
    }, [dispatch]);
    console.log(`[${componentCount}] component - after useEffect`);
    const onClickButton = () => {
        componentCount = returnCount = useSelectorCount = useEffectCount = 0; // reset counts
        console.log(`[${componentCount}] onClickNewValue`);
        dispatch(thunkComp04ClickButton(`Random ${new Date().getTime()}`));
    };
    // render
    returnCount++;
    return (
        <div>
            {console.log(`[${componentCount}] renderCount: ${returnCount}`)}
            <div>
                [{componentCount}], useEffect: {useEffectCount}, useSelectorCount: {useSelectorCount}, returnCount: {returnCount}
            </div>
            <button onClick={onClickButton}>Click Button</button>
        </div>
    );
};
export default Comp04ClickButtonPage;

摘自旧版package.json:

"dependencies": {
  "@reduxjs/toolkit": "^1.5.0",
  "react": "^16.8.6",
  "react-dom": "^16.8.6",
  "react-intl": "^5.10.2",
  "react-redux": "^7.2.2",
  "react-router-dom": "^5.2.0",
  "react-scripts": "^4.0.1",
  "react-use": "^15.3.4",
  "redux": "^4.0.5",
  "redux-devtools-extension": "^2.13.8",
  "typescript": "^4.1.3",
  "web-vitals": "^1.1.0"
} 

新版本package.json节选:

"dependencies": {
  "@reduxjs/toolkit": "^1.5.0",
  "react": "^17.0.1",
  "react-dom": "^17.0.1",
  "react-intl": "^5.10.16",
  "react-redux": "^7.2.2",
  "react-router-dom": "^5.2.0",
  "react-scripts": "^4.0.1",
  "react-use": "^15.3.8",
  "redux": "^4.0.5",
  "redux-devtools-extension": "^2.13.8",
  "typescript": "^4.1.3",
  "web-vitals": "^1.1.0"
}  

旧版本日志:截图1

新版本日志:截图2

在新版本的截图中更具体:

失踪1:componentCount由"[1]"改为"[2]",实际日志信息为:

[1] renderCount: 1
[2] selectorCount: 2  

但是如果我们看一下代码:

const Comp04ClickButtonPage = (): JSX.Element => {
    componentCount++;
    console.log(`[${componentCount}] component - START ----------------------`);
因此,期望的日志消息是:
[1] renderCount: 1
[2] component - START ----------------------
[2] selectorCount: 2 

我不明白componentCount是如何增加的,但component - START日志信息缺失??

失踪2:在新版本的日志消息中(截图2),组件第四次执行时的整个日志丢失了(而它们在旧版本中出现了-截图1):

[4] component - START ----------------------
[4] selectorCount: 7
[4] component - after useSelectorCount
[4] component - after useEffect
[4] renderCount: 4

期望是这些日志消息应该在新React版本运行时以与旧版本相同的方式出现。

注意:网页的结果仍然是[4], useEffect: 1, useSelectorCount: 7, returnCount: 4。这意味着执行componentCount++行,而不打印下一行console.log([${componentCount}] component - START ----------------------);的日志消息。这怎么可能呢?

p/S:完整代码:https://github.com/khoitnm/practice-react-redux
在该存储库中,有两个项目pro-00-old-react-versionpro-01-redux-simple。唯一的区别是package.json文件。所有其他文件都是完全相同的。

Strictmode在开发过程中运行时将运行hooks/渲染多次以检测内存泄漏,这就是为什么您的组件在严格模式下渲染4次而不是2次。

我确实克隆了你的repo,发现了一些有趣的东西。在不改变log

的情况下
console.log(`[${componentCount}] selectorCount: ${useSelectorCount}`);

从1跳转到3,值2不被记录。对于Chrome或React开发者来说,这可能是一个有趣的案例。虽然控制台日志没有显示,但控制台日志肯定是执行的,因为useSelectorCount++与日志位于同一代码块中。当不使用严格模式时,所有这些都会消失。

对于不移除严格模式;如果你看一下stack overflow,你会发现严格模式是一个完美的脚枪,我相信开发者会为它感到骄傲,不会建议删除它,但如果你想学习React并预测组件何时渲染和钩子何时执行,那么使用它会让你感到困惑。

相关内容

  • 没有找到相关文章