Skip to content

Commit

Permalink
fix(core): changes in props.id not reflected immediately in `useRes…
Browse files Browse the repository at this point in the history
…ourceParams` return type (#6260) (fixes #6259)
  • Loading branch information
aliemir authored Aug 16, 2024
1 parent 6963e59 commit 05b944a
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 1 deletion.
9 changes: 9 additions & 0 deletions .changeset/honest-peaches-deny.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@refinedev/core": patch
---

fix(core): `useResourceParams` not reflecting `id` prop changes immediately

`useResourceParams` hook was not reflecting the changes in the `id` prop immediately. This was due to the `id` state being set in the `useEffect` hook. This PR fixes the issue by setting the `id` state properly during render rather than after the render is complete.

[Fixes #6259](https://github.com/refinedev/refine/issues/6259)
148 changes: 148 additions & 0 deletions packages/core/src/hooks/use-resource-params/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {

import { useResourceParams } from ".";

import type { BaseKey } from "../../contexts/data/types";

describe("useResourceParams Hook", () => {
describe("with routerProvider", () => {
it("returns undefined when routerProvider doesn't have params", () => {
Expand Down Expand Up @@ -405,6 +407,152 @@ describe("useResourceParams Hook", () => {
);
});
});

it("should reflect changes in id prop immediately", async () => {
const { result, rerender } = renderHook(
({ id }) => useResourceParams({ id }),
{
wrapper: TestWrapper({}),
initialProps: {
id: undefined,
} as { id?: BaseKey },
},
);

expect(result.current).toMatchObject(
expect.objectContaining({
resource: undefined,
id: undefined,
action: undefined,
formAction: "create",
identifier: undefined,
}),
);

rerender({ id: "123" });

expect(result.current).toMatchObject(
expect.objectContaining({
resource: undefined,
id: "123",
action: undefined,
formAction: "create",
identifier: undefined,
}),
);
});

it("should reflect both id prop changes and setId invocations", async () => {
const { result, rerender } = renderHook(
({ id }) => useResourceParams({ id }),
{
wrapper: TestWrapper({}),
initialProps: {
id: undefined,
} as { id?: BaseKey },
},
);

expect(result.current).toMatchObject(
expect.objectContaining({
resource: undefined,
id: undefined,
action: undefined,
formAction: "create",
identifier: undefined,
}),
);

act(() => {
result.current.setId("123");
});

expect(result.current).toMatchObject(
expect.objectContaining({
resource: undefined,
id: "123",
action: undefined,
formAction: "create",
identifier: undefined,
}),
);

rerender({ id: "456" });

expect(result.current).toMatchObject(
expect.objectContaining({
resource: undefined,
id: "456",
action: undefined,
formAction: "create",
identifier: undefined,
}),
);
});

it("should respect value set by setId method", async () => {
const { result, rerender } = renderHook(
({ id }) => useResourceParams({ id }),
{
wrapper: TestWrapper({}),
initialProps: {
id: "123",
} as { id?: BaseKey },
},
);

expect(result.current).toMatchObject(
expect.objectContaining({
id: "123",
}),
);

act(() => {
result.current.setId(undefined);
});

expect(result.current).toMatchObject(
expect.objectContaining({
id: undefined,
}),
);

rerender({ id: "456" });

expect(result.current).toMatchObject(
expect.objectContaining({
id: "456",
}),
);
});

it("should provide id prop in setId setter", async () => {
const { result, rerender } = renderHook(
({ id }) => useResourceParams({ id }),
{
wrapper: TestWrapper({}),
initialProps: {
id: "123",
} as { id?: BaseKey },
},
);

expect(result.current).toMatchObject(
expect.objectContaining({
id: "123",
}),
);

act(() => {
result.current.setId((prev) => (Number(prev) + 1).toString());
});

expect(result.current).toMatchObject(
expect.objectContaining({
id: "124",
}),
);
});
});

describe("with legacyRouterProvider", () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/hooks/use-resource-params/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export function useResourceParams(props?: Props): ResourceParams {

const [id, setId] = React.useState<BaseKey | undefined>(defaultId);

React.useEffect(() => setId(defaultId), [defaultId]);
React.useMemo(() => setId(defaultId), [defaultId]);

const formAction = React.useMemo(() => {
if (!isSameResource && !props?.action) {
Expand Down

0 comments on commit 05b944a

Please sign in to comment.