前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >React 面试必知必会 Day9

React 面试必知必会 Day9

作者头像
用户1250838
发布2021-07-30 11:10:55
1K0
发布2021-07-30 11:10:55
举报
文章被收录于专栏:洛竹早茶馆洛竹早茶馆

大家好,我是洛竹?,一只住在杭城的木系前端??‍♀️,如果你喜欢我的文章?,可以通过点赞帮我聚集灵力⭐️。

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

1. 什么是切换组件?

切换组件是一个渲染许多组件中的一个组件。我们需要使用对象来将 props 值映射到组件。

例如,一个切换组件可以根据 page props 显示不同的页面。

代码语言:javascript
复制
import HomePage from './HomePage';
import AboutPage from './AboutPage';
import ServicesPage from './ServicesPage';
import ContactPage from './ContactPage';

const PAGES = {
  home: HomePage,
  about: AboutPage,
  services: ServicesPage,
  contact: ContactPage,
};

const Page = props => {
  const Handler = PAGES[props.page] || ContactPage;

  return <Handler {...props} />;
};

// PAGES 对象的键可以在 props 类型中使用,以捕捉开发时间错误。
Page.propTypes = {
  page: PropTypes.oneOf(Object.keys(PAGES)).isRequired,
};

2. 为什么我们需要向 setState() 传递一个函数?

这背后的原因是,setState() 是一个异步操作。出于性能的考虑,React 会对状态变化进行批处理,所以在调用 setState() 后,状态可能不会立即发生变化。这意味着你在调用 setState() 时不应该依赖当前的状态,因为你不能确定这个状态会是什么。解决办法是将一个函数传递给 setState(),并将之前的状态作为参数。通过这样做,你可以避免由于 setState() 的异步性而导致用户在访问时获得旧的状态值的问题。

假设初始计数值为 0。在连续三次递增操作后,该值将只递增一个。

代码语言:javascript
复制
// 假设 this.state.count === 0
this.setState({ count: this.state.count + 1 });
this.setState({ count: this.state.count + 1 });
this.setState({ count: this.state.count + 1 });
// this.state.count === 1,而不是 3

如果我们给 setState() 传递一个函数,计数就会被正确地递增。

代码语言:javascript
复制
this.setState((prevState, props) => ({
  count: prevState.count + props.increment,
}));
// this.state.count === 3

3. 为什么在 setState() 中首选函数而不是对象?

React 可以将多个 setState() 的调用批量化为一次更新,以提高性能。因为 this.propsthis.state 可能被异步更新,你不应该依赖它们的值来计算下一个状态。

这个计数器的例子将无法按预期更新。

代码语言:javascript
复制
// 错误❌
this.setState({
  counter: this.state.counter + this.props.increment,
});

首选的方法是用函数而不是对象调用 setState()。该函数将接收先前的状态作为第一个参数,并将应用更新时的 props 作为第二个参数。

代码语言:javascript
复制
// 正确✅
this.setState((prevState, props) => ({
  counter: prevState.counter + props.increment,
}));

4. React 中的严格模式是什么?

React.StrictMode 是一个有用的组件,用于暴露应用程序中的潜在问题。就像 <Fragment><StrictMode>不会渲染任何额外的 DOM 元素。它为其后代激活了额外的检查和警告。这些检查只适用于开发模式。

代码语言:javascript
复制
import React from 'react';

function ExampleApplication() {
  return (
    <div>
      <Header />
      <React.StrictMode>
        <div>
          <ComponentOne />
          <ComponentTwo />
        </div>
      </React.StrictMode>
      <Footer />
    </div>
  );
}

在上面的例子中,严格模式检查只适用于 <ComponentOne><ComponentTwo> 组件。

5. 为什么 isMounted() 是一个反模式,正确的解决方案是什么?

isMounted() 的主要用例是避免在组件被卸载后调用 setState(),因为它会发出警告。

代码语言:javascript
复制
if (this.isMounted()) {
  this.setState({...})
}

在调用 setState() 之前检查 isMounted() 确实可以消除警告,但这也违背了警告的目的。使用 isMounted() 是一种代码异味,因为你检查的唯一原因是你认为你可能在组件卸载后还持有一个引用。

一个最佳的解决方案是找到在组件卸载后可能调用 setState() 的地方,并修复它们。这种情况通常是由于回调引起的,当一个组件在等待一些数据时,在数据到达之前被卸载。理想情况下,任何回调都应该在 componentWillUnmount() 中取消(在解除挂载之前)。

代码异味 (Code smell):程序开发领域,代码中的任何可能导致深层次问题的症状都可以叫做代码异味。通常,在对代码做简短的反馈迭代时,代码异味会暴露出一些深层次的问题,这里的反馈迭代,是指以一种小范围的、可控的方式重构代码。

6. React 中支持哪些指针事件?

指针事件提供了一个处理所有输入事件的统一方法。在过去,我们有一个鼠标和各自的事件监听器来处理它们,但现在我们有许多设备与拥有鼠标不相关,如带有触摸表面的手机或笔。我们需要记住,这些事件只能在支持 Pointer Events 规范的浏览器中工作。

以下事件类型现在在 React DOM 中可用。

  1. onPointerDown
  2. onPointerMove
  3. onPointerUp
  4. onPointerCancel
  5. onGotPointerCapture
  6. onLostPointerCapture
  7. onPointerEnter
  8. onPointerLeave
  9. onPointerOver
  10. onPointerOut

7. 为什么组件名称要以大写字母开头?

如果你使用 JSX 渲染你的组件,该组件的名称必须以大写字母开头,否则 React 将抛出一个错误,即未识别的标签。这个惯例是因为只有 HTML 元素和 SVG 标签可以以小写字母开头。

代码语言:javascript
复制
class SomeComponent extends Component {
  // 掘金不止,代码不停
}

你可以定义名称以小写字母开头的组件类,但当它被导入时,它应该是大写字母。在这里,小写就可以了。

代码语言:javascript
复制
class myComponent extends Component {
  render() {
    return <div />;
  }
}

export default myComponent;

而当导入另一个文件时,它应该以大写字母开始。

代码语言:javascript
复制
import MyComponent from './MyComponent';

关于 React 组件的命名,有哪些例外情况?

组件名称应以大写字母开头,但这一惯例也有少数例外。带点的小写标签名(属性访问器)仍被认为是有效的组件名。

例如,下面的标签可以被编译成一个有效的组件。

代码语言:javascript
复制
render(){
return (
    <obj.component /> // `React.createElement(obj.component)`
   )
}

8. React v16 中支持自定义 DOM 属性吗?

是的,在过去,React 习惯于忽略未知的 DOM 属性。如果你写的 JSX 有一个 React 不认识的属性,React 会直接跳过它。

例如,让我们看一下下面的属性。

代码语言:javascript
复制
<div mycustomattribute={'something'} />

用 React v15 渲染一个空的 div 到 DOM 上。

代码语言:javascript
复制
<div />

在 React v16 中,任何未知的属性最终都会出现在 DOM 中。

代码语言:javascript
复制
<div mycustomattribute="something" />

这对于提供浏览器特定的非标准属性,尝试新的 DOM API,以及与有主见的第三方库集成是非常有用的。

9. constructor 和 getInitialState 的区别是什么?

当使用 ES6 类时,你应该在构造函数中初始化状态,而当使用 React.createClass() 时,应该在 getInitialState() 方法中初始化状态。

「使用 ES6 类:」

代码语言:javascript
复制
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      /* 初始化状态 */
    };
  }
}

「使用 React.createClass():」

代码语言:javascript
复制
const MyComponent = React.createClass({
  getInitialState() {
    return {
      /* 初始化状态 */
    };
  },
});

「注意:」 React.createClass() 在 React v16 中已被废弃并删除。请使用普通的 JavaScript 类来代替。

10. 你能在不调用 setState 的情况下强制一个组件重新渲染吗?

默认情况下,当你的组件的状态或 props 改变时,你的组件会重新渲染。如果你的 render() 方法依赖于其他数据,你可以通过调用 forceUpdate() 告诉 React 该组件需要重新渲染。

代码语言:javascript
复制
component.forceUpdate(callback);

建议避免使用 forceUpdate(),只在 render() 中读取this.propsthis.state

关注公众号洛竹早茶馆,一个持续分享编程知识的地方。

  • 点赞等于学会,在看等于精通
  • 最后祝大家 2021 学习进步,升职加薪

本文首发于「洛竹的官方网站」,同步于公众号「洛竹早茶馆」和「掘金专栏」。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-07-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 洛竹早茶馆 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 什么是切换组件?
  • 2. 为什么我们需要向 setState() 传递一个函数?
  • 3. 为什么在 setState() 中首选函数而不是对象?
  • 4. React 中的严格模式是什么?
  • 5. 为什么 isMounted() 是一个反模式,正确的解决方案是什么?
  • 6. React 中支持哪些指针事件?
  • 7. 为什么组件名称要以大写字母开头?
    • 关于 React 组件的命名,有哪些例外情况?
    • 8. React v16 中支持自定义 DOM 属性吗?
    • 9. constructor 和 getInitialState 的区别是什么?
    • 10. 你能在不调用 setState 的情况下强制一个组件重新渲染吗?
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档