You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Next.js应用中集成Launch Darkly的asyncWithLDProvider

问题

Launch Darkly提供了React项目使用asyncWithLDProvider的示例,但无法集成到Next.js应用中。尝试在_app.tsx里创建Provider包裹整个应用,但asyncWithLDProvider是异步函数,需要await,没法直接适配React生命周期。

官方React示例代码

import { asyncWithLDProvider } from 'launchdarkly-react-client-sdk';

(async () => {
  const LDProvider = await asyncWithLDProvider({
    clientSideID: 'client-side-id-123abc',
    user: {
      "key": "user-key-123abc",
      "name": "Sandy Smith",
      "email": "sandy@example.com"
    },
    options: { /* ... */ }
  });

  render(
    <LDProvider>
      <YourApp />
    </LDProvider>,
    document.getElementById('reactDiv'),
  );
})();

我的尝试代码

const App = ({ Component }) = {
    // 不知如何让该异步函数适配React生命周期
    const LDProvider = await asyncWithLDProvider({
      clientSideID: 'client-side-id-123abc',
    });

    return (
        <LDProvider>
            <Component />
        </LDProvider>
    )
}

当前_app.tsx代码

import { Next, Page } from '@my/types';
import NextHead from 'next/head';
import { QueryClient, QueryClientProvider } from 'react-query';

const App = ({
  Component,
  pageProps: { session, ...restProps },
}: Next.AppPropsWithLayout) => {
  const { pathname } = useRouter();
  const { description, title } = Page.getMetadata(pathname, ROUTES);

  const getLayout = Component.getLayout ?? ((page) => page);
  const WithRedirectShell = withRedirect(Shell);

  const queryClient = new QueryClient();

  const [colorScheme, setColorScheme] = useLocalStorage<ColorScheme>({
    key: 'mantine-color-scheme',
    defaultValue: 'light',
    getInitialValueInEffect: true,
  });

  const toggleColorScheme = (value?: ColorScheme) =>
    setColorScheme(value || (colorScheme === 'dark' ? 'light' : 'dark'));

  useHotkeys([['mod+J', () => toggleColorScheme()]]);

  return (
    <ColorSchemeProvider
      colorScheme={colorScheme}
      toggleColorScheme={toggleColorScheme}
    >
      <MantineProvider
        withGlobalStyles
        withNormalizeCSS
        theme={{ colorScheme, ...theme }}
      >
        <NotificationsProvider position='top-center' zIndex={2077} limit={5}>
          <SessionProvider session={session}>
            <QueryClientProvider client={queryClient}>
              <NextHead>
                <Head description={description} title={title} />
              </NextHead>
              <WithRedirectShell header={<Header />}>
                {getLayout(<Component {...restProps} />)}
              </WithRedirectShell>
            </QueryClientProvider>
          </SessionProvider>
        </NotificationsProvider>
      </MantineProvider>
    </ColorSchemeProvider>
  );
};

export default App;

当前index.tsx代码

import { Next } from "@my/types";

const Home: Next.Page = () => null;

export default Home;

解决方案

在Next.js的_app.tsx中,可通过React的useState和useEffect钩子处理异步获取LaunchDarkly Provider的逻辑,同时添加加载状态避免渲染错误。

步骤1:引入依赖并添加状态

先导入所需依赖和React钩子:

import { useState, useEffect } from 'react';
import { asyncWithLDProvider } from 'launchdarkly-react-client-sdk';

在组件内部添加状态存储Provider和加载状态:

const App = ({
  Component,
  pageProps: { session, ...restProps },
}: Next.AppPropsWithLayout) => {
  // 新增状态
  const [LDProvider, setLDProvider] = useState<any>(null);
  const [isLoading, setIsLoading] = useState(true);

  // ... 原有其他状态与逻辑

步骤2:异步初始化Provider

用useEffect调用asyncWithLDProvider,获取Provider后更新状态:

useEffect(() => {
  const initLDProvider = async () => {
    try {
      const provider = await asyncWithLDProvider({
        clientSideID: '你的客户端ID', // 替换为实际LaunchDarkly客户端ID
        user: {
          key: session?.user?.id || 'anonymous-user', // 根据会话设置用户标识
          // 可添加name、email等额外用户属性
        },
        options: {
          // 可选配置,如标志加载超时时间
        }
      });
      setLDProvider(provider);
    } catch (error) {
      console.error('LaunchDarkly Provider初始化失败:', error);
    } finally {
      setIsLoading(false);
    }
  };

  initLDProvider();
}, [session]); // 依赖session,用户会话变化时重新初始化

步骤3:处理加载状态并渲染Provider

在返回的JSX中先判断加载状态,完成后用LDProvider包裹整个应用:

// 加载中显示占位符(可替换为自定义加载组件)
if (isLoading) {
  return <div>加载中...</div>;
}

// 确保Provider存在后渲染
if (!LDProvider) {
  return <div>LaunchDarkly初始化失败</div>;
}

return (
  <ColorSchemeProvider
    colorScheme={colorScheme}
    toggleColorScheme={toggleColorScheme}
  >
    <MantineProvider
      withGlobalStyles
      withNormalizeCSS
      theme={{ colorScheme, ...theme }}
    >
      <NotificationsProvider position='top-center' zIndex={2077} limit={5}>
        <SessionProvider session={session}>
          <QueryClientProvider client={queryClient}>
            {/* 用LDProvider包裹应用 */}
            <LDProvider>
              <NextHead>
                <Head description={description} title={title} />
              </NextHead>
              <WithRedirectShell header={<Header />}>
                {getLayout(<Component {...restProps} />)}
              </WithRedirectShell>
            </LDProvider>
          </QueryClientProvider>
        </SessionProvider>
      </NotificationsProvider>
    </MantineProvider>
  </ColorSchemeProvider>
);

额外说明

  • 用户标识:若应用有登录系统,建议用用户唯一ID作为user.key;匿名用户可生成随机ID存储在localStorage,避免每次刷新重复初始化。
  • 错误处理:添加try/catch捕获初始化失败情况,防止应用崩溃。
  • Next.js 13+ App Router:逻辑类似,但需在layout.tsx中结合useEffect或Suspense(注意客户端组件使用Suspense的限制)。

内容的提问来源于stack exchange,提问作者daniel blythe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 11:24:58