React 一个星期踩坑记,解决页面闪烁与内存泄漏
是的,我又回来了,我写好nuxt3, 和 vue3,现在写着一个星期的 react 的老码农。
vue3 学习成本 与 react 的学习成本我认为差不了多少,vue3 花的时间是去了解官方为你准备的规范和建议,而react 是没有太多的官方标准的规范,所以你得花的时间在坑里成长。
有几个我统一下可以让你避免很多坑:
useEffect/useLayoutEffect:
const [status, setStatus] = useState(false);
useEffect(() => {
let isMounted = true;
if (isMounted) {
setStatus(true);
}
return () => {
// 卸载
isMounted = false;
};
}, [status]);
// 和 dom 有关系的,可以这样使用,如果有样式有闪烁,可以试试 useLayoutEffect
const isMountedRef = useRef(true);
useEffect(() => {
isMountedRef.current = true;
if (isMountedRef.current) {
setStatus(true);
}
return () => {
// 卸载
isMountedRef.current = false;
};
}, []);
React 不像 vue3, vue3 不管刷新还是状态,它的值只会被渲染第一次,所以你必须调用 ref, computed, watch 才可以拿到最新的值。
那么 react 侧会每次更新,处理不好就会产生内存泄漏,所以每次发看到 app 延迟时,大概率 app 是 react 开发的。
memo/useMemo/useCallBack
memo
你可以用在自定义组件里,比如以下:
// components/sidebar.tsx
// useMemo / memo 在我眼里都是差不多,只是用法不一样
// useMemo 肯定不能这样使用,所以就用 memo
const sidebar = (props) => {
return (
<>
菜单内容
</>
)
};
export default memo(sidebar);
useMemo
// 这里的依赖是当location.pathname 改变了,才调用一次
const items = useMemo(() => {
return [
'en' => {
key: 'en',
label: '<a onClick="navigate('/en/home')">English</a>'
},
'cn' => {
key: 'cn',
label: '<a onClick="navigate('/cn/home')">中文</a>'
},
]
}, [location.pathname]);
return (
<Dropdown menu={{ items }} placement="bottom" arrow>
<Button>
{items[i18n.language].label}
</Button>
</Dropdown>
);
useCallback
// 这个不难理解就封装多一层 useCallback 就可以
const handleToggle = useCallback(() => {
dispatch(dispatchSidebar.toggle());
}, []);
这些你可以掌握好,你的页面大概率不会出现闪烁了,也解决了大部分内存泄漏
本作品采用《CC 协议》,转载必须注明作者和本文链接