【发布时间】:2019-07-04 09:05:41
【问题描述】:
我有两个兄弟组件,它们在 react 中通过上下文共享状态。 组件之间的共享状态是一个数组。
如果我在一个组件中更新arr 状态,我希望另一个组件监听该更新并做相应的事情。当我在第二个组件中使用useEffect 时,我会监听arr 状态变量的变化。
例如:
// App Component -------
const App = props => {
const { arr, setArr } = useContext(GlobalContext)
const handleChange = () => {
const newArr = arr
[10, 20, 30, 40].map(v => {
newArr.push(v)
setArr(newArr)
})
return (...)
}
// App2 (Sibling) Component
const App2 = props => {
const { arr, setArr } = useContext(GlobalContext)
const [localArr, setLocalArr] = useState(0)
useEffect(
() => {
updateLocalState()
},
// fire if "arr" gets updated
[arr]
)
const updateLocalState = () => {
setLocalArr(localArr + 1)
}
return (...)
}
useEffect 钩子仅在初始渲染时触发,尽管arr 的状态会更新。
我知道向我的状态变量声明一个新变量const newArr = arr 是一个引用,所以newArr.push(v) 在技术上是一个状态突变。 但是,状态仍然更新,没有抛出警告,useEffect 什么也不做。
为什么状态更新后useEffect 没有被调用?是因为状态突变吗?
第二个问题:为什么没有关于状态突变的警告或错误?状态突变是危险的 - 如果它发生,我希望得到某种警告。
现场演示:
【问题讨论】:
-
您永远不会创建新数组。
const newArr = arr用另一个变量引用同一个数组。尝试例如const newArr = [...arr]代替。 -
它是对同一个数组的引用,但这并不能解释为什么
useEffect不会触发,尽管状态仍在更新。 -
您作为第二个参数传递给
useEffect的数组仅检查数组中的元素是否为===到上一次渲染中的元素。const newArr = arr;会导致newArr === arr,这不是你想要的。 -
@Tholle 所说的,只是更改
setArr([...newArr])会正确触发useEffect
标签: javascript reactjs react-hooks