我正在研究 React-Redux-v.7.1 提供的 Hooks API 的工作原理,并在平等比较和更新 ( https://react-redux.js.org/api/hooks#equality-comparisons-and-updates ) 中看到它:
“从 v7.1.0-alpha.5 开始,默认比较是严格的 === 引用比较。这与 connect() 不同,它对 mapState 调用的结果使用浅层相等性检查来确定是否需要重新渲染。这对您应该如何使用 useSelector() 有几个影响。”
我想知道为什么严格相等比connect()使用的浅层相等更好?然后我研究了他们的平等比较:
默认严格相等检查useSelector()只是检查a===b
const refEquality = (a, b) => a === b
以及 react-redux/src/connect/connect.js 中的相等性检查正在使用 Object.is() 以及其他检查,与 react 中的相同.
// The polyfill of Object.is()
function is(x, y) {
if (x === y) {
return x !== 0 || y !== 0 || 1 / x === 1 / y
} else {
return x !== x && y !== y
}
}
export default function shallowEqual(objA, objB) {
if (is(objA, objB)) return true
if (
typeof objA !== 'object' ||
objA === null ||
typeof objB !== 'object' ||
objB === null
) {
return false
}
const keysA = Object.keys(objA)
const keysB = Object.keys(objB)
if (keysA.length !== keysB.length) return false
for (let i = 0; i < keysA.length; i++) {
if (!hasOwn.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
return false
}
}
return true
}
根据the description of Object.is() in MDN: “Object.is 不进行类型转换,也不对 NaN、-0 和 +0 进行特殊处理(使其与 === 具有相同的行为,除了那些特殊的数值)。”
我不知道为什么a === b比一系列相等检查更好。 (这是我第一次在这里提问,对于粗鲁或缺乏信息表示歉意)
最佳答案
使用 connect
时,mapStateToProps
返回从存储中选择的所有状态的复合对象,因此对其键进行浅层比较是有意义的。使用 useSelector
时,该模式通常只为每次调用 useSelector
返回一个值,类似于 useState
钩子(Hook)仅处理的方式单个值而不是所有状态值。因此,如果每次调用 useSelector
都直接返回一个值,那么严格的相等检查与浅层比较相比就有意义。一个简短的例子应该可以让这一点更加清楚。
import {connect} from 'react-redux';
const mapStateToProps = state => (
{keyA: state.reducerA.keyA, keyB: state.reducerB.keyB}
);
export default connect(mapStateToProps)(MyComponent);
这里,每次存储以任何方式发生更改时都会调用 mapStateToProps
,因此返回值将始终是一个新对象,即使 keyA
和 keyB
不要改变。因此,通过浅层比较来决定是否需要重新渲染。
对于钩子(Hook)案例:
import {useSelector} from 'react-redux';
function MyComponent(props) {
const keyA = useSelector(state => state.reducerA.keyA);
const keyB = useSelector(sate => state.reducerB.keyB);
...
}
现在,useSelector
Hook 的结果是来自存储的各个值,而不是复合对象。因此,在这里使用严格相等作为默认值是有意义的。
如果您只想使用返回复合对象的单个 useSelector
钩子(Hook),您链接到的文档有一个使用 shallowEqual
相等函数的示例:https://react-redux.js.org/api/hooks#equality-comparisons-and-updates
关于javascript - React-Redux 中的严格相等 (===) 与浅度相等检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58212159/