diff --git a/.changeset/calm-pandas-refresh-opt-in.md b/.changeset/calm-pandas-refresh-opt-in.md
new file mode 100644
index 000000000..dfa4747dd
--- /dev/null
+++ b/.changeset/calm-pandas-refresh-opt-in.md
@@ -0,0 +1,5 @@
+---
+"@reflag/react-sdk": patch
+---
+
+Prevent `useOptInFlags()` from missing a flag update that finishes between render and event subscription.
diff --git a/packages/react-sdk/src/index.tsx b/packages/react-sdk/src/index.tsx
index 4039c1c53..8272516d9 100644
--- a/packages/react-sdk/src/index.tsx
+++ b/packages/react-sdk/src/index.tsx
@@ -753,6 +753,7 @@ export function useOptInFlags(
useOnEvent("optInFlagsLoadingUpdated", setIsOptInFlagsLoading, client);
useIsomorphicLayoutEffect(() => {
+ setFlags(getOptInFlags());
setIsOptInFlagsLoading(client.getIsLoadingOptInFlags());
}, [client]);
diff --git a/packages/react-sdk/test/usage.test.tsx b/packages/react-sdk/test/usage.test.tsx
index 51084dc7e..f1ab0a192 100644
--- a/packages/react-sdk/test/usage.test.tsx
+++ b/packages/react-sdk/test/usage.test.tsx
@@ -1146,6 +1146,67 @@ describe("opt-in hooks", () => {
unmount();
});
+ test("does not miss opt-in flags updated between render and subscription", async () => {
+ const client = new ReflagClient({
+ publishableKey: "key-opt-in-mount-race",
+ offline: true,
+ });
+ const optInFlag = {
+ key: "optInFlag",
+ name: "Opt-in flag",
+ description: null,
+ isEnabled: false,
+ userOptedIn: false,
+ companyOptedIn: false,
+ isOptedIn: false,
+ };
+ const getOptInFlags = vi
+ .spyOn(client, "getOptInFlags")
+ .mockReturnValueOnce([])
+ .mockReturnValue([optInFlag]);
+
+ const { result, unmount } = renderHook(() => useOptInFlags(), {
+ wrapper: ({ children }) => (
+
+ {children}
+
+ ),
+ });
+
+ expect(result.current).toEqual({ flags: [optInFlag], isLoading: false });
+ expect(getOptInFlags).toHaveBeenCalledTimes(2);
+
+ unmount();
+ await client.stop();
+ });
+
+ test("returns an empty flags array when regular provider initialization fails", async () => {
+ const logger = {
+ debug: vi.fn(),
+ info: vi.fn(),
+ warn: vi.fn(),
+ error: vi.fn(),
+ };
+ const initialize = vi
+ .spyOn(ReflagClient.prototype, "initialize")
+ .mockRejectedValueOnce(new Error("init failed"));
+
+ const { result, unmount } = renderHook(() => useOptInFlags(), {
+ wrapper: ({ children }) => getProvider({ children, logger }),
+ });
+
+ await waitFor(() => {
+ expect(logger.error).toHaveBeenCalledWith(
+ "failed to initialize client",
+ expect.any(Error),
+ );
+ });
+ expect(result.current).toEqual({ flags: [], isLoading: false });
+
+ unmount();
+ initialize.mockRestore();
+ });
+
test("suspends with a regular provider during the initial flags request", async () => {
let resolveResponse!: (response: HttpResponse) => void;
const response = new Promise((resolve) => {