Skip to content

Commit

Permalink
fix(react): trigger useComponentValue on deleted records (#1959)
Browse files Browse the repository at this point in the history
Co-authored-by: Kevin Ingersoll <kingersoll@gmail.com>
  • Loading branch information
emersonhsieh and holic committed Nov 30, 2023
1 parent 72df3d3 commit 9ef3f9a
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/tasty-balloons-collect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@latticexyz/react": patch
---

Fixed an issue where `useComponentValue` would not detect a change and re-render if the component value was immediately removed.
4 changes: 2 additions & 2 deletions packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
"clean": "pnpm run clean:js",
"clean:js": "rimraf dist",
"dev": "tsup --watch",
"test": "tsc --noEmit && vitest --run",
"test:ci": "pnpm run test"
"test": "tsc --noEmit && vitest",
"test:ci": "tsc --noEmit && vitest --run"
},
"dependencies": {
"@latticexyz/recs": "workspace:*",
Expand Down
22 changes: 22 additions & 0 deletions packages/react/src/useComponentValue.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ describe("useComponentValue", () => {
removeComponent(Position, entity);
});
expect(result.current).toBe(undefined);

act(() => {
setComponent(Position, entity, { x: 0, y: 0 });
});
expect(result.current).toEqual({ x: 0, y: 0 });
});

it("should re-render only when Position changes for entity", () => {
Expand Down Expand Up @@ -70,6 +75,23 @@ describe("useComponentValue", () => {
expect(result.current).toBe(undefined);
});

it("should re-render when Position is removed", () => {
const entity = createEntity(world, [withValue(Position, { x: 1, y: 1 })]);

const { result } = renderHook(() => useComponentValue(Position, entity));
expect(result.current).toEqual({ x: 1, y: 1 });

act(() => {
removeComponent(Position, entity);
});
expect(result.current).toBe(undefined);

act(() => {
setComponent(Position, entity, { x: 0, y: 0 });
});
expect(result.current).toEqual({ x: 0, y: 0 });
});

it("should return default value when Position is not set", () => {
const entity = createEntity(world);

Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/useComponentValue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export function useComponentValue<S extends Schema>(
setValue(entity != null ? getComponentValue(component, entity) : undefined);
if (entity == null) return;

const queryResult = defineQuery([Has(component)], { runOnInit: false });
const queryResult = defineQuery([Has(component)], { runOnInit: true });
const subscription = queryResult.update$.subscribe((update) => {
if (isComponentUpdate(update, component) && update.entity === entity) {
const [nextValue] = update.value;
Expand Down

0 comments on commit 9ef3f9a

Please sign in to comment.