高阶组件

高阶函数:如果一个函数接受一个或多个函数作为参数或者返回一个函数就可称之为高阶函数

高阶组件:如果一个函数 接受一个或多个组件作为参数并且返回一个组件 就可称之为 高阶组件

react 中的高阶组件

React 中的高阶组件主要有两种形式:属性代理反向继承

属性代理 Proxy

  • 操作 props
  • 抽离 state
  • 通过 ref 访问到组件实例
  • 用其他元素包裹传入的组件 WrappedComponent

反向继承

会发现其属性代理和反向继承的实现有些类似的地方,都是返回一个继承了某个父类的子类,只不过属性代理中继承的是 React.Component,反向继承中继承的是传入的组件 WrappedComponent

反向继承可以用来做什么:

1.操作 state

高阶组件中可以读取、编辑和删除WrappedComponent组件实例中的state。甚至可以增加更多的state项,但是非常不建议这么做因为这可能会导致state难以维护及管理。

function withLogging(WrappedComponent) {    return class extends WrappedComponent {    render() {    return (    <div>;    <h2>;Debugger Component Logging...<h2>;    <p>;state:<p>;    <pre>;{JSON.stringify(this.state, null, 4)}<pre>;    <p>props:<p>;    <pre>{JSON.stringify(this.props, null, 4)}<pre>;    {super.render()}    <div>;    );    }    };
}

2.渲染劫持(Render Highjacking)

条件渲染通过 props.isLoading 这个条件来判断渲染哪个组件。

修改由 render() 输出的 React 元素树

什么是状态提升

使用 react 经常会遇到几个组件需要共用状态数据的情况。这种情况下,我们最好将这部分共享的状态提升至他们最近的父组件当中进行管理。我们来看一下具体如何操作吧。

import React from 'react'
class Child_1 extends React.Component{constructor(props){super(props)}render(){return (<div><h1>{this.props.value+2}</h1></div> )}
}
class Child_2 extends React.Component{constructor(props){super(props)}render(){return (<div><h1>{this.props.value+1}</h1></div> )}
}
class Three extends React.Component {constructor(props){super(props)this.state = {txt:"牛逼"}this.handleChange = this.handleChange.bind(this)}handleChange(e){this.setState({txt:e.target.value})}render(){return (<div><input type="text" value={this.state.txt} onChange={this.handleChange}/><p>{this.state.txt}</p><Child_1 value={this.state.txt}/><Child_2 value={this.state.txt}/></div>)}
}
export default Three

React.Children.map和js的map有什么区别?

JavaScript中的map不会对为null或者undefined的数据进行处理,而React.Children.map中的map可以处理React.Children为null或者undefined的情况。

在构造函数调用 super 并将 props 作为参数传入的作用是啥?

在调用 super() 方法之前,子类构造函数无法使用this引用,ES6 子类也是如此。将 props 参数传递给 super() 调用的主要原因是在子构造函数中能够通过this.props来获取传入的 props
传递 props

class MyComponent extends React.Component {constructor(props) {super(props);console.log(this.props); // { name: 'sudheer',age: 30 }}
}

没传递 props

class MyComponent extends React.Component {constructor(props) {super();console.log(this.props); // undefined// 但是 Props 参数仍然可用console.log(props); // Prints { name: 'sudheer',age: 30 }}render() {// 构造函数外部不受影响console.log(this.props); // { name: 'sudheer',age: 30 }}
}

上面示例揭示了一点。props 的行为只有在构造函数中是不同的,在构造函数之外也是一样的。

Redux 请求中间件如何处理并发

使用redux-Saga redux-saga是一个管理redux应用异步操作的中间件,用于代替 redux-thunk 的。它通过创建 Sagas 将所有异步操作逻辑存放在一个地方进行集中处理,以此将react中的同步操作与异步操作区分开来,以便于后期的管理与维护。 redux-saga如何处理并发:

  • takeEvery

可以让多个 saga 任务并行被 fork 执行。

import {fork,take
} from "redux-saga/effects"const takeEvery = (pattern, saga, ...args) => fork(function*() {while (true) {const action = yield take(pattern)yield fork(saga, ...args.concat(action))}
})
  • takeLatest

takeLatest 不允许多个 saga 任务并行地执行。一旦接收到新的发起的 action,它就会取消前面所有 fork 过的任务(如果这些任务还在执行的话)。
在处理 AJAX 请求的时候,如果只希望获取最后那个请求的响应, takeLatest 就会非常有用。

import {cancel,fork,take
} from "redux-saga/effects"const takeLatest = (pattern, saga, ...args) => fork(function*() {let lastTaskwhile (true) {const action = yield take(pattern)if (lastTask) {yield cancel(lastTask) // 如果任务已经结束,则 cancel 为空操作}lastTask = yield fork(saga, ...args.concat(action))}
})

什么是state

  • 在组件初始化的时候 通过this.state 给组件设置一个初始化的state,第一次render的时候会用state来渲染组件

  • 通过this.setState方法来更新state

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

为何React事件要自己绑定this

在 React源码中,当具体到某一事件处理函数将要调用时,将调用 invokeGuardedCallback方法。

function invokeGuardedCallback(name, func, a) {try {func(a);} catch (x) {if (caughtError === null) {caughtError = x;}}
}

事件处理函数是直接调用的,并没有指定调用的组件,所以不进行手动绑定的情况下直接获取到的 this是不准确的,所以我们需要手动将当前组件绑定到 this上

(组件的)状态(state)和属性(props)之间有何不同

State 是一种数据结构,用于组件挂载时所需数据的默认值。State 可能会随着时间的推移而发生突变,但多数时候是作为用户事件行为的结果。

Props(properties 的简写)则是组件的配置。props 由父组件传递给子组件,并且就子组件而言,props 是不可变的(immutable)。组件不能改变自身的 props,但是可以把其子组件的 props 放在一起(统一管理)。Props 也不仅仅是数据–回调函数也可以通过 props 传递。

为什么 React 元素有一个 $$typeof 属性

目的是为了防止 XSS 攻击。因为 Synbol 无法被序列化,所以 React 可以通过有没有 $$typeof 属性来断出当前的 element 对象是从数据库来的还是自己生成的。

  • 如果没有 $$typeof 这个属性,react 会拒绝处理该元素。
  • 在 React 的古老版本中,下面的写法会出现 XSS 攻击:
// 服务端允许用户存储 JSON
let expectedTextButGotJSON = {type: 'div',props: {dangerouslySetInnerHTML: {__html: '/* 把你想的搁着 */'},},// ...
};
let message = { text: expectedTextButGotJSON };// React 0.13 中有风险
<p>{message.text}
</p>

对React-Fiber的理解,它解决了什么问题?

React V15 在渲染时,会递归比对 VirtualDOM 树,找出需要变动的节点,然后同步更新它们, 一气呵成。这个过程期间, React 会占据浏览器资源,这会导致用户触发的事件得不到响应,并且会导致掉帧,导致用户感觉到卡顿

为了给用户制造一种应用很快的“假象”,不能让一个任务长期霸占着资源。 可以将浏览器的渲染、布局、绘制、资源加载(例如 HTML 解析)、事件响应、脚本执行视作操作系统的“进程”,需要通过某些调度策略合理地分配 CPU 资源,从而提高浏览器的用户响应速率, 同时兼顾任务执行效率。

所以 React 通过Fiber 架构,让这个执行过程变成可被中断。“适时”地让出 CPU 执行权,除了可以让浏览器及时地响应用户的交互,还有其他好处:

  • 分批延时对DOM进行操作,避免一次性操作大量 DOM 节点,可以得到更好的用户体验;
  • 给浏览器一点喘息的机会,它会对代码进行编译优化(JIT)及进行热代码优化,或者对 reflow 进行修正。

核心思想: Fiber 也称协程或者纤程。它和线程并不一样,协程本身是没有并发或者并行能力的(需要配合线程),它只是一种控制流程的让出机制。让出 CPU 的执行权,让 CPU 能在这段时间执行其他的操作。渲染的过程可以被中断,可以将控制权交回浏览器,让位给高优先级的任务,浏览器空闲后再恢复渲染。

如何 React.createElement ?

const element = <h1 className="greeting">Hello, world!</h1>;

上述代码如何使用 React.createElement 来实现:

const element = React.createElement("h1", { className: "greeting" }, "Hello, world!");

在 React 中如何处理事件

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

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

React 的生命周期方法有哪些?

  • componentWillMount:在渲染之前执行,用于根组件中的 App 级配置。

  • componentDidMount:在第一次渲染之后执行,可以在这里做AJAX请求,DOM 的操作或状态更新以及设置事件监听器。

  • componentWillReceiveProps:在初始化render的时候不会执行,它会在组件接受到新的状态(Props)时被触发,一般用于父组件状态更新时子组件的重新渲染

  • shouldComponentUpdate:确定是否更新组件。默认情况下,它返回true。如果确定在 stateprops 更新后组件不需要在重新渲染,则可以返回false,这是一个提高性能的方法。

  • componentWillUpdate:在shouldComponentUpdate返回 true 确定要更新组件之前件之前执行。

  • componentDidUpdate:它主要用于更新DOM以响应propsstate更改。

  • componentWillUnmount:它用于取消任何的网络请求,或删除与组件关联的所有事件监听器。

类组件和函数组件之间的区别是啥?

  • 类组件可以使用其他特性,如状态 state 和生命周期钩子。

  • 当组件只是接收 props 渲染到页面时,就是无状态组件,就属于函数组件,也被称为哑组件或展示组件。
    函数组件和类组件当然是有区别的,而且函数组件的性能比类组件的性能要高,因为类组件使用的时候要实例化,而函数组件直接执行函数取返回结果即可。为了提高性能,尽量使用函数组件。

    区别 函数组件 类组件
    是否有 this 没有
    是否有生命周期 没有
    是否有状态 state 没有

react-redux 的实现原理?

通过 redux 和 react context 配合使用,并借助高阶函数,实现了 react-redux

React-Router怎么设置重定向?

使用<Redirect>组件实现路由的重定向:

<Switch><Redirect from='/users/:id' to='/users/profile/:id'/><Route path='/users/profile/:id' component={Profile}/>
</Switch>

当请求 /users/:id 被重定向去 '/users/profile/:id'

  • 属性 from: string:需要匹配的将要被重定向路径。
  • 属性 to: string:重定向的 URL 字符串
  • 属性 to: object:重定向的 location 对象
  • 属性 push: bool:若为真,重定向操作将会把新地址加入到访问历史记录里面,并且无法回退到前面的页面。

对 React Hook 的理解,它的实现原理是什么

React-Hooks 是 React 团队在 React 组件开发实践中,逐渐认知到的一个改进点,这背后其实涉及对类组件函数组件两种组件形式的思考和侧重。

(1)类组件: 所谓类组件,就是基于 ES6 Class 这种写法,通过继承 React.Component 得来的 React 组件。以下是一个类组件:

class DemoClass extends React.Component {state = {text: ""};componentDidMount() {//...}changeText = (newText) => {this.setState({text: newText});};render() {return (<div className="demoClass"><p>{this.state.text}</p><button onClick={this.changeText}>修改</button></div>);}
}

可以看出,React 类组件内部预置了相当多的“现成的东西”等着我们去调度/定制,state 和生命周期就是这些“现成东西”中的典型。要想得到这些东西,难度也不大,只需要继承一个 React.Component 即可。

当然,这也是类组件的一个不便,它太繁杂了,对于解决许多问题来说,编写一个类组件实在是一个过于复杂的姿势。复杂的姿势必然带来高昂的理解成本,这也是我们所不想看到的。除此之外,由于开发者编写的逻辑在封装后是和组件粘在一起的,这就使得类组件内部的逻辑难以实现拆分和复用。

(2)函数组件:函数组件就是以函数的形态存在的 React 组件。早期并没有 React-Hooks,函数组件内部无法定义和维护 state,因此它还有一个别名叫“无状态组件”。以下是一个函数组件:

function DemoFunction(props) {const { text } = propsreturn (<div className="demoFunction"><p>{`函数组件接收的内容:[${text}]`}</p></div>);
}

相比于类组件,函数组件肉眼可见的特质自然包括轻量、灵活、易于组织和维护、较低的学习成本等。

通过对比,从形态上可以对两种组件做区分,它们之间的区别如下:

  • 类组件需要继承 class,函数组件不需要;
  • 类组件可以访问生命周期方法,函数组件不能;
  • 类组件中可以获取到实例化后的 this,并基于这个 this 做各种各样的事情,而函数组件不可以;
  • 类组件中可以定义并维护 state(状态),而函数组件不可以;

除此之外,还有一些其他的不同。通过上面的区别,我们不能说谁好谁坏,它们各有自己的优势。在 React-Hooks 出现之前,类组件的能力边界明显强于函数组件。

实际上,类组件和函数组件之间,是面向对象和函数式编程这两套不同的设计思想之间的差异。而函数组件更加契合 React 框架的设计理念: React 组件本身的定位就是函数,一个输入数据、输出 UI 的函数。作为开发者,我们编写的是声明式的代码,而 React 框架的主要工作,就是及时地把声明式的代码转换为命令式的 DOM 操作,把数据层面的描述映射到用户可见的 UI 变化中去。这就意味着从原则上来讲,React 的数据应该总是紧紧地和渲染绑定在一起的,而类组件做不到这一点。函数组件就真正地将数据和渲染绑定到了一起。函数组件是一个更加匹配其设计理念、也更有利于逻辑拆分与重用的组件表达形式。

为了能让开发者更好的的去编写函数式组件。于是,React-Hooks 便应运而生。

React-Hooks 是一套能够使函数组件更强大、更灵活的“钩子”。

函数组件比起类组件少了很多东西,比如生命周期、对 state 的管理等。这就给函数组件的使用带来了非常多的局限性,导致我们并不能使用函数这种形式,写出一个真正的全功能的组件。而React-Hooks 的出现,就是为了帮助函数组件补齐这些(相对于类组件来说)缺失的能力。

如果说函数组件是一台轻巧的快艇,那么 React-Hooks 就是一个内容丰富的零部件箱。“重装战舰”所预置的那些设备,这个箱子里基本全都有,同时它还不强制你全都要,而是允许你自由地选择和使用你需要的那些能力,然后将这些能力以 Hook(钩子)的形式“钩”进你的组件里,从而定制出一个最适合你的“专属战舰”。

什么是 React Context?

Context 通过组件树提供了一个传递数据的方法,从而避免了在每一个层级手动的传递 props 属性。

如何用 React构建( build)生产模式?

通常,使用 Webpack的 DefinePlugin方法将 NODE ENV设置为 production。这将剥离 propType验证和额外的警告。除此之外,还可以减少代码,因为 React使用 Uglify的dead-code来消除开发代码和注释,这将大大减少包占用的空间。

校招前端二面常考react面试题(边面边更)相关推荐

  1. 前端常考react面试题(持续更新中)

    react diff 算法 我们知道React会维护两个虚拟DOM,那么是如何来比较,如何来判断,做出最优的解呢?这就用到了diff算法 diff算法的作用 计算出Virtual DOM中真正变化的部 ...

  2. 「 最新大厂常考架构技术面试题 + 详细解答」

    很多没有收到offer的朋友一直在 后台问我,怎么梳理面试要考的知识点.这里必须要和大家再强调一下要准备的7大方面!总结起来包括:JAVA编程语言+数据结构和算法题+计网+操作系统+设计模式+数据库+ ...

  3. 分享10道常考Java面试题及答案

    转载自   分享10道常考Java面试题及答案 Hi,大家好,今天给大家分享10道常考的Java面试题及答案,涉及到Java中的10个方面.每个领域一道题.希望你能有收获. <面向对象>什 ...

  4. 每日一练 | 20道常考Python面试题大总结

    每日一练 如果要对数据分析面试题进行归纳总结,基本可以分为三大类,分别是技术题.逻辑思维题.业务场景题. 本栏目旨在为小伙伴们分享常考/经典的数据分析面试题,大家在学习之余也可以进行自测,巩固学习成果 ...

  5. 阿里前端常考vue面试题汇总

    Vuex中actions和mutations有什么区别 题目分析 mutations和actions是vuex带来的两个独特的概念.新手程序员容易混淆,所以面试官喜欢问. 我们只需记住修改状态只能是m ...

  6. web前端教程分享:常见 React 面试题

    React 中 keys 的作用是什么? Keys 是 React 用于追踪哪些列表中元素被修改.被添加或者被移除的辅助标识. render () {   return (     <ul> ...

  7. 20道常考Python面试题大总结

    一般来说,面试官会根据求职者在简历中填写的技术及相关细节来出面试题.一位拿了大厂技术岗Special Offer的网友分享了他总结的面试经验.当时,面试官根据他在简历中所写的技术,面试题出的范围大致如 ...

  8. 携创教育:自考英语二可以不考吗?与英语四级哪个更难?

    经常有同学请教小编自己英语基础不太好,可不可以不考自考英语二?英语二和英语四级比哪个难?自考英语二在自考的学分里占有很大的比重,小编今天就整理了相关信息,一起来看看吧! 自考英语二可以不考吗? 小编想 ...

  9. 校招前端二面高频面试题合集

    DOCTYPE(⽂档类型) 的作⽤ DOCTYPE是HTML5中一种标准通用标记语言的文档类型声明,它的目的是告诉浏览器(解析器)应该以什么样(html或xhtml)的文档类型定义来解析文档,不同的渲 ...

最新文章

  1. android a z 快速定位,快速集成android实现listview的字母A-Z排序,界面侧边字母索引...
  2. c# SortedList的妙用 (GroupBy)
  3. 实际场景中,云原生存储面临的 7 个挑战
  4. Redis源码剖析(六)事务模块
  5. python 通登录银行_Python3 适合初学者学习的银行账户登录系统实例
  6. java写一个外网访问的接口_Java程序员如何入门?教你写第一个程序
  7. Bokeh 使用Basic Glyphs做图
  8. Android 使用AsyncTask 后监听异步加载完毕的动作
  9. mysql 实时恢复_MySQL实时在线备份恢复方案:Replication+LVM Snapsho
  10. php implicit_flush,php – ob_implicit_flush(),flush(),ob_flush() – 不在远程服务器上工作...
  11. 游戏开发筑基之判断回文数及static(C语言)
  12. 莫烦python sklearn笔记
  13. linux-巴斯勒相机 GigE通信配置步骤
  14. 对微信公众号文章爬取进行分析
  15. matlab里peaks,MATLAB中peaks函數的用法
  16. @Autowired实现的原理
  17. combin14_使用SwiftUI,Combin和Swift Package Manager(SPM)构建复杂的模块化架构
  18. 软件工程实践2017——软件产品案例分析
  19. 车载网络: 常见车载网络
  20. vue2 + tinymce 包含自定义图片上传及视频、音频上传

热门文章

  1. Kong(k8s)部署及使用
  2. [CSS]CSS 的背景
  3. 模电学习笔记 (一) 晶体三极管工作原理
  4. 如何将D3.js的强交互延续到Python中?
  5. python文本相似度分析tf-idf
  6. UiPath常见的变量转换及相关函数整理
  7. “五一”国际劳动节是怎么来的?
  8. 如何成功抵御DOS攻击?给你介绍四种方法
  9. js获取字符串转拼音首字母
  10. 【AD】Altium Designer哪里下载和导入元件库_图文教程