-
Notifications
You must be signed in to change notification settings - Fork 204
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(react): add react package #294
Conversation
f4a3d5e
to
dc923b0
Compare
dc923b0
to
07ec8f5
Compare
packages/mud-react/package.json
Outdated
@@ -0,0 +1,72 @@ | |||
{ | |||
"name": "@latticexyz/mud-react", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wasn't sure what to call this! @latticexyz/react
felt incorrect and I think what I actually want is something like @mud/react
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good!
Let's add a short README.md
- this show up on npm's package overview page when releasing this package (like here: https://www.npmjs.com/package/@latticexyz/solecs)
import { IComputedValue } from "mobx"; | ||
import { useEffect, useState } from "react"; | ||
|
||
// TODO: migrate the rest of the mobx stuff to rxjs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Opened an issue to track this, let's add a link to the code comment: #339
component: Component<S, Metadata, undefined>, | ||
defaultValue?: ComponentValue<S> | ||
) { | ||
const entities = useEntityQuery([Has(component)]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would this hook cause a react rerender every time any value in the component changes or only if the value of the entity specified in the entityIndex
param changes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ohh this is a great point. It'd currently reevaluate for anything matching the query (Has(component)
). I may rewrite this to not depend on useEntityQuery
and be more mindful of rendering only when the single entity value changes.
Co-authored-by: alvarius <89248902+alvrs@users.noreply.github.com>
057ff27
to
1accd43
Compare
85e2000
to
0a63018
Compare
Returns the value of the component for the entity, and triggers a re-render as the component is added/removed/updated. | ||
|
||
``` | ||
const position = useComponentValue(entity, Position); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While building Emojimon, I was thinking about ECS in terms of entity-first, where "entity" is often the thing to key off of, and components are bits of data on an entity.
However, I noticed our internal APIs (setComponent
, removeComponent
), etc. all have components first, then entities. I wonder if this is because we internally model a component as a mapping of entities <> values.
How do you feel about the position of the arguments here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes that's mostly the reason - when thinking of components as tables and entities as rows in that table, it felt more natural to first specify which table to modify and then which row in that table. In general I don't feel strongly about the order of arguments, can totally see how putting entity first is more intuitive when thinking about entities as objects and components as parameters on that object. My main argument for changing the order here to also put component first would be consistency with existing functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Chatted with @alvrs some more and here's what I got out of the convo:
Data modeling with MUD can be thought of in one of two ways
- Entity-first, where the entity is the focus and data (components/values) are "attached" to an entity. I was thinking about it like this, where my "get component value" operation is more like a "get this value of this key from the entity object"
- Component/Table-first, where it's more like a relational database and the entity ID is a primary key. In the future, we may want more complicated keys (tuples) that would expand past just an entity ID. So asking for a component value is more like "get the value in the component table for this primary key aka entity ID".
Sounds like we want to guide folks towards the latter mental model, esp. as we push further into SQL-like capability.
Will update these hooks!
Quickly wired this into Emojimon to make sure it works and to see what the diff looks like: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Just a some minor comments and a minor preference for changing the order of parameters for consistency.
Returns the value of the component for the entity, and triggers a re-render as the component is added/removed/updated. | ||
|
||
``` | ||
const position = useComponentValue(entity, Position); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes that's mostly the reason - when thinking of components as tables and entities as rows in that table, it felt more natural to first specify which table to modify and then which row in that table. In general I don't feel strongly about the order of arguments, can totally see how putting entity first is more intuitive when thinking about entities as objects and components as parameters on that object. My main argument for changing the order here to also put component first would be consistency with existing functions.
packages/react/package.json
Outdated
"jest": "^29.3.1", | ||
"mobx": "^6.4.2", | ||
"react": "^18.2.0", | ||
"react-dom": "^18.2.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is react-dom
also required as peer dependency?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nope! will remove
expect(result.current).toBe(undefined); | ||
}); | ||
|
||
it("should re-render only when Position changes for entity", () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
love these tests!! 🔥
packages/react/tsconfig.json
Outdated
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ | ||
"skipLibCheck": true /* Skip type checking all .d.ts files. */ | ||
}, | ||
"exclude": ["dist", "**/*.test.ts", "packages"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ooc why do we need to exclude packages
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's not needed, this was just copy pasta
Should we add you as the codeowner for this package to auto-request reviews from? https://github.com/latticexyz/mud/blob/main/CODEOWNERS (Can also set the codeowner for |
Co-authored-by: alvarius <89248902+alvrs@users.noreply.github.com>
7dcdc60
to
8b38e05
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Amazing! 🚢
* feat: add mud-react * feat: rename mud-react to react * chore(react): clean up * chore(react): rename mobx-dependent module * feat(react): add useObservableValue hook * chore(react): add deprecation notice * chore(react): remove unused deps * fix(react): version * fix(react): use @deprecated tag Co-authored-by: alvarius <89248902+alvrs@users.noreply.github.com> * chore(react): more deprecated notices * test(react): set up test framework, add tests for useEntityQuery * test(react): add tests for useComponentValue * test(react): refactor useComponentValue to only re-render when entity's value changes * docs(react): add README * fix(react): use typed helper for checking if it's a component update Co-authored-by: alvarius <89248902+alvrs@users.noreply.github.com> * chore(react): add frolic to codeowners * refactor(react): change useComponentValue args ordering * style(react): simplify tsconfig * fix(react): remove unused dep Co-authored-by: alvarius <89248902+alvrs@users.noreply.github.com>
Adds official React MUD package! This will replace the React usages sprinkled into other packages (I'll do a clean up in a breaking follow up).