侧边栏壁纸
  • 累计撰写 53 篇文章
  • 累计创建 12 个标签
  • 累计收到 8 条评论

目 录CONTENT

文章目录

React下,变量'xxxx'赋值失败?undefined?

Kirito
2024-08-13 / 0 评论 / 0 点赞 / 43 阅读 / 2931 字 / 正在检测是否收录...

What——发生了什么

今天遭遇了一个问题,在函数A内给函数A外声明的变量a赋值,函数B中访问变量a,却为 undefined,简化代码如下:

const Demo = () => {
  const [message, setMessage] = useState<string>('')  

  let target: EventSource

  const functionA = () => {
    target = new EventSource('#href#')
    console.log(target)  // EventSource Object

    target.onmessage = (event) => {
      setMessage(event.data)
    }
  }

  const functionB = () => {
    console.log(target)  // undefined
    target.close() // 无效
  }
  
  return (
    <div>{message}</div>
    <button @click={functionA}>A</button>
    <button @click={functionB}>B</button>
  )
}

Why——为什么

React 组件的渲染是声明式的,每次渲染都会生成新的 JSX 输出,并根据新的输出更新 DOM。这意味着在每次渲染时,函数组件都会被重新执行,从而创建新的局部变量。

说人话:setMessage造成了组件渲染,渲染会重置局部普通变量,没错,target被重置了

How——怎么解决

useRef 持久化

useRef 提供了一种方式来创建一个在组件的整个生命周期内持续存在的对象。这个对象的 .current 属性可以用于存储任意可变值,并且 React 不会因为组件的重新渲染而重置这个对象。这就意味着你可以在组件的多个渲染周期之间持久化某些数据,而不会丢失这些数据。

挺浅显易懂的,就不说人话了

优化后代码如下

const Demo = () => {
  const [message, setMessage] = useState<string>('')  

  const targetRef = useRef<EventSource>()

  const functionA = () => {
    targetRef.current = new EventSource('#href#')
    console.log(target)  // EventSource Object

    targetRef.current.onmessage = (event) => {
      setMessage(event.data)
    }
  }

  const functionB = () => {
    console.log(targetRef.current)  // EventSource Object
    targetRef.current.close()
  }
  
  return (
    <div>{message}</div>
    <button @click={functionA}>A</button>
    <button @click={functionB}>B</button>
  )
}

0

评论区