title: Strict Equality (===) versus Shallow Equality Checks in React-Redux
body: <p>I'm studying how Hooks APIs provided by <b>React-Redux-v.7.1</b> works, and saw it mentioned in <b>Equality Comparisons and Updates</b> (<a href="https://react-redux.js.org/api/hooks#equality-comparisons-and-updates" rel="noreferrer">https://react-redux.js.org/api/hooks#equality-comparisons-and-updates</a>) that: </p>
  
  <p>"<em>As of v7.1.0-alpha.5, the default comparison is a strict <b>===</b> reference comparison. This is different than <b>connect()</b>, which uses shallow equality checks on the results of <b>mapState</b> calls to determine if re-rendering is needed. This has several implications on how you should use <b>useSelector()</b>.</em>"</p>
  
  <p>I'm wondering <b>why strict equality is better than shallow equality that used by <em>connect()</em></b>? Then I looked into their equality comparisons:</p>
  
  <p>The default strict equality check of <a href="https://github.com/reduxjs/react-redux/blob/master/src/hooks/useSelector.js#L25" rel="noreferrer"><em>useSelector()</em></a> is simply checking <em>a===b</em></p>
  
  <pre><code>const refEquality = (a, b) =&gt; a === b
  </code></pre>
  
  <p>And the equality checks in <a href="https://github.com/reduxjs/react-redux/blob/0c048f0646754de103cc2d9825762340bed06119/src/utils/shallowEqual.js#L11-L35" rel="noreferrer">react-redux/src/connect/connect.js</a> is using <em>Object.is()</em> and also other checks, which is same as that in <a href="https://github.com/facebook/react/blob/a9b035b0c2b8235405835beca0c4db2cc37f18d0/packages/shared/shallowEqual.js#L19-L51" rel="noreferrer">react</a>.</p>
  
  <pre><code>// 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 &amp;&amp; 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 &lt; keysA.length; i++) {
      if (!hasOwn.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
        return false
      }
    }
  
    return true
  }
  </code></pre>
  
  <p>According to <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness" rel="noreferrer">the description of Object.is() in MDN:</a> "<em><b>Object.is</b> does no type conversion and no special handling for NaN, -0, and +0 (giving it <b>the same behavior as === except on those special numeric values</b>).</em>"</p>
  
  <p>I have no idea why <em>a === b</em> is better than a series of equality checks.
  (It's my first time asking questions here, apologize for rudeness or lack of information)</p>