han's bolg - 年糕記

react组件全局变量写在Component前面和用Ref的区别

在 react hook 中,因为闭包陷阱的问题,我们不能使用 useState 来进行处理。

比如下面这段代码,不管怎么setCount,console输出的还是最初的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import React, {useEffect, useState} from 'react'

const ClosureExample = ({index}) => {
const [count, setCount] = useState(0)
useEffect(() => {
setInterval(() => {
console.log(count)
}, 1000)
}, [])

return (
<button
onClick={() => {
setCount(index)
console.log(`已点击${index}`)
}}
>{`点击闭包陷阱${index}`}</button>
)
}

export default ClosureExample
  • 解决思路就是用全局变量来处理,可以使用两种方式来处理:

    • useRef,作为组件实例的变量,保证获取到的数据肯定是最新的
    • 在组件前定义一个类似 global 的变量

但这就引发了另外一个问题,既然这两种方式都能解决问题,那两种方式有什么区别呢?

  • useRef 是定义在实例基础上的,如果代码中有多个相同的组件,每个组件的 ref 只跟组件本身有关,跟其他组件的 ref 没有关系。
  • 组件前定义的 global 变量,是属于全局的。如果代码中有多个相同的组件,那这个 global 变量在全局是同一个,他们会互相影响。

Talk is cheap, show the code.

Edit interesting-turing-91nt1

点击上面代码查看,用 ref 的组件,click 时 console 的内容是不同的。
而用组件前变量的组件,click 时 console 的内容都是最后出现的那个组件的值。

你,学会了吗?