根据文件
useSelector(selector: Function, equalityFn?: Function)
useSelector接受两个参数,第二个参数是可选的,因为默认情况下它比较strict ===引用相等性检查,而不是shallow相等性检查。
const state = useSelector(state => {
console.log("useSelector rerendering");
return state.counter
}, shallowEqual)
另一个是
const state = useSelector(state => {
console.log("useSelector rerendering");
return state.counter
})
在这两种情况下,当redux存储状态更改时组件重新呈现,当本地状态更改时组件也将呈现(在useSelector内打印console.log)
我真的不明白它到底是怎么运作的
完整的源代码
import React, { useState } from 'react'
import { shallowEqual, useDispatch, useSelector } from 'react-redux'
import { decrement, increment } from './store/actions'
export default function CounterHooks(props) {
const [submit, setSubmit] = useState(false)
const state = useSelector(state => {
console.log("useSelector rerendering");
return state.counter
}, shallowEqual)
const dispatch = useDispatch()
console.log("component rerendering");
const increments = () => {
dispatch(increment());
}
const decrements = () => {
dispatch(decrement());
}
const submitButton = () => {
console.log("component submit", submit);
setSubmit((previousState) => !previousState)
}
return (
<div>
<button onClick={increments} >Incrmeent Counter</button>
<br />
<button onClick={decrements} >Decrement Counter</button>
<br />
<button onClick={submitButton} >Submit</button>
<br />
<h2>total : {state.count}</h2> <br />
<h2>Submit:{String(submit)}</h2> <br />
</div>
)
}
我的问题是第二个参数到底是如何工作的?
2条答案
按热度按时间frebpwbc1#
在您的示例中,这并没有什么区别。
shallowEquals
适用于选择内容相似但引用不同的对象。请参见以下两个对象:
虽然
a
和b
是两个具有相似形状和内容的对象,但它们不是同一个对象。现在shallowEquals
在a.foo
和b.foo
之间进行===
比较,由于两者都是具有相同内容的字符串,因此a.foo === b.foo
将为真。如果您在选择器中创建一个新对象,例如
这样做的结果将始终是一个新对象,因此默认情况下
useSelector
将始终假定它们是不同的,即使state.foo.bar
和state.baz.boo
实际上没有更改。如果使用shallowEqual
,useSelector
将查看直接(仅1级深度)子属性并比较它们。然后它会注意到它们实际上是相等的,并且不会重新呈现。f5emj3cl2#
考虑以下为减速器,
如果我们用如下所示的相同数据向reducer发送一个动作,
上面的代码不会导致组件重新呈现,因为我们引用的state.users与前一个相同。
我们可以通过以下更改使其重新渲染,
在上面的代码中,我们直接返回了一个对象,因此无论何时运行useSelector,由于引用相等,返回的对象都不会相同。