记一个React组件入参不当导致页面卡死的问题
2024-01-07 23:37:20
一、问题描述
1.1 触发现象
点击按钮后页面卡死
1.2 最小 Demo
- CodeSandBox:https://codesandbox.io/p/sandbox/react-hook-component-stuck-755wcy
- inscode:https://inscode.csdn.net/
import './App.css';
import React, { useState, useEffect } from "react";
const Demo = ({ value = [] }) => {
const [state, setState] = useState();
useEffect(() => {
console.log("value", value);
setState((value || []).filter((item) => item !== ""));
}, [value]);
return <div>list:{state}</div>;
};
export default function App() {
const [list, setList] = useState(["1", "2"]);
return (
<div className="App">
<Demo value={list} />
<h1 onClick={() => setList([...list, "a"])}>Add List</h1>
<h1 onClick={() => setList(undefined)}>Clear List</h1>
</div>
);
}
二、原因分析
2.1 排查过程
2.1.1 console 输出查看
没有报错日志
2.1.2 performance 查看
setState 方法耗时较长
2.1.3 源码屏蔽分析
二分法屏蔽问题代码并大致定位范围为 Demo 组件引起
2.1.4 源码加 log 分析
第 7 行加 log 发现,Value 入参传为 undefined 时会循环打印 log
2.2 原因分析
- 入参默认空数组不合理,组件内部更新状态都会拿到一个全新的入参空数组
const Demo = ({ value = [] }) => {
- 状态更新不合理,依赖入参状态并处理后再显示,还使用了空数组兜底,这里也没有判断入参 Value 本身为空的情况
useEffect(() => {
console.log("value", value);
setState((value || []).filter((item) => item !== ""));
}, [value]);
三、后续预防
3.1 入参默认值
使用 useEffect 监听的入参尽量不给默认值,并且处理好入参的各种边界情况
3.2 入参与视图
简单的入参处理尽量省略,可以直接使用入参做视图展示,比如:
return <div>list:{value?.length > 0 && value.filter(Boolean)}</div>;
文章来源:https://blog.csdn.net/zhichaosong/article/details/135446067
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!