前提场景:代码中 buildProcessor 方法不能重复运行 ,useExecuter 方法只会用第一次结果
"use client";
import { useEffect, useMemo, useState } from "react";
export default function RenderTest() {
const [processor, setProcessor] = useState<number | undefined>();
// build processor
useEffect(() => {
const _processor = buildProcessor();
console.log("build processor", _processor.processor);
setProcessor(_processor.processor);
return () => {
console.log("cleanup processor", _processor.processor);
_processor.destroy();
};
}, []);
console.log("renderRenderTest, processor", processor);
//虽然该组件会被 react 强制执行两次,但是 ExecurerWrap 只会被渲染最后一次
return processor ? (
<ExecurerWrap processor={processor} />
) : (
<div>Loading...</div>
);
}
function ExecurerWrap({ processor }: { processor: number }) {
const executer = useExecuter(processor);
console.log("render ExecurerWrap, executer, processor", executer, processor);
return (
<div>
<div>渲染 executer:{executer}</div>
</div>
);
}
function buildProcessor() {
// 该函数构建了网络访问,因此不允许未销毁而重复创建
const seed = Date.now();
return {
processor: seed,
destroy: () => console.log("destory processor", seed),
};
}
/**
* 只会初始化一次,不会使用新的值
*/
function useExecuter(processor?: number) {
return useMemo(() => {
console.log("call processor", processor);
return processor;
}, []);
}
代码执行结果
page.tsx:33 renderRenderTest, processor undefined
page.tsx:8 mounted
page.tsx:25 build processor 1701061145592
page.tsx:15 unmounted
page.tsx:28 cleanup processor 1701061145592
page.tsx:58 destory processor 1701061145592
page.tsx:8 mounted
page.tsx:25 build processor 1701061145593
page.tsx:33 renderRenderTest, processor 1701061145593
page.tsx:67 call processor 1701061145593
page.tsx:67 call processor 1701061145593
page.tsx:45 render ExecurerWrap, executer, processor 1701061145593 1701061145593
以上我是构建了一个场景(我真实遇到的):useExecuter 方法由于会缓存第一次结果而不再更新,导致我无法在页面上渲染最新的 executer 。因此我采用包装了 ExecurerWrap ,实现按条件触发渲染。最终效果是成功了。
顺便对于 react 的严格模式我得到这样一个结论:它是把 hook 重新执行一次,而不是按着顺序把整个组件函数跑两遍,因此 build processor 构建了两次不一样的值,但是 ExecurerWrap 只有最后一次才真的被调用了。 (这个结论对吗)
最后也是最重要的 我上面这个解决 buildProcessor 方法不能重复运行和 useExecuter 方法只用第一次结果 的方案是不是合适的,有什么其他的方案吗?
————————
我这两天刚开始接触 react ,因此虚心求教大佬们。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.