Closed ityuany closed 7 months ago
Well, it's how it's designed. (Or, it can be said, it's the limitation with runtime solution.)
p.td.brandId;
p.td;
We treat it âď¸ the same as đ
p.td;
p.td.brandId;
which is equivalent to đ
p.td.brandId;
(We might be able to detect the access order to overcome this, but it would be less predictable, so the current behavior is our design decision.)
To summarize,
Accessing p.td.brandId
individually returns false
, which is expected because brandId has not changed.
Accessing p.td
individually returns true
, which is also expected because the object reference addresses of the two td are different.
Simultaneously accessing p.td.brandId
and p.td
returns false
, which is not quite as expected. Although brandId has not changed, td is not equal. My expectation was that it should return false
.
I found that affected actually records both brandId and td, so they should be compared simultaneously. I don't quite understand why.
p.td;
p.td.brandId;
which is equivalent to đ
p.td.brandId;
What would be your expectation of the behavior of this?
const x = p.td;
x.brandId;
What would be your expectation of the behavior of this?
const x = p.td; x.brandId;
The expected behavior, as I understand it, is to track td
and brandId
. When either td
or brandId
changes to any value, isChange
should return false
.
For example, this has caused some confusing behavior in valtio.
import { useEffect } from 'react';
import { proxy, useSnapshot } from 'valtio';
const store = proxy({
td: {
brandId: 1,
tkRepositoryIds: 2,
},
});
export default function App() {
const snap = useSnapshot(store);
useEffect(() => {
console.log('effect-->', snap.td.brandId, snap.td);
}, [snap.td, snap.td.brandId]);
return (
<>
<button
onClick={() => {
store.td.tkRepositoryIds = Math.random();
}}
>
çšć
</button>
</>
);
}
đđđ Because snap.td
and snap.td.brandId
are written in the deps of useEffect, my intuition tells me that any changes in the values of td
and brandId
should trigger a rerender of the component.
useEffect(() => {
console.log('effect-->', snap.td.brandId, snap.td);
}, [snap.td, snap.td.brandId]);
đđđ And the following button mutates td.tkRepositoryIds
, so theoretically I think td
has also changed, and the component should rerender.
<button onClick={() => {
store.td.tkRepositoryIds = Math.random();
}}>
çšć
</button>
const x = p.td;
x.brandId;
We can't distinguish that âď¸ from this đ .
p.td;
p.td.brandId;
For valtio, we consider it a limitation. https://github.com/pmndrs/valtio/blob/d1e462e14fe1d0a161c5514718ce10c1980c35ba/docs/how-tos/some-gotchas.mdx#L51 https://github.com/pmndrs/valtio/blob/d1e462e14fe1d0a161c5514718ce10c1980c35ba/docs/how-tos/some-gotchas.mdx#L135
ok , thanks .
I think maybe my understanding of proxy-compare is not deep enough. I encountered a phenomenon that I couldn't understand while using it, and I hope to get your answer.
Thank you very much.