@@ -90,6 +90,12 @@ type PersistableFixableAtomOptionsWithPrecompute<TValue, TPrecomputedValue> = {
9090 */
9191 initialValue : TValue ;
9292
93+ /**
94+ * A function to compare two values for equality.
95+ * This is used to optimize updates by preventing unnecessary re-renders.
96+ */
97+ areEqualFunction ?: ( a : TValue , b : TValue ) => boolean ;
98+
9399 precomputeFunction : ( options : { value : TValue ; get : Getter } ) => TPrecomputedValue ;
94100 /**
95101 * A function to validate whether the given value is valid in the current application context.
@@ -123,6 +129,12 @@ type PersistableFixableAtomOptionsWithoutPrecompute<TValue> = {
123129 */
124130 initialValue : TValue ;
125131
132+ /**
133+ * A function to compare two values for equality.
134+ * This is used to optimize updates by preventing unnecessary re-renders.
135+ */
136+ areEqualFunction ?: ( a : TValue , b : TValue ) => boolean ;
137+
126138 /**
127139 * A function to validate whether the given value is valid in the current application context.
128140 * Called whenever the atom is read to determine if a persisted value is still valid.
@@ -226,20 +238,28 @@ export function persistableFixableAtom<TValue, TPrecomputedValue>(
226238 _source : internalState . _source ,
227239 } ;
228240 } ,
229- ( _ , set , update : TValue | PersistableAtomState < TValue > ) => {
241+ ( get , set , update : TValue | PersistableAtomState < TValue > ) => {
242+ const areEqualFunc = options . areEqualFunction ;
243+ const currentState = get ( internalStateAtom ) ;
244+
230245 if ( isInternalState ( update ) ) {
231- set ( internalStateAtom , {
232- ...update ,
233- } ) ;
246+ if ( areEqualFunc && areEqualFunc ( currentState . value , update . value ) ) {
247+ // If values are equal, preserve value reference, but update source if different
248+ if ( currentState . _source !== update . _source ) {
249+ set ( internalStateAtom , { value : currentState . value , _source : update . _source } ) ;
250+ }
251+ return ;
252+ }
253+ set ( internalStateAtom , { ...update } ) ;
234254 return ;
235255 }
236256
237- const newInternalState : PersistableAtomState < TValue > = {
238- value : update ,
239- _source : Source . USER ,
240- } ;
241-
242- set ( internalStateAtom , newInternalState ) ;
257+ // Handle direct value updates (non-internal state)
258+ const value =
259+ areEqualFunc && areEqualFunc ( currentState . value , update )
260+ ? currentState . value // Preserve reference when equal
261+ : update ;
262+ set ( internalStateAtom , { value , _source : Source . USER } ) ;
243263 } ,
244264 ) ;
245265
0 commit comments