写点什么

react 面试题合集

作者:beifeng1996
  • 2022-12-12
    浙江
  • 本文字数:4270 字

    阅读完需:约 14 分钟

何为 redux

Redux 的基本思想是整个应用的 state 保持在一个单一的 store 中。store 就是一个简单的 javascript 对象,而改变应用 state 的唯一方式是在应用中触发 actions,然后为这些 actions 编写 reducers 来修改 state。整个 state 转化是在 reducers 中完成,并且不应该有任何副作用。

与 ES5 相比,React 的 ES6 语法有何不同

以下语法是 ES5 与 ES6 中的区别:


  1. require 与 import


// ES5var React = require('react');
// ES6import React from 'react';
复制代码


  1. export 与 exports


// ES5module.exports = Component;
// ES6export default Component;
复制代码


  1. component 和 function


// ES5var MyComponent = React.createClass({    render: function() {        return            <h3>Hello Edureka!</h3>;    }});
// ES6class MyComponent extends React.Component { render() { return <h3>Hello Edureka!</h3>; }}
复制代码


  1. props


// ES5var App = React.createClass({    propTypes: { name: React.PropTypes.string },    render: function() {        return            <h3>Hello, {this.props.name}!</h3>;    }});
// ES6class App extends React.Component { render() { return <h3>Hello, {this.props.name}!</h3>; }}
复制代码


  1. state


// ES5var App = React.createClass({    getInitialState: function() {        return { name: 'world' };    },    render: function() {        return            <h3>Hello, {this.state.name}!</h3>;    }});
// ES6class App extends React.Component { constructor() { super(); this.state = { name: 'world' }; } render() { return <h3>Hello, {this.state.name}!</h3>; }}
复制代码

react-router4 的核心

  • 路由变成了组件

  • 分散到各个页面,不需要配置 比如<link> <route></route>

在 React 中如何处理事件

为了解决跨浏览器的兼容性问题,SyntheticEvent 实例将被传递给你的事件处理函数,SyntheticEvent是 React 跨浏览器的浏览器原生事件包装器,它还拥有和浏览器原生事件相同的接口,包括 stopPropagation()preventDefault()。比较有趣的是,React 实际上并不将事件附加到子节点本身。React 使用单个事件侦听器侦听顶层的所有事件。这对性能有好处,也意味着 React 在更新 DOM 时不需要跟踪事件监听器。

什么情况下使用异步组件

  • 提高页面加载速度,使用reloadable把各个页面分别单独打包,按需加载

react 中这两个生命周期会触发死循环

componentWillUpdate生命周期在shouldComponentUpdate返回 true 后被触发。在这两个生命周期只要视图更新就会触发,因此不能再这两个生命周期中使用 setState。否则会导致死循环


参考 前端进阶面试题详细解答

React 如何区分 Class 组件 和 Function 组件

一般的方式是借助 typeof 和 Function.prototype.toString 来判断当前是不是 class,如下:


function isClass(func) {  return typeof func === 'function'    && /^class\s/.test(Function.prototype.toString.call(func));}
复制代码


但是这个方式有它的局限性,因为如果用了 babel 等转换工具,将 class 写法全部转为 function 写法,上面的判断就会失效。


React 区分 Class 组件 和 Function 组件的方式很巧妙,由于所有的类组件都要继承 React.Component,所以只要判断原型链上是否有 React.Component 就可以了:


AComponent.prototype instanceof React.Component
复制代码

为什么 JSX 中的组件名要以大写字母开头

因为 React 要知道当前渲染的是组件还是 HTML 元素

当调用setState时,React render 是如何工作的?

咱们可以将"render"分为两个步骤:


  1. 虚拟 DOM 渲染:当render方法被调用时,它返回一个新的组件的虚拟 DOM 结构。当调用setState()时,render会被再次调用,因为默认情况下shouldComponentUpdate总是返回true,所以默认情况下 React 是没有优化的。

  2. 原生 DOM 渲染:React 只会在虚拟 DOM 中修改真实 DOM 节点,而且修改的次数非常少——这是很棒的 React 特性,它优化了真实 DOM 的变化,使 React 变得更快。

Hooks 可以取代 render props 和高阶组件吗?

通常,render props和高阶组件仅渲染一个子组件。React 团队认为,Hooks 是服务此用例的更简单方法。这两种模式仍然有一席之地(例如,一个虚拟的 scroller 组件可能有一个 renderItem prop,或者一个可视化的容器组件可能有它自己的 DOM 结构)。但在大多数情况下,Hooks 就足够了,可以帮助减少树中的嵌套。

React 中 keys 的作用是什么?

render () {  return (    <ul>      {this.state.todoItems.map(({item,i}) => {        return <li key={i}>{item}</li>      })}    </ul>  )}
复制代码


在 React Diff 算法中 React 会借助元素的 Key 值来判断该元素是新近创建的还是被移动而来的元素,从而减少不必要的元素重渲染。


##s# 如何避免在 React 重新绑定实例?


有几种常用方法可以避免在 React 中绑定方法:1.将事件处理程序定义为内联箭头函数


class SubmitButton extends React.Component {  constructor(props) {    super(props);    this.state = {      isFormSubmitted: false,    };  }  render() {    return (      <button        onClick={() => {          this.setState({ isFormSubmitted: true });        }}      >        Submit      </button>    );  }}
复制代码


2.使用箭头函数来定义方法:


class SubmitButton extends React.Component {  state = {    isFormSubmitted: false,  };  handleSubmit = () => {    this.setState({      isFormSubmitted: true,    });  };  render() {    return <button onClick={this.handleSubmit}>Submit</button>;  }}
复制代码


3.使用带有 Hooks 的函数组件


const SubmitButton = () => {  const [isFormSubmitted, setIsFormSubmitted] = useState(false);  return (    <button      onClick={() => {        setIsFormSubmitted(true);      }}    >      Submit    </button>  );};
复制代码

setState 到底是异步还是同步?

先给出答案: 有时表现出异步,有时表现出同步。


  • setState 只在合成事件和钩⼦函数中是“异步”的,在原⽣事件和 setTimeout 中都是同步的;

  • setState 的“异步”并不是说内部由异步代码实现,其实本身执⾏的过程和代码都是同步的,只是合成事件和钩⼦函数的调⽤顺序在更新之前,导致在合成事件和钩⼦函数中没法⽴⻢拿到更新后的值,形成了所谓的“异步”,当然可以通过第⼆个参数 setState(partialState, callback)中的 callback 拿到更新后的结果;

  • setState 的批量更新优化也是建⽴在“异步”(合成事件、钩⼦函数)之上的,在原⽣事件和 setTimeout 中不会批量更新,在“异步”中如果对同⼀个值进⾏多次 setState,setState 的批量更新策略会对其进⾏覆盖,取最后⼀次的执⾏,如果是同时 setState 多个不同的值,在更新时会对其进⾏合并批量更新。

React setState 笔试题,下面的代码输出什么

class Example extends React.Component {  constructor() {  super()  this.state = {    val: 0  }}componentDidMount() {  this.setState({ val: this.state.val + 1 })  console.log(this.state.val)  // 第 1 次 log  this.setState({ val: this.state.val + 1 })  console.log(this.state.val)  // 第 2 次 log  setTimeout(() => {    this.setState({ val: this.state.val + 1 })    console.log(this.state.val)    // 第 3 次 log    this.setState({ val: this.state.val + 1 })    console.log(this.state.val)    // 第 4 次 log    }, 0)  }  render() {    return null  }}
// 答:0, 0, 1, 2
复制代码

什么是 React Fiber?

Fiber 是 React 16 中新的协调引擎或重新实现核心算法。它的主要目标是支持虚拟 DOM 的增量渲染。React Fiber 的目标是提高其在动画、布局、手势、暂停、中止或重用等方面的适用性,并为不同类型的更新分配优先级,以及新的并发原语。React Fiber 的目标是增强其在动画、布局和手势等领域的适用性。它的主要特性是增量渲染:能够将渲染工作分割成块,并将其分散到多个帧中。

一般可以用哪些值作为 key

  • 最好使用每一条数据中的唯一标识作为 key,比如:手机号,id 值,身份证号,学号等

  • 也可以用数据的索引值(可能会出现一些问题)

useEffect(fn, []) 和 componentDidMount 有什么差异

useEffect 会捕获 props 和 state。所以即便在回调函数里,你拿到的还是初始的 props 和 state。如果想得到“最新”的值,可以使用 ref。

讲讲什么是 JSX ?

Facebook 第一次发布 React 时,他们还引入了一种新的 JS 方言 JSX,将原始 HTML 模板嵌入到 JS 代码中。JSX 代码本身不能被浏览器读取,必须使用Babelwebpack等工具将其转换为传统的 JS。很多开发人员就能无意识使用 JSX,因为它已经与 React 结合在一直了。


class MyComponent extends React.Component {  render() {    let props = this.props;    return (      <div className="my-component">        <a href={props.url}>{props.name}</a>      </div>    );  }}
复制代码

什么是 React 的 refs?为什么它们很重要

refs 允许你直接访问 DOM 元素或组件实例。为了使用它们,可以向组件添加个 ref 属性。如果该属性的值是一个回调函数,它将接受底层的 DOM 元素或组件的已挂载实例作为其第一个参数。可以在组件中存储它。


export class App extends Component {  showResult() {    console.log(this.input.value);  }  render() {    return (      <div>        <input type="text" ref={(input) => (this.input = input)} />        <button onClick={this.showResult.bind(this)}>展示结果</button>      </div>    );  }}
复制代码


如果该属性值是一个字符串, React 将会在组件实例化对象的 refs 属性中,存储一个同名属性,该属性是对这个 DOM 元素的引用。可以通过原生的 DOM API 操作它。


export class App extends Component {  showResult() {    console.log(this.refs.username.value);  }  render() {    return (      <div>        <input type="text" ref="username" />        <button onClick={this.showResu1t.bind(this)}>展示结果</button>      </div>    );  }}
复制代码

react 性能优化方案

  • 重写shouldComponentUpdate来避免不必要的 dom 操作

  • 使用 production 版本的react.js

  • 使用key来帮助React识别列表中所有子组件的最小变化


用户头像

beifeng1996

关注

还未添加个人签名 2022-09-01 加入

还未添加个人简介

评论

发布
暂无评论
react面试题合集_React_beifeng1996_InfoQ写作社区