【问题标题】:useBetween render count presented does not match render count calculateduseBetween 呈现的渲染计数与计算的渲染计数不匹配
【发布时间】:2021-06-17 23:47:53
【问题描述】:

我有一个简单的反应工作示例,显示 'App Renders: 2',但控制台日志仅显示计算的渲染计数达到 1,但我不确定为什么。 p>

通过日志查看钩子也无法让我知道渲染计数何时达到 2,以及渲染计数达到 2 的确切原因。

codesandbox 上的工作示例链接,以及代码和控制台输出如下:

working example is also here

代码:

- app.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;

- index.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

【问题讨论】:

    标签: reactjs react-hooks rendering


    【解决方案1】:

    问题与&lt;React.StrictMode&gt;...&lt;/React.StrictMode&gt; 标签有关。或者,更一般地说,据我了解,React 在严格模式/开发模式下会进行额外的渲染。

    如预期的那样,删除这些标签会将渲染计数减少到 1。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-04
      • 2016-10-21
      • 1970-01-01
      • 2023-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多