如何在 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) 应用程序根据收到的功能信息生成页面
这绝对不是什么高深的学问。现在就开始练习吧!
我们的目标
我们想构建一个基本标准的仪表盘应用(抱歉,今天没有待办事项),并设置好授权。我们希望只向选择加入 Beta 版的用户展示某些功能组件。
React、Next.js、Next-Auth 和来自 Tailwind UI 的漂亮的仪表板组件将帮助我们构建它。
先决条件
使用 Next.js、React 和 Next-Auth 创建新应用程序或克隆此示例存储库
其他链接
然后在Flagsmith的云版本中创建一个帐户。
配置 Flagsmith 环境
配置过程很简单。注册后,创建一个新项目。在 Flagsmith 中,您可以为每个项目定义多个环境,每个环境都有自己的功能/用户/细分和 API 密钥。
让我们创建第一个功能,并将其命名为“pinned_projects”。测试版用户将能够固定项目并查看它们。
下一步我们需要安装flagsmith-react
包
npm i flagsmith-react
作为第一步,我们将使用FlagsmithProvider
Flagsmith 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>
);
}
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 />;
}
这里您可以看到我们使用了getTrait
和setTrait
。特征只是与个人身份关联的键/值对。您可以向用户传递任何其他信息,这些信息稍后可用于细分,例如当前套餐、选择加入测试版功能或新闻通讯等。
让我们创建第一个细分并将其命名为beta_opt_in
。前往“细分”→“创建细分”。在这里,您还可以根据特征定义一个表达式,该表达式会将符合该条件的用户添加到细分中。我们可以从一个简单的表达式开始,例如,如果电子邮件已将[pixelpoint.io](http://pixelpoint.io)
他们视为已选择加入 Beta 功能。
最后一步是使用向我们的 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>
</>
);
};
干得好!
如果你一直在关注,现在你应该已经完成了一个很棒的小项目,它展示了一种现代化的功能标记方法。恭喜🎉
不要犹豫,扩展它或在现有项目中利用这个想法。
PS 进一步阅读
在本文中,我们只是快速浏览了 Feature Flags 并构建了一个简单的示例应用,但 FF 系统的功能远不止于此。请查看:
文章来源:https://dev.to/alex_barashkov/how-to-hide-feature-a-and-show-feature-b-for- Different-users-in-react-j6e