React Hooks 的依赖是一个引用类型时
依赖项的比较是===,所以对于引用类型比较的都是地址
props
组件每次渲染的时候 props 的引用都会变,但是 props 里面的引用类型的引用可能不会变,因为即使引用类型即使是复制,复制的也是地址
所以当我们需要使用 props 的引用类型属性作为 Hooks 的依赖的时候,可能会导致的一个问题就是,该引用类型的值变了,但是由于地址没有变,所以我们拿不到最新的值,所以对于对象或者数组,当然也有可能是每次引用类型属性的地址都会变,即使对象的属性没有发生变化。所以数组或者对象不要直接使用他们来作为 hooks 的依赖。作为 Hooks 的依赖的时候我们需要这样写
对象:使用对象的某些属性而不是直接使用对象本身作为依赖
理想情况下,props 传入的 team 的内容是一样的话,其内存地址也会相同。但这其实是无法保证的。(可能相同,也可能不同)
import React, { useState, useEffect } from 'react'
import { getPlayers } from '../api'
import Players from '../components/Players'
const Team = ({ team }) => {
const [players, setPlayers] = useState([])
useEffect(() => {
if (team.active) {
getPlayers(team.id).then(setPlayers)
}
}, [team.id, team.active]) // 错误做法:[team]
return <Players team={team} players={players} />
}
数组:直接把数组作为依赖
import React, { useState, useEffect } from 'react'
import { getPlayers } from '../api'
import Players from '../components/Players'
const Team = ({ arr }) => {
const [players, setPlayers] = useState([])
useEffect(() => {
// 利用arr做一些操作
}, arr) // 错误做法:[arr]
return <Players arr={arr} players={players} />
}
state
当你使用 state 作为 hooks 的依赖时,hooks 是否能监听到 state 的改变取决于你怎么 setState 的。
当 state 是一个对象或者是数组的时候,如果你的改变是基于原来的 state 去 push 值或者直接是 state.xxx=123 这样的,此时 state 的引用是没有改变的,你的 state 还是和之前的引用一致
所以作为依赖是可能不能拿到最新的 state
可以对于对象和数组使用上面的方法作为依赖,或者每次 setState 都对 state 进行重新创建一个新对象或者是数组
但是需要注意的是 hooks 的依赖的数量在每次渲染的时候都需要保持一致,所以如果直接将数组作为依赖的时候,每次改变数组,数组的长度发生了变化就会导致 hooks 依赖数组的长度会改变,React 回报 warning,所以可以将数组 join 转为字符串做 hooks 依赖