Hacker News new | ask | show | jobs
by masylum 1551 days ago
The point is that "a prop changed" can't be reasoned within a component. If I receive an object as a prop, I can only reason if that pointer in memory will be the same, not wether it has changed. The allocation can happen up in the component hierarchy making this a subtle for even the most senior developers.
3 comments

That's why a number of people (myself included) advocate for overzealous/defensive use of useMemo/useCallback as a means of ensuring that a prop changing is always meaningful. The rationale is summarised here: https://www.zhenghao.io/posts/memo-or-not

There are good reasons for _not_ doing this, since using these hooks isn't free; and technically speaking useMemo isn't an identity guarantee (though it currently behaves as one), but I haven't experienced any of the common useEffect pitfalls since adopting this methodology a couple of years ago.

But as my sibling comment points out, a lot of the need for this defensive coding would go away if there were more ways of defining equivalence. I hope that one day the record and tuple proposals land, which should help a bit. But i'd also like to see something like Python's __eq__ and __hash__ in JavaScript too - perhaps done in a similar way to [Symbol.iterator].

Props are outside the boundary of concerns for a component as far as allocation go. You react to value and identity. The parent component is the one concerned with actually giving you the correct props. Very much like a function call would work. You can provide a signature or a contract, but you are not actually expected to deal with every kind of abuses, especially things that fall outside good practices.

Perhaps it is a concern in bigger codebase. AFAIK, there is no method to enforce this kind of contract. But documentation could be a big help. Like documenting how changes to a prop impact the behavior of the component - like the common `initialValue` and `value`.

In an ideal world, you're absolutely right. Reality is different, though—sometimes people make mistakes and generate objects on-the-fly without memoizing them, and sometimes you have to deal with third-party or legacy code that you can't control. Reasoning about the behavior of hooks in these types of situations can become really difficult, and there really is no good answer aside from being ultra-defensive with how you handle props and dependencies (which has many of its own downsides).
in java terms, it sounds like you need to define your own "equals()/hashCode()". The "reference equality vs logical equality" is well-understood in that domain at least.