作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
Teimur Gasanov的头像

Teimur Gasanov

Teimur是一位高级前端工程师和React专家,在Klarna和Clubhouse(现为Shortcut)等公司拥有丰富的web开发经验。.

Previously At

Klarna
Share

最有经验的软件工程师利用开发人员工具的强大功能来节省时间并提高生产力. 当调试时间到来时,这些工具的重要性成倍增加, 因为调试可能是软件开发中最困难的方面.

进入React开发人员工具, 一个由Meta支持的浏览器扩展, React的创造者, 全世界有300万人在使用. 我们将研究这个工具如何提升你的 React debugging 技能-检查组件, states, 并且支持跟踪呈现和性能——所有这些都没有浏览器控制台日志记录的麻烦.

如何使用React开发工具

Web developers 必须每天确定应用程序中复杂问题的根本原因. 前端的一种典型方法是使用多个 console.log 语句,并检查浏览器的控制台. 这种方法可以工作,但不是特别有效. 幸运的是,React Developer Tools让事情变得更简单,并允许我们:

  • 参见React组件树.
  • 检查并更新树中任何组件的状态/道具.
  • 跟踪组件渲染的时间.
  • 检测组件被重新渲染的原因.

有了这些特性, 你应该能够优化应用, find bugs, 或者毫不费力地指出其他问题.

安装扩展

首先,按照以下六个步骤将React Developer Tools扩展添加到浏览器中. 我们将重点介绍Chrome浏览器的设置,但您可以按照类似的过程设置您的首选浏览器(例如Chrome).g., Firefox, Edge)如果需要:

  1. Visit Chrome插件页面.
  2. Click on Add to Chrome.
  3. Click on Add extension 在弹出窗口中.
  4. 等待下载完成.
  5. 单击浏览器右上角的扩展(拼图)图标.
  6. 点击引脚图标轻松访问扩展.

Now, 当你访问一个使用React的网站时, 你在步骤6中固定的扩展图标将改变其外观:

四种不同的React徽标. 从左到右, 蓝色黑底标志(制作), 一个带有黑色背景和黄色警告三角形的白色标志(过时的React), 一个没有背景的白色标志(没有React), 还有一个红色背景的白色标志和一个黑色的bug(开发).

从左到右,显示的图标状态用于页面:

扩展启动并运行后,接下来我们将创建一个要调试的应用程序.

创建测试应用程序

The create-react-app 实用工具可以在几秒钟内顺利启动应用程序. 作为先决条件, install Node.js 在你的机器上,然后通过命令行创建你的应用:

NPX创建-react-app -app -调试

该操作可能需要一些时间,因为它需要初始化代码库并安装依赖项. 一旦完成,转到应用程序的根文件夹并启动新的React应用程序:

cd app-to-debug
npm start

编译后,您的应用程序出现在浏览器中:

URL为“localhost:3000”的网页显示了React徽标. 屏幕上有一行文字写着“编辑src/App”.并在其下方有一个Learn React链接.

我们的React Developer Tools扩展图标现在表明我们正在开发环境中工作.

使用React开发工具的实用调试方法

让我们继续学习更多关于实际开发人员工具的知识. 首先,打开开发者控制台(Option + ⌘ + J on Mac or Shift + CTRL + J 在Windows / Linux). 有多个选项卡可用(Elements, Console, etc.). 我们现在需要的是 Components:

在屏幕截图中,左侧显示与之前相同的网页, 还在屏幕右侧显示了开发人员工具. 开发控制台显示Components选项卡的内容.

此时只有一个组件可用. 这是正确的,因为我们的测试应用程序只呈现了一个组件 App (see src/index.js). 单击组件以显示其道具,版本的 react-dom 使用的,和源文件.

跟踪组件状态

让我们从您将经常使用的特性开始:检查/编辑组件的状态. 为了演示此功能,我们将对测试项目进行一些更改. 我们将用一个简单的登录表单替换React占位符主页,该表单包含三个状态块:一个用户名字符串, 密码字符串, 以及一个表示“记住我”设置的布尔值.

In the src folder, remove App.css, App.test.js, and logo.svg, then add a new LoginForm.js file as follows:

从“react”中导入{useState};

const LoginForm = () => {
  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");
  const [memorme, setmemorme] = useState(false);

  return (
    
setUsername(e.currentTarget.value)} /> setPassword(e.currentTarget.value)} />
setRememberMe(!rememberMe)} />
); }; 导出默认LoginForm;

注意组件声明方法. 我们使用命名组件(const LoginForm => …)在开发工具中查看其名称. 匿名组件显示为 Unknown.

LoginForm 组件将是我们的调试目标,所以让我们在内部渲染它 App.js:

导入LoginForm./LoginForm";

const App = () => {
  return ;
};

导出默认App;

返回到浏览器窗口 Components tab open. Now, next to the App 组件,您将看到 LoginForm component. Clicking on LoginForm 将显示我们使用?创建的所有状态项 useState hooks. 因为我们还没有输入任何文本或复选框,所以我们看到两个空字符串和 false:

组件选项卡的屏幕截图, 在左边显示应用组件和它的LoginForm, 右边的LoginForm选项卡上有三个钩子状态.

在用户名和密码字段中输入任何内容,或者单击复选框以查看调试窗口更新中的值:

登录组件的屏幕截图,左侧为“admin”用户名和隐藏密码, 组件选项卡中更新了钩子状态(“admin,”“StrongPassword,和false)在右边.

您可能已经注意到状态变量没有名称. 它们都叫 State. 这是工具的预期行为,因为 useState 只接受值参数("" or false in our example). React对这个状态项的名称一无所知.

A utility called useDebugValue 部分解决了这个问题. 它可以设置自定义钩子的显示名称. 例如,您可以设置显示名称 Password for a custom usePassword hook.

监控组件道具

我们不仅可以监控状态变化,还可以监控组件道具. 我们首先修改 LoginForm:

const LoginForm = ({ defaultUsername, onSubmit }) => {
  const [username, setUsername] = useState(defaultUsername);
  const [password, setPassword] = useState("");
  const [memorme, setmemorme] = useState(false);

  return (
    
// ...

上面的代码将添加一个 defaultUsername 属性在初始加载时填充用户名,并且 onSubmit 属性来控制提交表单操作. 我们还必须在内部设置这些属性的默认值 App:

const App = () => {
  return  {}} />;
};

进行更改后重新加载页面,您将看到控件中的道具 Components tab:

与上面相同的屏幕截图,使用不同的用户名/密码条目(“foo@bar.并在Components选项卡下添加了props (defaultUsername和onSubmit)。.

如果你需要检查组件将如何对不同的状态/道具做出反应, 您可以在不更改任何代码的情况下做到这一点. 单击Components选项卡中的状态/道具值,并设置所需的值.

测量应用程序性能

在这一点上,我们应该注意到跟踪道具和状态是可能的 console.log. 然而,React Developer Tools提供了两个优势:

  • 首先,在扩展项目时,登录到控制台是不现实的. 日志越多,就越难找到所需的内容.
  • 其次,监视组件的状态和属性只是工作的一部分. 如果您遇到应用程序正常工作但速度较慢的情况, React Developer Tools可以识别某些性能问题.

有关应用程序性能的总体概述, React Developer Tools可以突出显示DOM更新. 点击右上角的齿轮图标 Components tab.

您将看到一个带有四个选项卡的弹出窗口. Click on the General 选项卡,并选择 在组件呈现时突出显示更新 check box. 开始输入密码字段,然后您的表单将被绿色/黄色框架包裹起来. 每秒执行的更新越多,帧就越突出显示.

与上面相同的截图,在Components选项卡上出现一个弹出窗口. 它显示四个选项卡(General, Debugging, Components, and Profiler), 并在常规选项卡中显示三个选项:主题, Display density, 和在组件呈现时突出显示更新(这是选中的选项). 登录组件显示一个填满的密码字段,并在黄色框架中高亮显示.

要获得更详细的性能分解,我们将从 Components tab to the Profiler 选项卡(不要忘记取消选中高亮选项).

在Profiler选项卡中,您将在左上角看到一个蓝色圆圈. 这是一个开始分析应用程序的按钮. 只要你点击它,所有的状态/道具更新将被跟踪. 在执行此步骤之前, however, 我们将点击标签右上角的齿轮图标,并检查 记录在分析时呈现每个组件的原因 check box. 它将通过更新的解释扩展分析器的功能.

登录组件的屏幕截图,右边打开了Profiler选项卡和弹出窗口. 分析器被设置为记录每个组件在分析时呈现的原因, 并且“隐藏提交”功能未被激活.

配置现在已经完成,所以让我们继续分析我们的应用程序. 关闭设置叠加,点击蓝色圆圈按钮. 开始输入密码字段,并选择“记住我”框. 然后再次单击圆圈按钮以停止分析并查看结果.

完整配置的屏幕截图, 在左侧显示登录组件, 分析器被激活并在右边输出结果. 结果说明了组件渲染的原因(Hook 2发生了变化),并列出了渲染的时间和速度(以毫秒为单位)。.

在分析结果中,您应该看到项目的逐项更新 LoginForm component. 我们的示例显示了9个更新:8个用于密码字段中的每个字符,1个用于“记住我”复选框. 如果你点击任何更新,你将看到渲染发生原因的解释. 例如,第一个渲染说“钩子2改变了.”

让我们看看第二个钩子 LoginForm component:

const [password, setPassword] = useState("");

我们的结果是有意义的,因为第二个钩子负责 密码状态管理. 如果你点击最后的渲染, 它将显示“钩子3已更改”,因为我们的第三个钩子处理“记住我”状态.

Viewing React useReducer and Context

上面的示例提供了简单场景的一瞥. However, React’s API 包含更复杂的特性,例如 Context and useReducer.

让我们将它们添加到应用程序中. 首先,我们必须添加一个包含上下文的文件. 我们将要创建的上下文将用于登录用户并提供登录操作的信息. We’ll create the AuthenticationContext.js 包含以下内容的文件:

从“react”中导入{useCallback, useContext, useReducer};
从“react”中导入{createContext};

const initialState = {
  loading: false,
  令牌:未定义的,
  错误:未定义的,
};

const AuthenticationContext = createContext({
  ...initialState,
  logIn: () => {},
});

const reducer = (state, action) => {
  switch (action.type) {
    case "LOG_IN":
      return { ...状态,加载:true};
    例“LOG_IN_SUCCESS”:
      return { ...状态,加载:false,令牌:动作.token };
    例“LOG_IN_ERROR”:
      return { ...状态,加载:false,错误:动作.error };
    default:
      return action;
  }
};

const mockAPICall = async (payload) => ({ token: "TOKEN" });

export const AuthenticationContextProvider = ({ children }) => {
  const [state, dispatch] = useReducer(reducer, initialState);

  const logIn = useCallback(async (payload) => {
    try {
      dispatch({type: "LOG_IN"});
      const response = await mockAPICall(payload);
      调度({type: "LOG_IN_SUCCESS", token: response).token });
    } catch (error) {
      dispatch({type: "LOG_IN_ERROR", error});
    }
  }, []);

  return (
    
      {children}
    
  );
};

export const useAuthentication = () => useContext(AuthenticationContext);

这个上下文将提供加载状态、错误、结果(token),以及要执行的动作(logIn)的身份验证逻辑. 从reducer函数中可以看到,初始化登录操作将把加载值设置为 true. The token will be updated if the response is successful; otherwise, an error will be set. 我们不会添加成功状态值,因为该值可以通过 token (如果有令牌,说明操作成功).

要用这些值填充应用程序,我们需要更新我们的 App.js file:

导入{AuthenticationContextProvider}./ AuthenticationContext”;
导入LoginForm./LoginForm";

const App = () => {
  return (
    
      
    
  );
};

导出默认App;

您现在可以重新加载页面,打开 Components 选项卡,查看组件树中的上下文:

左边是显示登录组件的屏幕截图,右边是Components dev选项卡. 组件树现在显示了四个嵌套的组件, 从上到下:App, AuthenticationContextProvider, Context.Provider和LoginForm. AuthenticationContextProvider被选中并显示两个钩子,Reducer和Callback.

添加了两个节点: AuthenticationContextProvider and Context.Provider. 第一个是我们用来包装应用程序的自定义提供程序 App.js file. 它包含一个带有当前状态的reducer钩子. 第二个是上下文表示,显示整个组件树中提供的确切值:

{
  value: {
    错误:未定义的,
    loading: false,
    令牌:未定义的,
    logIn: ƒ () {}
  }
}

确保React Developer Tools可以监控reducer的变化,并显示上下文的实际状态, we’ll adjust the LoginForm.js file to use the logIn action as the onSubmit callback:

从“react”中导入{useCallback, useState};
导入{useAuthentication}./ AuthenticationContext”;

const LoginForm = ({ defaultUsername }) => {
  const {logIn} = useAuthentication();

  const [username, setUsername] = useState(defaultUsername);
  const [password, setPassword] = useState("");
  const [memorme, setmemorme] = useState(false);

  const onSubmit = useCallback(
    async (e) => {
      e.preventDefault ();
      等待logIn({username, password, memorme});
    },
    [用户名,密码,记忆,登录]
  );

  return (
// ...

现在,如果你回到浏览器,点击 Log in,你会看到的 token过去是这样 undefined中有更新的值 Context.Provider’s props.

补充React调试工具

调试React应用程序不会在React Developer Tools中停止. 工程师可以利用多种实用程序及其功能组合来创建满足其需求的完美流程.

你为什么要渲染

第一个值得一提的工具是一流的绩效分析师, why-did-you-render. 它不像React开发者工具那样简单易用, 但是它通过用人类可读的文本解释每个渲染来增强渲染监控, 与状态/道具的差异和如何解决问题的想法.

“why-did-you-render”的截图,显示Child: f被重新渲染是因为props对象发生了变化.

Redux DevTools

Redux是一个著名的状态管理库,被许多React工程师使用, 你可以通过阅读了解更多 我之前的文章. 简而言之,它由两部分组成:动作和状态. Redux DevTools 用户界面是否表示应用程序中触发的操作和随后的状态. 您可以在Medium网页上看到插件的运行情况:

Redux DevTools巡检介质的截图.com page.

简化解决问题的下一个应用程序

React Developer Tools是一个简单但功能强大的工具,可以让你的工作流程更容易解决问题. 根据你的要求, 您可能会受益于其他工具, 但是React Developer Tools应该是你的起点.

使用新的React Developer Tools技能集,您将掌握 调试下一个应用程序 并且可以浏览任何基于react的页面或应用程序,比传统的代码检查快几倍.

Toptal工程博客的编辑团队向 Imam Harir 查看本文中提供的代码示例和其他技术内容.

了解基本知识

  • 什么是React开发者工具?

    React Developer Tools是React JavaScript库的浏览器扩展. 这组工具可以揭示任何React应用程序的内部并监控更改,而无需浏览器记录和调试.

  • React开发者工具的用途是什么?

    它可以显示React组件树, 显示和更新状态/道具, 跟踪渲染时间, 并检测重新渲染的原因.

  • 设置React开发工具困难吗?

    不,设置React Developer工具只需要在浏览器上安装一个扩展.

  • 我可以用这个工具调试上下文和useReducer吗?

    是的,你可以使用React Developer工具来调试Context和useReducer. 它支持React API的每个部分.

聘请Toptal这方面的专家.
Hire Now
Teimur Gasanov的头像
Teimur Gasanov

Located in 比什凯克,Chuy省,吉尔吉斯斯坦

Member since May 1, 2018

About the author

Teimur是一位高级前端工程师和React专家,在Klarna和Clubhouse(现为Shortcut)等公司拥有丰富的web开发经验。.

Toptal作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.

Previously At

Klarna

世界级的文章,每周发一次.

订阅意味着同意我们的 privacy policy

世界级的文章,每周发一次.

订阅意味着同意我们的 privacy policy

Toptal开发者

Join the Toptal® community.