Equality
Overview
Some common equality-checking presets that can be used with useStateValue
and useStateValueWithReactiveSelector
or for any general purpose.
Presets
shallowCompareArray
Compares each element in the array using Object.is
. Use this when your selector returns an array.
shallowCompareArray(
previousState: Array<any> | any,
nextState: Array<any> | any
): boolean
Plain Example
React Example
import { Equality, StateManager } from 'cotton-box'
import { useStateValue } from 'cotton-box-react'
const ExampleState = new StateManager({
foo: '...',
bar: '...',
})
function App(): JSX.Element {
const state = useStateValue(
ExampleState,
(state) => [state.foo, state.bar],
Equality.shallowCompareArray
)
return '...'
}
Each time the selector runs, a new array is returned. By default, Object.is
is used to compare the previous and next states. So even if the length of array and the elements that it contains do not change, they will still be treated as "not equal" and cause unnecessary re-rendering in components.
shallowCompareObject
Compares each item in the object using Object.is
. Use this when your selector returns a plain object.
shallowCompareObject(previousState: any, nextState: any): boolean
Plain Example
React Example
import { Equality, StateManager } from 'cotton-box'
import { useStateValue } from 'cotton-box-react'
const ExampleState = new StateManager({
foo: '...',
bar: '...',
})
function App(): JSX.Element {
const state = useStateValue(
ExampleState,
(state) => ({ foo: state.foo, bar: state.bar }),
Equality.shallowCompareObject
)
return '...'
}
Each time the selector runs, a new object is returned. By default, Object.is
is used to compare the previous and next states. So even if the number of key-value pairs, their contents, and how they are ordered do not change, the previous and next states will still be treated as "not equal" and cause unnecessary re-rendering in components.
shallowCompareArrayOrObject
A wrapper around shallowCompareArray
and shallowCompareObject
. Only use this when you cannot determine whether your selected state will return an array or an object as it exhausts additional computing resources that could otherwise be prevented.
shallowCompareArrayOrObject(
previousState: Array<any> | any,
nextState: Array<any> | any
): boolean
Plain Example
React Example
import { Equality, StateManager } from 'cotton-box'
import { useStateValue } from 'cotton-box-react'
const ExampleState = new StateManager({
foo: '...',
bar: '...',
baz: '...',
qux: '...',
someFlag: true,
})
const complexSelector = (state) => {
if (state.someFlag) {
return [
state.foo,
state.bar,
]
} else {
return {
baz: state.baz,
qux: state.qux,
}
}
}
function App(): JSX.Element {
const state = useStateValue(
ExampleState,
complexSelector,
Equality.shallowCompareArrayOrObject
)
return '...'
}
stringifyCompare
Compares the previous and next states after serializing them with JSON.stringify
.
stringifyCompare(previousState: any, nextState: any): boolean
Plain Example
React Example
import { Equality, StateManager } from 'cotton-box'
import { useStateValue } from 'cotton-box-react'
const ExampleState = new StateManager({
foo: new Date('...'),
bar: '...',
})
function App(): JSX.Element {
const state = useStateValue(
ExampleState,
(state) => state.foo,
Equality.stringifyCompare
)
return '...'
}
The example above is just for demonstration. Avoid using JSON.stringify
to compare states because it usually comes with a higher computing overhead as the states will first need to be serialized into strings before their values can be compared.
Instead, prefer using custom functions that are tailored to the shape of your state. This would be a more practical rewrite of the example above:
const state = useStateValue(
ExampleState,
(state) => state.foo,
(prevState, nextState) => prevState.getTime() === nextState.getTime()
)
What is a "shape"?
In JavaScript programs, it’s common to have multiple objects with the same property keys. Such objects have the same shape.
const object1 = { x: 1, y: 2 };
const object2 = { x: 3, y: 4 };
// `object1` and `object2` have the same shape.
Quoted from: https://mathiasbynens.be/notes/shapes-ics#shapes