记一个React组件入参不当导致页面卡死的问题

一、问题描述

1.1 触发现象

点击按钮后页面卡死

1.2 最小 Demo

javascript 复制代码
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 原因分析

  1. 入参默认空数组不合理,组件内部更新状态都会拿到一个全新的入参空数组
javascript 复制代码
const Demo = ({ value = [] }) => {
  1. 状态更新不合理,依赖入参状态并处理后再显示,还使用了空数组兜底,这里也没有判断入参 Value 本身为空的情况
javascript 复制代码
  useEffect(() => {
    console.log("value", value);
    setState((value || []).filter((item) => item !== ""));
  }, [value]);

三、后续预防

3.1 入参默认值

使用 useEffect 监听的入参尽量不给默认值,并且处理好入参的各种边界情况

3.2 入参与视图

简单的入参处理尽量省略,可以直接使用入参做视图展示,比如:

javascript 复制代码
  return <div>list:{value?.length > 0 && value.filter(Boolean)}</div>;
相关推荐
不可求~18 小时前
多模型路由怎么落地:把任务分流写进项目的最小实现
java·前端·数据库
AC赳赳老秦21 小时前
公开图片 OCR 数据提取:OpenClaw 合规采集公开信息图,识别文字与表格并转化为结构化数据
java·大数据·前端·数据库·python·php·openclaw
谢慧琼21 小时前
2026零基础做企业网站,低成本搭建官方网站
服务器·前端·javascript
weixin_431600441 天前
前端数据埋点(1):一次点击如何变成一条埋点
前端·js·数据埋点
IT_陈寒1 天前
Python线程池吞了异常还不告诉我,这谁顶得住啊
前端·人工智能·后端
计算机魔术师1 天前
同样是AI辅助建造,为什么有的游戏三个月就烂尾了?
前端
用户921080262861 天前
0. 做 Agent 产品,前端 AI 组件框架怎么选?
前端
拾年2751 天前
React Hooks 进阶篇:useMemo / useCallback / useReducer / useImperativeHandle,用「算账 +
前端·javascript·react.js
Jackson__1 天前
面试官:如何在老项目中使用新框架,并实现通信?
前端·javascript·面试
拾年2751 天前
React Hooks 保姆级教程:把组件想象成失忆的打工人,4 个 Hook 带你原地起飞
前端·javascript·react.js