React中的useState传入函数的好处

目录

用法解释

[1. useState(getArr) vs useState(getArr())](#1. useState(getArr) vs useState(getArr()))

[2. 数组的不可变更新](#2. 数组的不可变更新)


说明

代码示例

javascript 复制代码
import React, { FC, useState } from 'react'

/**
 * 模拟一个昂贵的计算函数
 * 
 * 这个函数的作用是创建并填充一个长度为 100 的数组。
 * 我们在函数内部打印日志,是为了观察它被调用的时机。
 */
function getArr() {
  // 只有当 getArr 被执行时,控制台才会打印 'getArr...'
  // 这帮助我们理解 useState 传参的执行机制
  console.log('getArr...')

  // 创建一个长度为 100 的空数组
  const arr = new Array(100)
  
  // 将数组的每一个元素填充为字符串 'hello'
  arr.fill('hello')
  
  // 返回填充好的数组
  return arr
}

/**
 * React 函数组件 Demo
 * 
 * 该组件演示了:
 * 1. useState 的惰性初始化(传入函数)
 * 2. 不可变数据更新(展开运算符)
 */
const Demo: FC = () => {
  // 每次组件渲染(重新执行)时,都会打印 'demo...'
  console.log('demo...')

  // --- 状态定义 ---
  // useState 接收一个函数 getArr 作为参数。
  // 这是"惰性初始化"的写法。
  // React 会执行 getArr(),将其返回值作为 arr 的初始值。
  // 关键点:getArr 只会在组件的**首次渲染**时执行,后续重新渲染组件时,该函数不会再次执行。
  const [arr, setArr] = useState(getArr)

  // --- 事件处理函数 ---
  // 点击按钮时触发
  function addStr() {
    // 1. 使用展开运算符 (...) 复制原数组 arr 的所有元素
    // 2. 在新数组末尾添加一个新元素 'hello'
    // 3. 使用 setArr 更新状态
    // 注意:不能直接修改原数组 arr.push(),必须返回一个新数组来触发视图更新
    setArr([...arr, 'hello'])
  }

  // --- JSX 渲染结构 ---
  return (
    <>
      {/* 显示当前数组的长度 */}
      <p>length: {arr.length}</p>
      
      {/* 包含操作按钮的容器 */}
      <div>
        {/* 点击按钮调用 addStr 函数 */}
        <button onClick={addStr}>add</button>
      </div>
    </>
  )
}

export default Demo

结果:getArr函数,只在初始化的时候,执行一次

用法解释
1. useState(getArr) vs useState(getArr())

代码中使用的是 useState(getArr)(传入函数引用),而不是 useState(getArr())(传入函数执行结果)。

  • useState(getArr) (当前代码):
    • 机制: 惰性初始化。getArr 函数只会在组件第一次渲染 时执行一次,用来计算初始 state。之后即使组件因为状态更新而重新渲染,getArr 也不会再执行。
    • 适用场景: 当初始 state 需要通过昂贵的计算(如创建大数组、复杂计算)才能获得时,使用这种方式可以优化性能。
  • useState(getArr()):
    • 机制: 每次组件渲染(重新执行)时,都会先执行 getArr() 函数,然后将结果传给 useState。这会导致不必要的重复计算。
2. 数组的不可变更新

addStr 函数中,使用了 [...arr, 'hello']

  • 原因: React 中的状态(State)是不可变的。如果你直接使用 arr.push('hello') 修改原数组,数组的引用地址没有变,React 会认为状态没有变化,从而不会触发视图重新渲染
  • 解决: 使用展开运算符 ... 创建一个新数组,setArr 接收到新的引用地址,从而触发组件更新。
相关推荐
子兮曰13 小时前
OpenClaw入门:从零开始搭建你的私有化AI助手
前端·架构·github
吴仰晖14 小时前
使用github copliot chat的源码学习之Chromium Compositor
前端
1024小神14 小时前
github发布pages的几种状态记录
前端
不像程序员的程序媛16 小时前
Nginx日志切分
服务器·前端·nginx
Daniel李华16 小时前
echarts使用案例
android·javascript·echarts
北原_春希16 小时前
如何在Vue3项目中引入并使用Echarts图表
前端·javascript·echarts
JY-HPS16 小时前
echarts天气折线图
javascript·vue.js·echarts
尽意啊16 小时前
echarts树图动态添加子节点
前端·javascript·echarts
吃面必吃蒜16 小时前
echarts 极坐标柱状图 如何定义柱子颜色
前端·javascript·echarts
O_oStayPositive16 小时前
Vue3使用ECharts
前端·javascript·echarts