React软件开发工具包快速入门

云眼About 16 min

React软件开发工具包快速入门

欢迎来到 云眼 功能实验的 React SDK 的快速入门指南。

按照本指南中的步骤创建灰度标帜、推出标帜传递,并使用简单的命令行应用程序运行 A/B 测试。

第一部分:创建示例应用

1. 获取免费帐户

需要一个 云眼 帐户才能遵循本指南。如果没有帐户,可以注册一个免费帐户open in new window。如果已有帐户,请导航到启用了标帜的项目。

2. 获取开发工具包密钥

要在云眼项目中查找开发工具包密钥,请执行以下操作:

  1. 转到“设置”>“主环境”。
  2. 复制并保存主环境的 SDK 密钥

📘 注意

每个环境都有自己的开发工具包密钥。

点击图片放大
sdk_key.png

3. 复制示例代码

要快速试用 SDK,请执行以下操作:

  1. 创建一个新的反应应用程序Create React App

创建React应用程序

npx create-react-app eyeofcloud-react-quickstart cd eyeofcloud-react-quickstart

  1. 安装 云眼 React SDK。可以使用 Yarnopen in new window 轻松做到这一点。

Shell

yarn add @eyeofcloud/react-sdk

React SDK 是开源的,可在 GitHubopen in new window 上使用。

  1. 将以下代码示例复制到文件中。请确保替换为在上一步中找到的 SDK 密钥。src/App.js``<Your_SDK_Key>
import React, { useState } from 'react';
import {
  createInstance,
  EyeofcloudProvider,
  useDecision,
} from '@eyeofcloud/react-sdk';

const eyeofcloudClient = createInstance({ sdkKey:'<YOUR_SDK_KEY>' });

function Pre(props) {
  return <pre style={{ margin: 0 }}>{props.children}</pre>
}

function isClientValid() {
  return eyeofcloudClient.getEyeofcloudConfig() !== null;
}

const userIds = [];
while (userIds.length < 10) {
  // to get rapid demo results, generate an array of random users. Each user always sees the same variation unless you reconfigure the flag rule.
  userIds.push((Math.floor(Math.random() * 999999) + 100000).toString())
}

function App() {
  const [hasOnFlag, setHasOnFlag] = useState(false);
  const [isDone, setIsDone] = useState(false);
  const [isClientReady, setIsClientReady] = useState(null);
  
  eyeofcloudClient.onReady().then(() => {
    setIsDone(true);
    isClientValid() && setIsClientReady(true);
  });
  
  let projectId = '{project_id}';  
  if (isClientValid()) {
    const datafile = JSON.parse(eyeofcloudClient.getEyeofcloudConfig().getDatafile());
    projectId = datafile.projectId;
  }

  return (
    <EyeofcloudProvider
        eyeofcloud={eyeofcloudClient}
        // Generally React SDK runs for one client at a time i.e for one user throughout the lifecycle.
        // You can provide the user Id here once and the SDK will memoize and reuse it throughout the application lifecycle.
        // For this example, we are simulating 10 different users so we will ignore this and pass override User IDs to the useDecision hook for demonstration purpose.
        user={{ id: 'default_user' }}
      >
        <pre>Welcome to our Quickstart Guide!</pre>
        {isClientReady &&
          <>
            {userIds.map((userId) => <Decision key={userId} userId={userId} setHasOnFlag={setHasOnFlag} />)}
            <br />
            {!hasOnFlag && <FlagsOffMessage projectId={projectId} />}
          </>
        }
        {isDone && !isClientReady && <Pre>Eyeofcloud client invalid. Verify in Settings -> Environments that you used the primary environment's SDK key</Pre>}
    </EyeofcloudProvider>
  )
}

function FlagsOffMessage({ projectId }) {  
  const navLink = `https://app.eyeofcloud.com/v2/projects/${projectId}/settings/implementation`;
  return (
    <div>      
      <Pre>Flag was off for everyone. Some reasons could include:</Pre>
      <Pre>1. Your sample size of visitors was too small. Rerun, or increase the iterations in the FOR loop</Pre>
      <Pre>2. By default you have 2 keys for 2 project environments (dev/prod). Verify in Settings>Environments that you used the right key for the environment where your flag is toggled to ON.</Pre>
      <Pre>Check your key at <a href={navLink}>{navLink}</a></Pre>
      <br />
    </div>
    );
}

function Decision({ userId, setHasOnFlag }) {
  // Generally React SDK runs for one client at a time i.e for one user throughout the lifecycle.
  // You can provide the user Id once while wrapping the app in the Provider component and the SDK will memoize and reuse it throughout the application lifecycle.
  // For this example, we are simulating 10 different users so we will ignore this and pass override User IDs to the useDecision hook for demonstration purpose.
  // This override will not be needed for normal react sdk use cases.
  const [decision, clientReady] = useDecision('product_sort', {}, {overrideUserId: userId});

  // Don't render the component if SDK client is not ready yet.
  if (!clientReady) {
    return ''
  }

  const variationKey = decision.variationKey;

  // did decision fail with a critical error?
  if (variationKey === null) {
    console.log(' decision error: ', decision['reasons']);    
  }
  
  if (decision.enabled) {
    setTimeout(() => setHasOnFlag(true));
  }  

  // get a dynamic configuration variable
  // "sort_method" corresponds to a variable key in your Eyeofcloud project
  const sortMethod = decision.variables['sort_method'];
  
  return (    
    <Pre>
      {`\nFlag ${decision.enabled ? 'on' : 'off'}. User number ${userId} saw flag variation: ${variationKey} and got products sorted by: ${sortMethod} config variable as part of flag rule: ${decision.ruleKey}`}
    </Pre>    
  );
}

export default App;

📘 注意

暂时不要运行应用程序,因为仍然需要在 云眼 应用程序中设置标帜。

第二部分:运行应用

完成第一部分后,应用将不执行任何操作。需要在 云眼 应用程序中创建标帜和标帜规则才能启用该应用程序。

1. 创建灰度标帜

通过灰度标帜,可以控制在应用中看到新功能代码的用户。对于本快速入门,假设你正在推出一个重新设计的排序功能来显示产品。
在 云眼 中创建一个名为 product_sort 的标帜,并为其提供一个名为 sort_method 的变量:

  1. 转到标帜>创建标帜
  2. 将标帜键命名为_product_sort_,然后单击**“创建标帜**”,该标帜对应于示例应用中的标帜键。
  3. 转到默认变量,然后单击新建 (+)。
  4. 将变量类型设置为“字符串”。
  5. 将变量命名_为 sort_method_,该名称对应于示例应用中的变量键。
  6. 将变量默认值设置为_字母顺序_,表示旧的排序方法。
创建变量
variable_sort_method.png
  1. 单击右下角的保存以保存变量。
  2. 转到变体**,**然后点击默认的“开启”变体。变体是变量值集合的包装器。
  3. sort_method变量值设置为 popular_first,表示新的排序方法。
创建变体
variation_popular.png
  1. 单击保存

2. 创建标帜传递规则

示例应用_仍_不执行任何操作,因为需要在应用中创建并启用标帜规则。

为_product_sort_标帜的“开启”变体制定有针对性的投放规则。有针对性的交付允许逐步向用户发布灰度标帜,但可以灵活地在遇到错误时将其回滚。

  1. 验证您是否在主环境中(因为您使用的是主环境 SDK 密钥):
验证制定规则的环境
verify_env.png
  1. 点击添加规则,然后选择定向投放
  2. 将流量滑块设置为 50%。这会将标帜传递给在此环境中触发标帜的每个人的 50%。可以随时将product_sort标帜推出或回滚到流量的百分比。
  3. 从“传递”下拉列表中,选择“打开”。
  4. 单击保存
配置目标投放
Screenshot docs.png
  1. 为标帜规则启用标帜:
enable_flag.png

3. 运行示例应用

使用 运行React应用程序。输出应显示在浏览器中,类似于以下内容: yarn start

Flag on. User number 6998 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: targeted_delivery

Flag on. User number 1177 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: targeted_delivery

Flag on. User number 9714 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: targeted_delivery

Flag on. User number 4140 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: targeted_delivery

Flag on. User number 4994 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: targeted_delivery

Flag off. User number 8700 saw flag variation: off and got products sorted by: alphabetical config variable as part of flag rule: default-rollout-208-19963693913

Flag off. User number 9912 saw flag variation: off and got products sorted by: alphabetical config variable as part of flag rule: default-rollout-208-19963693913

Flag on. User number 6560 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: targeted_delivery

Flag on. User number 9252 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: targeted_delivery

Flag on. User number 6582 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: targeted_delivery

📘 注意

在“开启”变体中,您不会获得恰好 50% 的用户流量,因为您正在与如此少量的访问者合作。此外,获得“关闭”标帜的用户没有进入您设置的 50% 流量,因此他们跌落到默认的“关闭”规则(前面的打印语句中的_默认推出_):

4. 工作原理

到目前为止,您:

  • 在 云眼 应用程序中创建了标帜、标帜变量和标帜变体(变量的包装器)
  • 使用 useDecision 挂钩在应用中实现了一个标帜

示例应用中发生了什么?

工作原理:决定向用户显示标帜

React SDK 的使用决策钩子决定了是显示还是隐藏特定用户的灰度标帜。

📘 注意

可以将此挂钩重用于不同的标帜规则 - 无论是为了传递到更多流量,还是运行实验以仅向部分用户展示不同的排序方法。

了解哪种排序方法最能提高销售额后,请将产品排序标帜推广到所有流量,并将该方法设置为最佳值。

在示例应用中:

JavaScript

// "product_sort" corresponds to the flag key you create in the Eyeofcloud app
const [decision] = useDecision('product_sort');

📘 注意

(可选)在创建用户时包括属性(未显示在示例应用中),以便可以定位特定受众。例如:

JavaScript

var attributes = { logged_in: true };

<EyeofcloudProvider
 eyeofcloud={eyeofcloudClient}        
   user={{
   id: 'userId',
   attributes: attributes,
 }}>
   { /*Application Components here*/ }
</EyeofcloudProvider>

工作原理:配置标帜变体

可以使用标帜变量动态配置标帜变体。在示例应用中:

JavaScript

// always returns false until you enable a flag rule in the Eyeofcloud app
if (decision.enabled) 
{
  // "sort_method" corresponds to variable key you define in Eyeofcloud app
 var sortMethod = decision.variables['sort_method'];
 console.log('sort_method: ', sortMethod);
}

对于product_sort标帜,可以配置具有不同sort_method值的变体,按热门产品、相关产品、推广产品等进行排序。可以随时在 云眼 应用程序中为排序方法设置不同的值。

第三部分:运行 A/B 测试

本教程只是指导您完成有针对性的交付,因为它是最简单的标帜规则。但是,在推出灰度标帜传递之前,你通常需要对用户_对_灰度标帜变体的反应进行 A/B 测试。

下表显示了标帜传递和 A/B 测试之间的差异:

目标投放规则

A/B 测试规则

可以将标帜推广到一定比例的一般用户群(或特定受众),或者在遇到错误时回滚。

在投资交付之前,通过 A/B 测试标帜进行实验,这样您就知道要构建什么。跟踪用户在标帜变体中的行为,然后使用 云眼 统计引擎解释实验结果。

现在,A / B测试product_sort标帜的“on”变体。

1. 添加事件跟踪

需要将跟踪事件方法添加到示例应用,以便可以模拟用户事件,然后查看指标。

  1. 在 中删除旧示例代码,然后粘贴以下代码。 src/App.js
  2. 请记得再次更换开发工具包密钥
  3. 不要运行应用程序,因为仍然需要在 云眼 应用程序中设置 A/B 测试。

使用 NPM

import React, { useState } from 'react';
import {
  createInstance,
  EyeofcloudProvider,
  useDecision,
} from '@eyeofcloud/react-sdk';

const eyeofcloudClient = createInstance({ sdkKey: '<YOUR_SDK_KEY>'});

function Pre(props) {
  return <pre style={{ margin: 0 }}>{props.children}</pre>
}

function isClientValid() {
  return eyeofcloudClient.getEyeofcloudConfig() !== null;
}

const userIds = [];
while (userIds.length < 4) {
  // to get rapid demo results, generate an array of random users. Each user always sees the same variation unless you reconfigure the flag rule.
  userIds.push((Math.floor(Math.random() * 999999) + 100000).toString())
}

let userMessages = userIds.reduce((result, userId) => ({ ... result, [userId]: []}), {});
const donePromise = new Promise((resolve) => {
  setTimeout(() => {
    eyeofcloudClient.onReady().then(() => {
      if (isClientValid()) {
        userIds.forEach((userId) => {
          const question = `Pretend that user ${userId} made a purchase?`;
          const trackEvent = window.confirm(question);
          eyeofcloudClient.track('purchase', userId);
          const message = trackEvent
                            ? "Eyeofcloud recorded a purchase in experiment results for user " + userId
                            : "Eyeofcloud didn't record a purchase in experiment results for user " + userId;       
          userMessages[userId].push(`${question} ${trackEvent ? 'Y' : 'N'}`, message);
        });
      }
      resolve();
    });
  }, 500);  
});

function App() {
  const [hasOnFlag, setHasOnFlag] = useState(false);
  const [isDone, setIsDone] = useState(false);
  const [isClientReady, setIsClientReady] = useState(null);

  donePromise.then(() => setIsDone(true));
  eyeofcloudClient.onReady().then(() => { isClientValid() && setIsClientReady(true) });
  
  let projectId = '{project_id}';  
  if (isClientValid()) {
    const datafile = JSON.parse(eyeofcloudClient.getEyeofcloudConfig().getDatafile());
    projectId = datafile.projectId;
  }

  const reportsNavLink = `https://app.eyeofcloud.com/v2/projects/${projectId}/reports`;

  return (
    <EyeofcloudProvider
        eyeofcloud={eyeofcloudClient}
        // Generally React SDK runs for one client at a time i.e for one user throughout the lifecycle.
        // You can provide the user Id here once and the SDK will memoize and reuse it throughout the application lifecycle.
        // For this example, we are simulating 10 different users so we will ignore this and pass override User IDs to the useDecision hook for demonstration purpose.
        user={{ id: 'default_user' }}
      >
        <pre>Welcome to our Quickstart Guide!</pre>
        {isClientReady && <>
            { userIds.map((userId) => (
              <>
                <Decision key={userId} userId={userId} setHasOnFlag={setHasOnFlag} />
                { userMessages[userId].map((message) => <Pre>{message}</Pre>)}
                <br />
              </>
            )) }
            {!hasOnFlag && <FlagsOffMessage projectId={projectId} />}
            {isDone && (
              <>
                <Pre>Done with your mocked A/B test.</Pre>
                <Pre>Check out your report at <a href={reportsNavLink}>{reportsNavLink}</a></Pre>
                <Pre>Be sure to select the environment that corresponds to your SDK key</Pre>
              </>
            )}
          </>
        }
        {isDone && !isClientReady && <Pre>Eyeofcloud client invalid. Verify in Settings -> Environments that you used the primary environment's SDK key</Pre>}
    </EyeofcloudProvider>
  )
}

function FlagsOffMessage({ projectId }) {  
  const navLink = `https://app.eyeofcloud.com/v2/projects/${projectId}/settings/implementation`;
  return (
    <div>      
      <Pre>Flag was off for everyone. Some reasons could include:</Pre>
      <Pre>1. Your sample size of visitors was too small. Rerun, or increase the iterations in the FOR loop</Pre>
      <Pre>2. By default you have 2 keys for 2 project environments (dev/prod). Verify in Settings>Environments that you used the right key for the environment where your flag is toggled to ON.</Pre>
      <Pre>Check your key at <a href={navLink}>{navLink}</a></Pre>
      <br />
    </div>
    );
}

function Decision({ userId, setHasOnFlag }) {
  // Generally React SDK runs for one client at a time i.e for one user throughout the lifecycle.
  // You can provide the user Id once while wrapping the app in the Provider component and the SDK will memoize and reuse it throughout the application lifecycle.
  // For this example, we are simulating 10 different users so we will ignore this and pass override User IDs to the useDecision hook for demonstration purpose.
  // This override will not be needed for normal react sdk use cases.
  const [decision, clientReady] = useDecision('product_sort', {}, {overrideUserId: userId});

  // Don't render the component if SDK client is not ready yet.
  if (!clientReady) {
    return ''
  }

  const variationKey = decision.variationKey;

  // did decision fail with a critical error?
  if (variationKey === null) {
    console.log(' decision error: ', decision['reasons']);    
  }
  
  if (decision.enabled) {
    setTimeout(() => setHasOnFlag(true));
  }  

  // get a dynamic configuration variable
  // "sort_method" corresponds to a variable key in your Eyeofcloud project
  const sortMethod = decision.variables['sort_method'];
  
  return (    
    <Pre>
      {`Flag ${decision.enabled ? 'on' : 'off'}. User number ${userId} saw flag variation: ${variationKey} and got products sorted by: ${sortMethod} config variable as part of flag rule: ${decision.ruleKey}`}
    </Pre>    
  );
}

export default App;

2. 暂停免费帐户中的其他规则

如果你有免费帐户,则需要在保存 A/B 测试之前暂停之前在本快速入门中创建的目标交付:

  1. 选择包含您计划暂停的目标投放的特定标帜
  1. 选择要暂停的环境目标投放
  2. 单击右上角的禁用规则按钮。

3. 创建 A/B 测试

要在云眼项目中创建和启动实验,请执行以下操作:

  1. 转到旗帜的规则。
  2. 单击“> A/B 测试添加规则”。
创建新的 A/B 测试
创建新的 A/B 测试

4. 添加事件

在实验中,将跟踪用户的相关操作,以衡量用户对灰度标帜变体的反应。需要定义要跟踪的操作:

  1. 单击**“指标**”字段。
  2. 点击创建新活动
点击图片放大
create_new_event.png
  1. 对于事件密钥,输入_购买_并单击创建事件。(您想知道新的排序标帜是否帮助客户确定要购买什么,因此请跟踪用户在新订单中显示产品后是否进行了购买。
2021-03-24 12_27_01-product_sort_ Flags_ Rules_ Development_ Experiment - 云眼.png
  1. 保留默认值(衡量_唯一身份转化_次数_的增加_)。
点击图片放大
2020-11-19_10_13_31-Window.png
  1. 点击添加指标
  2. 将默认的“关闭”变体保留为控件。选择您在上一步中配置的“开”变体:
save_ab_test.png
  1. 单击保存

📘 注意

您不限于两种变体;还可以创建具有多种变体的 A/B/ 测试。例如:

仔细检查标帜以确保它处于开启状态,以便实验可以运行:

点击图片放大
flag_on.png

5. 运行 A/B 测试

使用 运行反应应用程序。输出将显示在浏览器中,类似于以下内容,以及确认框,让开发者选择假装购买或不购买:yarn start

.HTML

Flag on. User number 103512 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: experiment

Flag off. User number 134981 saw flag variation: off and got products sorted by: alphabetical config variable as part of flag rule: experiment

Flag on. User number 254103 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: experiment

Flag on. User number 736927 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: experiment

要求假装购买的确认框类似于以下内容:

Confirmation.png

为每个用户做出选择后,最终输出将类似于以下内容:

.HTML

Welcome to our Quickstart Guide!
Flag on. User number 103512 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: experiment
Pretend that user 103512 made a purchase? N
Eyeofcloud didn't record a purchase in experiment results for user 103512

Flag off. User number 134981 saw flag variation: off and got products sorted by: alphabetical config variable as part of flag rule: experiment
Pretend that user 134981 made a purchase? N
Eyeofcloud didn't record a purchase in experiment results for user 134981

Flag on. User number 254103 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: experiment
Pretend that user 254103 made a purchase? N
Eyeofcloud didn't record a purchase in experiment results for user 254103

Flag on. User number 736927 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: experiment
Pretend that user 736927 made a purchase? N
Eyeofcloud didn't record a purchase in experiment results for user 736927

Done with your mocked A/B test.
Check out your report at https://app.eyeofcloud.com/v2/projects/20130771383/reports
Be sure to select the environment that corresponds to your SDK key

6. 查看 A/B 测试结果

转到“报告”标签以查看实验结果。

choose_report.png

结果应如下所示:

experiment overview.png

📘 注意

  • 在拥有更多用户之前,开发者可能不会看到为标帜变体配置的确切用户流量百分比。
  • 开发者可能不会立即看到用户流量。刷新浏览器以刷新流量。
  • 在有大量访问者(大约 100,000 人)之前,实验结果不会告诉您获胜变体。

7. 工作原理

对于 A/B 测试,需要一种方法来告知 云眼 用户何时在应用中进行了购买,并将应用代码中的此事件映射到您在 云眼 中创建的特定事件。幸运的是,SDK有一种方法!使用 Track Event 方法并传入所创建事件的密钥 ()。在示例应用中:purchase

JavaScript

// Track how users behave when they see a flag variation
// e.g., after your app processed a purchase, let Eyeofcloud know what happened:
eyeofcloudClient.track('purchased');

📘 注意

(可选)向事件添加标签以丰富事件(未显示在示例应用中)。还可以使用收入等备用标签键来跟踪定量结果。例如:

JavaScript

var tags = {
 category: 'shoes',
 revenue: 6432,
};

eyeofcloudClient.track('purchase', null, tags);

目前仅实验规则支持事件跟踪,不支持投放规则。未来变体将支持跟踪交货。

无论哪种方式,在实现标帜时都应包括事件跟踪,因为它可以帮助与第三方分析平台集成,并且在创建 A/B 测试时提供灵活性。

结论

祝贺!您已成功设置并启动了第一个云眼灰度实验。虽然此示例侧重于优化销售,但 云眼 的实验平台可以支持一组开放式的实验用例。

请参阅我们完整的 React SDK 文档,了解更多使用实验优化软件的方法。


Last update:
Contributors: “zhangweixue”,zhangweixue