阅读 794

React 面试必知必会 Day 6

这是我参与更文挑战的第12天,活动详情查看:更文挑战

大家好,我是 @洛竹,一个坚持写作的博主,感恩你的每一个点赞和评论。

本文首发于 洛竹的官方网站

本文翻译自 sudheerj/reactjs-interview-questions

本文同步于公众号洛竹早茶馆,转载请联系作者。

1. 如何在 React 中对 props 进行验证?

当应用程序运行在开发模式时,React 会自动检查我们在组件上设置的所有 props,以确保它们具有正确的类型。如果类型不正确,React 会在控制台生成警告信息。由于对性能的影响,它在生产模式中被禁用。必需 props 是用 isRequired 定义的。

预定义的 props 类型集合。

  1. PropTypes.number
  2. PropTypes.string
  3. PropTypes.array
  4. PropTypes.object
  5. PropTypes.func
  6. PropTypes.node
  7. PropTypes.element
  8. PropTypes.bool
  9. PropTypes.symbol
  10. PropTypes.any

我们可以为 User 组件定义 propTypes,如下所示。

import React from 'react';
import PropTypes from 'prop-types';

class User extends React.Component {
  static propTypes = {
    name: PropTypes.string.isRequired,
    age: PropTypes.number.isRequired,
  };

  render() {
    return (
      <>
        <h1>{`Welcome, ${this.props.name}`}</h1>
        <h2>{`Age, ${this.props.age}`}</h2>
      </>
    );
  }
}
复制代码

注意:在 React v15.5 中,PropTypes 被从 React.PropTypes 移到 prop-types库中。

等效的函数式组件:

import React from 'react';
import PropTypes from 'prop-types';

function User() {
  return (
    <>
      <h1>{`Welcome, ${this.props.name}`}</h1>
      <h2>{`Age, ${this.props.age}`}</h2>
    </>
  );
}

User.propTypes = {
  name: PropTypes.string.isRequired,
  age: PropTypes.number.isRequired,
};
复制代码

2. React 的优势是什么?

以下是 React的 主要优势。

  1. 通过虚拟 DOM 提高应用程序的性能。
  2. JSX 使代码易于阅读和编写。
  3. 它在客户端和服务器端都能进行渲染(SSR)。
  4. 易于与框架(Angular, Backbone)集成,因为它只是一个视图库。
  5. 使用 Jest 等工具容易编写单元和集成测试。

3. React 的局限性是什么?

除了优点之外,React 也有一些限制。

  1. React 只是一个视图库,不是一个完整的框架。
  2. 对于刚接触网络开发的初学者来说,有一个学习曲线。
  3. 将 React 整合到传统的 MVC 框架中需要一些额外的配置。
  4. 代码的复杂性随着内联模板和 JSX 的增加而增加。
  5. 太多的小组件导致了过度工程化或模板化。

4. 什么是 React v16 中的错误边界(Error Boundary)?

错误边界是指在其子组件树的任何地方捕获 JavaScript 错误的组件,记录这些错误,并显示一个后备 UI ,而不是崩溃的组件树。

如果一个类组件定义了一个新的生命周期方法 componentDidCatch(error, info)static getDerivedStateFromError() ,它就成为一个错误边界。

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  componentDidCatch(error, info) {
    // 你也可以把错误记录到一个错误报告服务中去
    logErrorToMyService(error, info)。
  }

  static getDerivedStateFromError(error) {
    // 更新状态,以便下次渲染时显示回退的用户界面。
    return { hasError: true };
  }

  render() {
    if (this.state.hasError) {
      // 你可以渲染任何自定义的回退用户界面
      return <h1>{'Something went wrong.'}</h1>;
    }
    return this.props.children。
  }
}
复制代码

之后把它作为一个普通的组件使用。

<ErrorBoundary>
  <MyWidget />
</ErrorBoundary>
复制代码

5. React v15 中是如何处理错误边界的?

React v15 使用 unstable_handleError 方法为错误边界提供了非常基本的支持。在 React v16 中,它已经被重新命名为 componentDidCatch

6. 静态类型检查的推荐方式是什么?

通常我们使用 PropTypes 库(React.PropTypes 从 React v15.5 开始转移到 prop-types 包)来进行 React 应用中的类型检查。对于大型代码库,建议使用静态类型检查器,如 Flow 或 TypeScript,在编译时进行类型检查并提供自动补全功能。

7. react-dom 包有什么用?

react-dom 包提供了 DOM 特定的方法,可以在你的应用程序的顶层使用。大多数组件不需要使用此模块。这个包的一些方法是:

  1. render()
  2. hydrate()
  3. unmountComponentAtNode()
  4. findDOMNode()
  5. createPortal()

8. react-dom 的 render 方法的目的是什么?

此方法用于将 React 元素渲染到提供的容器中的 DOM 中,并返回对组件的引用。如果 React 元素之前已渲染到容器中,它将对其执行更新,并且仅在必要时更改 DOM 以反映最新更改。

ReactDOM.render(element, container[, callback])
复制代码

如果提供了可选的回调,它将在组件渲染或更新后执行。

9. 什么是 ReactDOMServer?

ReactDOMServer 对象使你能够将组件呈现为静态标记(通常用于节点服务器)。该对象主要用于服务器端渲染(SSR)。以下方法可用于服务器和浏览器环境:

  1. renderToString()
  2. renderToStaticMarkup()

例如,你通常运行基于 Node 的 Web 服务器(如 Express、Hapi 或 Koa),然后调用 renderToString 将根组件渲染为字符串,然后将其作为响应发送。

// 使用 Express
import { renderToString } from 'react-dom/server';
import MyPage from './MyPage';

app.get('/', (req, res) => {
  res.write('<!DOCTYPE html><html><head><title>My Page</title></head><body>');
  res.write('<div id="content">');
  res.write(renderToString(<MyPage />));
  res.write('</div></body></html>');
  res.end();
});
复制代码

10. 如何在 React 中使用 innerHTML?

dangerouslySetInnerHTML 属性是 React 在浏览器 DOM 中使用 innerHTML 的替代品。就像 innerHTML 一样,考虑到跨站点脚本 (XSS) 攻击,使用此属性是有风险的。你只需要传递一个 __html 对象作为键和 HTML 文本作为值。

在这个例子中,MyComponent 使用 dangerouslySetInnerHTML 属性来设置 HTML 标记:

function createMarkup() {
  return { __html: 'First &middot; Second' };
}

function MyComponent() {
  return <div dangerouslySetInnerHTML={createMarkup()} />;
}
复制代码
文章分类
前端
文章标签