As per Doc
useSelector(selector: Function, equalityFn?: Function)
useSelector accepts two params and second one is optional since by default it compare strict === reference equality check but not shallow equality.
const state = useSelector(state => {
console.log("useSelector rerendering");
return state.counter
}, shallowEqual)
Another is
const state = useSelector(state => {
console.log("useSelector rerendering");
return state.counter
})
In both Cases component rerendering when redux store state changes and also when local state changes then it will render (print console.log inside useSelector)
I really didn't understand exactly how it works
Full source code
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>
)
}
MY question is how exactly second param works ?
In your example, it does not make a difference.
shallowEquals makes sense when you select an object that might be similar in contents, but different by reference.
See these two objects:
const a = { foo: "bar" }
const b = { foo: "bar" }
console.log( a === b ) // will log false
console.log( shallowEquals(a, b)) // will log true
While a and b are two objects with similar shape and contents, they are not the same object.
Now shallowEquals does a === comparison between a.foo and b.foo and since both are strings with the same content, a.foo === b.foo will be true.
This does play a role if you create a new object in your selector, say
const result = useSelector((state) => {
return { a: state.foo.bar, b: state.baz.boo }
})
The result of this will always be a new object, so per default useSelector will always assume they are different, even when state.foo.bar and state.baz.boo actually did not change.
If you use a shallowEqual, useSelector will look at the direct (only 1 level deep) child properties of the objects and compare those. Then it will notice that they are in fact equal and not rerender.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With