如何在 React 中为不同用户隐藏功能 A 并显示功能 B

2025-05-24

如何在 React 中为不同用户隐藏功能 A 并显示功能 B

概述

你有没有想过,像 Slack、Netlify、Zoom、Facebook(当然还有 FAANG 的其他成员)这样的公司是如何逐步推出只针对特定用户的新功能的?🤔

别再疑惑了!它是通过功能标志(简称 FF)实现的,我们即将深入探讨这个概念。

功能标记服务的工作方式如下。您可以定义一系列功能(例如,暗黑模式、水平登录布局、设计 2.0),并将其分配给一组用户,并指定是否启用或禁用这些功能的条件。

您可能已经在项目中使用过 FF,但之前没有意识到这一点。您是否在数据库中存储了一些布尔值,用于指示特定用户是否应该拥有某个功能的访问权限?如果是,那么恭喜您——您确实拥有使用功能开关的经验。

DB 中的布尔值在一定程度上表现良好,但进步永无止境。现在,我们拥有了更加灵活且开发者友好的方式来控制功能是否可用。让我们来看看功能开关服务。FF 服务具有以下优势:

  • 您可以在其中定义和管理功能的 UI
  • 用户细分
  • A/B 测试
  • 标志分析
  • 分阶段推出功能
  • 适用于不同语言/框架的 SDK

在本文中,我们将使用Flagsmith——一个开源功能开关和远程配置服务,但您也可以查看LaunchDarkly等商业替代方案。我们的目标是学习如何在 React 中使用功能开关,并使用户更顺畅地启动新功能。

使用 Flagsmith 进行 FF 操作几乎可以在任何地方进行(前端/后端/移动平台)。我们来看看下面的架构:

图表

让我们分析一下这里发生的事情。

1) 用户请求页面
2) 应用程序的某一端(FE/BE)使用用户 uuid 调用 Flagsmith 服务
3) Flagsmith 将收到的 uuid 与该特定用户的可用功能配置进行匹配,并返回相关信息
4) 应用程序根据收到的功能信息生成页面

这绝对不是什么高深的学问。现在就开始练习吧!

GitHub 徽标 旗匠/旗匠

开源功能标记和远程配置服务。可在本地部署或使用我们的托管版本 https://flagsmith.com/

我们的目标

我们想构建一个基本标准的仪表盘应用(抱歉,今天没有待办事项),并设置好授权。我们希望只向选择加入 Beta 版的用户展示某些功能组件。

React、Next.js、Next-Auth 和来自 Tailwind UI 的漂亮的仪表板组件将帮助我们构建它。

4 个固定项目

先决条件

使用 Next.js、React 和 Next-Auth 创建新应用程序或克隆此示例存储库

其他链接

Next.js 入门

开始使用 nextauth

然后在Flagsmith的云版本中创建一个帐户。

1-注册

配置 Flagsmith 环境

配置过程很简单。注册后,创建一个新项目。在 Flagsmith 中,您可以为每个项目定义多个环境,每个环境都有自己的功能/用户/细分和 API 密钥。

2-入职

让我们创建第一个功能,并将其命名为“pinned_projects”。测试版用户将能够固定项目并查看它们。

3-创建功能

下一步我们需要安装flagsmith-react

npm i flagsmith-react
Enter fullscreen mode Exit fullscreen mode

作为第一步,我们将使用FlagsmithProviderFlagsmith API 密钥包装 _app.js 文件,并传递该密钥。该密钥可以从 Flagsmith UI 的“设置”页面获取。FlagsmithProvider 允许使用useFlagsmith钩子函数将状态传递给底层组件。

import Auth from 'components/auth';
import { Provider as SessionProvider } from 'next-auth/client';
import { FlagsmithProvider } from 'flagsmith-react';

import '../styles/globals.css';

export default function MyApp({ Component, pageProps }) {
  return (
    <FlagsmithProvider environmentId={process.env.NEXT_PUBLIC_FLAGSMITH_API_KEY}>
      <SessionProvider session={pageProps.session}>
        {Component.auth ? (
          <Auth>
            <Component {...pageProps} />
          </Auth>
        ) : (
          <Component {...pageProps} />
        )}
      </SessionProvider>
    </FlagsmithProvider>
  );
}
Enter fullscreen mode Exit fullscreen mode

FlagsmithProvider这会初始化 Flagsmith 的 JavaScript 客户端,然后您就可以开始获取 UI 中声明的标志了。但除非我们获取用户特定的标志,否则这没什么意义。为了让 Flagsmith 知道哪些用户请求了标志,我们需要通知identify他。Auth 组件非常适合这个位置,它负责检查用户会话,并在会话过期时将用户重定向到登录页面。

import { useSession, signIn } from 'next-auth/client';
import { useEffect } from 'react';
import { useFlagsmith } from 'flagsmith-react';

export default function Auth({ children }) {
  const { identify, isIdentified, getTrait, setTrait } = useFlagsmith();
  const [session, loading] = useSession();
  const isUser = !!session?.user;

  // Identify user and set email trait if does not exist
  const identifyUser = async (id, email) => {
    await identify(id);
    const hasEmail = !!getTrait('email');
    if (!hasEmail) {
      setTrait('email', email);
    }
  };

  useEffect(() => {
    if (loading) return; // Do nothing while loading
    if (!isUser) signIn(); // If not authenticated, force log in
  }, [isUser, loading]);

  useEffect(() => {
    if (isUser && !isIdentified) {
      // In the example we don't save users in the database so we don't have id that should be used for identification
      // Instead we're going to use email as a trait and id
      identifyUser(session.user.email, session.user.email);
    }
  }, [isIdentified, identify, session, isUser]);

  if (isUser) {
    return children;
  }

  // Session is being fetched, or no user.
  // If no user, useEffect() will redirect.
  return <div />;
}
Enter fullscreen mode Exit fullscreen mode

这里您可以看到我们使用了getTraitsetTrait。特征只是与个人身份关联的键/值对。您可以向用户传递任何其他信息,这些信息稍后可用于细分,例如当前套餐、选择加入测试版功能或新闻通讯等。

让我们创建第一个细分并将其命名为beta_opt_in。前往“细分”→“创建细分”。在这里,您还可以根据特征定义一个表达式,该表达式会将符合该条件的用户添加到细分中。我们可以从一个简单的表达式开始,例如,如果电子邮件已将[pixelpoint.io](http://pixelpoint.io)他们视为已选择加入 Beta 功能。

5段

最后一步是使用向我们的 React 组件添加检查hasFeature("pinned_projects")

const Home = () => {
  const { hasFeature } = useFlagsmith();

  return (
    <>
      <main className="flex-1 relative z-0 overflow-y-auto focus:outline-none">
        <div className="border-b border-gray-200 px-4 py-4 sm:flex sm:items-center sm:justify-between sm:px-6 lg:px-8">
          <HomeHeader />
        </div>
        {hasFeature('pinned_projects') && (
          <div className="px-4 mt-6 sm:px-6 lg:px-8">
            <PinnedProjects items={pinnedProjects} />
          </div>
        )}
        <ProjectsTable items={projects} />
      </main>
    </>
  );
};
Enter fullscreen mode Exit fullscreen mode

干得好!

如果你一直在关注,现在你应该已经完成​​了一个很棒的小项目,它展示了一种现代化的功能标记方法。恭喜🎉

不要犹豫,扩展它或在现有项目中利用这个想法。

PS 进一步阅读

在本文中,我们只是快速浏览了 Feature Flags 并构建了一个简单的示例应用,但 FF 系统的功能远不止于此。请查看:

文章来源:https://dev.to/alex_barashkov/how-to-hide-feature-a-and-show-feature-b-for- Different-users-in-react-j6e
PREV
微服务与单体架构
NEXT
如何在 Docker 容器中调试 Node.js