TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Ask HN: What are good patterns for holding state?

7 pointsby JSLegendDevover 1 year ago
It&#x27;s common practice to use classes when needing to hold state. However, I&#x27;m wondering if it&#x27;s the best approach when you don&#x27;t need all the baggage OOP comes with like inheritance, etc...<p>Here is an example of how I would go about it without classes :<p>function makePlayer() {<p><pre><code> const data = { x: 100, y: 100, health: 300, speed: 200 } const methods = { setHealth(value){ data.health = value }, &#x2F;&#x2F; etc... } return {...data, ...methods}</code></pre> }<p>Do you think this is a good approach? If not, why?<p>EDIT: The question is meant to be general and not specific to a given framework or library. For something like React you use what is given by the library. There isn&#x27;t much room for choice here.

11 comments

Leftiumover 1 year ago
OOP classes are commonly used because they seem to naturally map to physical objects, especially in games. However they can break down when trying to model the inevitable exceptions to this &quot;natural&quot; mapping or abstract concepts.<p>OOP is based on inheritance, but there is a school of thought that prefers composition over inheritance[1]. Composition is more flexible and usually more CPU cache efficient. Entity component system (ECS) is another way to store game objects based on composition. Instead of grouping properties related to a single object together, the same property from all objects are grouped together (thus it is usually more CPU cache efficient).<p>Someone made the argument the logical conclusion of ECS is a relational database: store and modify your (game) entities using SQL![2]<p>Another paradigm is using immutable state (works with either OOP-like objects or ECS-like entities). CRUD loses data that event-sourced objects can access later. (CRUD cannot remember what items were removed from a shopping cart without extra work; event-sourced objects naturally retain this information.)[3]<p>[1]: <a href="https:&#x2F;&#x2F;youtu.be&#x2F;hxGOiiR9ZKg" rel="nofollow noreferrer">https:&#x2F;&#x2F;youtu.be&#x2F;hxGOiiR9ZKg</a><p>[2]: <a href="https:&#x2F;&#x2F;hw.leftium.com&#x2F;#&#x2F;item&#x2F;38545417" rel="nofollow noreferrer">https:&#x2F;&#x2F;hw.leftium.com&#x2F;#&#x2F;item&#x2F;38545417</a><p>[3]: <a href="https:&#x2F;&#x2F;youtu.be&#x2F;I3uH3iiiDqY" rel="nofollow noreferrer">https:&#x2F;&#x2F;youtu.be&#x2F;I3uH3iiiDqY</a>
Leftiumover 1 year ago
&gt; Do you think this is a good approach? If not, why?<p>There is no real advantage to bundling data and methods together like: `{...data, ...methods}`<p>This just uses extra memory because every player must contain its own duplicate copy of the exact same methods.<p>Instead, methods should be stored outside the player object and require their input `value` to implement an &quot;interface&quot;. For example, the input value for the `setHealth()` method must implement the &quot;Health&quot; interface.<p>TypeScript provides syntax for defining interfaces. I think JSDoc provides a way to implement interfaces with annotations. Otherwise, you could just manually enforce the interface as a convention.<p>In fact, JavaScript already allows you to attach methods to objects via Object prototypes. [1]<p>[1]: <a href="https:&#x2F;&#x2F;developer.mozilla.org&#x2F;en-US&#x2F;docs&#x2F;Learn&#x2F;JavaScript&#x2F;Objects&#x2F;Object_prototypes" rel="nofollow noreferrer">https:&#x2F;&#x2F;developer.mozilla.org&#x2F;en-US&#x2F;docs&#x2F;Learn&#x2F;JavaScript&#x2F;Ob...</a>
chalsprhebaoduover 1 year ago
Take this from someone who has been down this road: you are way over-thinking this.<p>Until you accept this, you will be holding yourself back as a JavaScript developer.<p>If you need objects with encapsulated state and methods, use classes.<p>OOP does not magically introduce baggage or complexity.<p>Your proposed solution is still OOP. Coming up with your own OOP framework <i>will</i> introduce baggage and complexity.<p>Classes are highly optimized in modern JS engines.<p>Classes can be transpiled to performant code for legacy JS engines.<p>There are times when classes are not the right choice, but avoiding classes when they’re the obvious right choice is a clear indicator that a developer is unwilling to actually learn JavaScript.<p>Edit:<p>Your example code also has a bug, where your methods don’t actually mutate the properties of the returned object.<p>Please take the leap and just learn to use JavaScript classes!
austin-cheneyover 1 year ago
For simple state management here is what I do: <a href="https:&#x2F;&#x2F;github.com&#x2F;prettydiff&#x2F;wisdom&#x2F;blob&#x2F;master&#x2F;state_management.md">https:&#x2F;&#x2F;github.com&#x2F;prettydiff&#x2F;wisdom&#x2F;blob&#x2F;master&#x2F;state_manag...</a><p>Here is an application with an OS-like GUI making use of that concept: <a href="https:&#x2F;&#x2F;github.com&#x2F;prettydiff&#x2F;share-file-systems">https:&#x2F;&#x2F;github.com&#x2F;prettydiff&#x2F;share-file-systems</a>
muzaniover 1 year ago
The reason some things manage state via classes etc is because it can change.<p>When health changes, maybe you want to change the UI to reflect the new health, without running a &quot;updateHealthUI(data.health)&quot; each time. Maybe speed is also based on health. When a project has enough people and every file is changing every day, sometimes you just want something to observe another state without them understanding the context around it. Most of the inefficiency in a large team is communicating context.<p>Don&#x27;t use more than what you need. Sometimes you don&#x27;t need React.
romanhnover 1 year ago
How is inheritance baggage? If you don&#x27;t need it, don&#x27;t use it. Not sure I understand the aversion to OOP.
评论 #38613300 未加载
bundlebeeover 1 year ago
Closures? <a href="https:&#x2F;&#x2F;developer.mozilla.org&#x2F;en-US&#x2F;docs&#x2F;Web&#x2F;JavaScript&#x2F;Closures" rel="nofollow noreferrer">https:&#x2F;&#x2F;developer.mozilla.org&#x2F;en-US&#x2F;docs&#x2F;Web&#x2F;JavaScript&#x2F;Clos...</a>
raoollover 1 year ago
I think elixir process model is the best pattern for this. Combined with GenServer it makes managing&#x2F;manipulating states easy.
joshxyzover 1 year ago
no, because it is not immutable.<p>in react directly mutating objects and arrays does not trigger rerenders.
评论 #38578678 未加载
ezekgover 1 year ago
If you need to notify on updates, a basic pubsub works for most use cases.
tracer4201over 1 year ago
What problem are we trying to solve?<p>When I think of holding in memory state, to me it’s less about class or OOP vs something else and more about race conditions, thread safety, possibly idempotency, and proper abstraction design.<p>Abstraction design meaning, I’m not exposing the keys to the castle or leaking internal details where it might allow another good intentioned programmer to do bad things or introduce some subtle, difficult to reproduce bug.