手把手教你修复VSCode C/C++开发环境:当IntelliSense Engine设置冲突导致运行按钮丢失
2026/6/16 22:08:36
在 React 的render()(或函数组件的渲染路径)中
不应包含
副作用(Side effects): 如网络请求、订阅、定时器、I/O、路由跳转等。
componentDidMount/componentDidUpdate,函数组件放useEffect(并正确设置依赖)。调用setState或 导致状态变化的操作: 直接或间接在 render 里调用setState会立即触发新渲染,容易导致无限循环。
直接修改this.state或可变数据(Mutation): 如this.state.obj.x = 1、array.push()。
const next = {...this.state.obj, x:1}或const nextArr = [...arr, item]。长时间或昂贵的计算: CPU 密集型操作会阻塞渲染导致卡顿。
useMemo/memo/PureComponent或把计算异步化/提前计算。创建新的函数/对象引用(频繁): 在渲染每次都新建匿名函数或对象(如onClick={() => doX()}、style={{}})会使子组件收到不同引用,触发不必要重渲染。
useCallback、useMemo或提前提取常量。直接操作 DOM 或添加事件监听: 如document.addEventListener、手动修改节点。
componentDidMount/useEffect中进行,并在卸载时清理。异步/await 表达式: render 不能是异步函数,返回值必须是 React 元素或null。
非确定性副作用(例如导航、弹窗、全局状态修改): 这些在每次渲染时重复执行会造成 UX/状态错乱。
抛出异常的操作(未捕捉): 如果 render 抛错会破坏整棵组件树(除非有 ErrorBoundary)。
常见错误示例(错误)
// 错误:每次 render 都会创建定时器并在回调里 setState -> 无限循环 render() { setTimeout(() => this.setState({ x: 1 }), 1000); return <div>{this.state.x}</div>; }正确写法(类组件)
componentDidMount() { this.timer = setTimeout(() => this.setState({ x: 1 }), 1000); } componentWillUnmount() { clearTimeout(this.timer); } render() { return <div>{this.state.x}</div>; }正确写法(函数组件 + Hook)
useEffect(() => { const id = setTimeout(() => setX(1), 1000); return () => clearTimeout(id); }, []); // 空依赖:只在挂载时执行一次(排查 render 问题时用)
setState/setTimeout/fetch/addEventListener?若有,把它们移动到 effect 或生命周期。state或 props 的对象/数组?若是,改为不可变更新。useCallback/useMemo。componentWillUnmount/ effect cleanup)