注意:这在开发和生产中都会发生,我根本不使用<StrictMode>
。
它似乎工作得很好:
B.js
export default function B()
{
return <p>B</p>
}
TestApp.js
import { lazy, Suspense } from "react";
const B = lazy(()=>import("./B"));
export default function TestApp()
{
const counter = useRef(0);
counter.current++;
console.log("rendering TestApp - counter",counter.current);
return <Suspense fallback={<p>loading B...</p>}><B/></Suspense>
}
index.js
import { lazy, Suspense } from "react";
import {createRoot} from "react-dom/client";
const TestApp = lazy(()=>import("./TestApp"));
const root = createRoot(document.getElementById("root"));
root.render(<Suspense fallback={<p>loading testapp...</p>}><TestApp/></Suspense>);
但是,当组件树中有一个更深的<Suspense>
(在TestApp本身中,挂起<B>
)时,<TestApp>
会被复制。
项目:https://github.com/jmlee2k/react-suspense-root
演示:https://jmlee2k.github.io/react-suspense-root/ (生产构建)
要查看问题,转到演示并打开控制台,您将看到两次“呈现TestApp计数器1”。如果这只是一个双重渲染,我希望计数器会增加.
我是相当新的反应,我很清楚我可能做错了什么,但任何信息都将不胜感激。
提前感谢!
发布于 2022-08-21 11:48:14
您的应用程序没有不必要的重新呈现;这是React和闭包的工作方式。
如前所述,应用程序首先加载悬念组件,并在延迟加载完成后呈现TestApp组件。
在此过程中,function装入调用该函数的TestApp组件。这里有第一个invoke count
值。当B
延迟加载时,将再次调用该函数。但是没有重新渲染,因为它的状态没有改变。TestApp组件中的所有变量都被刷新了,除了useRef
组件。这就是为什么在组件中有尽可能少的处理程序(在每次呈现时都会刷新)是一个好主意,也是为什么在useEffect中包装代码(也称为效果)是个好主意。
发布于 2022-08-11 21:04:47
这与反应的方式有关。每当任何组件的状态或属性发生更改时,响应更新其虚拟DOM树。例如,在这里,您可以看到在状态发生更改时组件是如何再次呈现的。
const {useState} = React;
const Example = () => {
console.log("Hi mom!I re-rendered")
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
};
// Render it
ReactDOM.createRoot(
document.getElementById("root")
).render(
<Example />
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>
<div id="root"></div>
请记住,应用程序的流程如下:
所以您的代码没有什么问题,因为这是react的自然行为,但是,如果有许多不必要的重新呈现,应用程序可能会遇到性能问题。
更新
我环顾四周,显然useRef不起作用,但我尝试了console.count,现在起作用了
import { lazy, Suspense, useRef } from "react";
const B = lazy(()=>import("./B"));
export default function TestApp()
{
console.count('counter')
return <Suspense fallback={<p>loading B...</p>}><B/></Suspense>
}
https://stackoverflow.com/questions/73325723
复制相似问题