react面试题(六到七部分)

第六部分:React

1、React 事件绑定原理

理解:react中的事件都是合成事件,不是把每一个dom的事件绑定在dom上,而是把事件统一绑定到document中,触发时通过事件冒泡到document进行触发合成事件,因为是合成事件,所以我们无法去使用e.stopPropagation去阻止,而是使用e.preventDefault去阻止。
1.事件注册:组件更新或者装载时,在给dom增加合成事件时,需要将增加的target传入到document进行判断,给document注册原生事件回调为dispatchEvent(统一的事件分发机制)。

2.事件存储:EventPluginHub负责管理React合成事件的callback,它将callback存储到listennerBank中,另外还存储了负责合成事件的Plugin,Event存储到listennerbank中,每一个元素在listennerBank中会有唯一的key。

3.事件触发执行:点击时冒泡到docunment中,触发注册原生事件的回调dispatchEvent,获取到触发这个事件的最深层元素,事件执行利用react的批处理机制。
案例

<div onClick={this.parentClick} ref={ref => this.parent = ref}>
      <div onClick={this.childClick} ref={ref => this.child = ref}>
          test
      </div>
</div>
点击test后
1.首先获取到this.child
2.遍历此元素的所有父元素,依次对每一级元素进行处理
3.构成合成事件
4.将每一级的合成事件存储在eventQueen事件队列中
5.遍历,是否组织冒泡,是则停止,否则继续
6.释放已经完成的事件

4.合成事件:循环所有类型的eventPlugin,对应每个事件类型,生成不同的事件池,如果是空,则生成新的,有则用之前的,根据唯一key获取到指定的回调函数,再返回带有参数的回调函数。

5.总流程:组件装载/更新 – 新增/删除事件 – eventplugin添加到ListennerBank中监听事件 – 触发事件 – 生成合成事件 – 通过唯一key获取到指定函数 – 执行指定回调函数 – 执行完毕后释放

2、什么是React?

  • React 是 Facebook 在 2011 年开发的前端 JavaScript 库。
  • 它遵循基于组件的方法,有助于构建可重用的UI组件。
  • 它用于开发复杂和交互式的 Web 和移动 UI。
  • 尽管它仅在 2015 年开源,但有一个很大的支持社区。

3、 React有什么特点?

React的主要功能如下:

  1. 它使用**虚拟DOM **而不是真正的DOM。
  2. 它可以用服务器端渲染
  3. 它遵循单向数据流或数据绑定。

4、类组件和函数组件的区别

定义组件有两个要求:

  1. 组件名称必须以大写字母开头
  2. 组件的返回值只能有一个根元素

函数组件

function Welcome (props) {
  return <h1>Welcome {props.name}</h1>
}
ReactDOM.render(<Welcome name='react' />, document.getElementById('root'));
  1. 函数组件接收一个单一的 props 对象并返回了一个React元素

类组件

class Welcome extends React.Component {
  render() {
    return (
      <h1>Welcome { this.props.name }</h1>
    );
  }
}
ReactDOM.render(<Welcome name='react' />, document.getElementById('root'));

  1. 无论是使用函数或是类来声明一个组件,它决不能修改它自己的 props
  2. 所有 React 组件都必须是纯函数,并禁止修改其自身 props
  3. React是单项数据流,父组件改变了属性,那么子组件视图会更新。
  4. 属性 props 是外界传递过来的,状态 state 是组件本身的,状态可以在组件中任意修改
  5. 组件的属性和状态改变都会更新视图。

区别

函数组件和类组件当然是有区别的,而且函数组件的性能比类组件的性能要高,因为类组件使用的时候要实例化,而函数组件直接执行函数取返回结果即可。为了提高性能,尽量使用函数组件。

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

5、请你说说React的路由是什么

1.1、基本用法

单页面得特点:只需要加载一次主页面,通过局部刷新,就可以实现跳转或者切换页面

优点:加载速度快,用户体验比较好

缺点:

- 第一次加载比传统要慢一点
- 不利seo
- 页面相对复杂
- 返回键

1.2安装react-router-dom

cnpm install react-router-dom  

下载到生产环境的依赖中。

在组件中通过对象的解构方式去获取到react-router-dom内置组件,在组件中,按需引入内置组件,在页面中进行使用:

- HashRouter表示一个路由的根容器,将来所有的路由相关的东西,都要包裹在HashRouter里面,而且一个网站中,只需要使用一次HashRouter就好了;
- Route表示一个路由规则,在Route上,有两个比较重要的属性,path,component
- Link表示一个路由的链接

代码示例

render(){``    ``return` `(``      ````        ``
`` ``

这是网站的根目录

`` ``
`` ``首页 `` ``电影 `` ``关于`` ``
`` ``
`` ``
`` ``
`` ``
`` ``
`` ``);`` ``}

当使用HashRouter把APP根组件的元素包裹起来之后,网站就已经启用路由了,在一个HashRouter中,只能有唯一的一个根元素。 在一个网站中,只需要使用唯一的一次就行了。

Route创建的标签,就是路由规则,其中path表示要匹配的路由,component表示要展示的组件。Route具有两种身份:1.它是一个路由匹配规则;2.它是一个占位符,表示将来匹配到的组件都放到这个位置

需要注意的地方

- Route 组件path地址是以/开头 ,配置component属性,是显示的组件,这个属性不可以大写
- Route组件可以单双标签使用,单标签需要/结尾,双标签不可以在中间写入别的东西
- Link to属性的地址也是/开头,Link在页面渲染的是a标签

2.1、路由传值

通过配置路由的地址,在Link跳转时

- Route path路径后面 /:id (key)
- Link to 路径后面 /top/10 (value)

接收传值:

- class类组件,this.props.match.params.属性名
- 函数组件:形参.match.params.属性名

代码示例

render(){``    ``return` `(``      ````        ``
`` ``

这是网站的根目录

`` ``
`` ``电影 `` ``
`` ```` ``
`` ``
`` ``);`` ``}

在Route内置组件中,配置path地址:



在Link内置组件中,配置to属性,进行跳转:

电影

类组件中通过生命周期进行接收,this.props携带路由传递过来的数据:

render(){``    ``console.log(``this``);``    ``return` `(``      ``
`` ``电影--{``this``.props.match.``params``.type}--{``this``.props.match.``params``.id}`` ``
`` ``);`` ``}

代码优化后:

class` `Movie extends React.Component{` `  ``constructor(props){``    ``super();``    ``this``.state = {``      ``routeParams:props.match.``params``    ``}``  ``}` `  ``render(){``    ``console.log(``this``);``    ``return` `(``      ``
`` ``电影--{``this``.state.routeParams.type}--{``this``.state.routeParams.id}`` ``
`` ``);`` ``}``}

函数组件中通过形参接收传递过来的值,props形参,函数组件作为路由组件,props就是传递过来的对象,里面携带着路由传递过来的数据

import React ``from` `'react'` `export ``default` `function home(props) {``  ``return` `(``    ``
`` ``{props.match.``params``.id}`` ``
`` ``)``}

2.2、嵌套路由

嵌套路由:在路由组件中,使用Link, Route,配置子路由,实现跳转,切换;

下面为一级路由,在一级路由Home为路由组件



在Home组件中继续使用Link,Route进行路由的嵌套,需要注意的就是路由地址,前部分为一级路由地址,后面接一个二级路由相应的路径

render() {``  ``return` `(``    ``
`` ``
    `` ``
  • 推荐
  • `` ``
  • 新时代
  • `` ``
  • 动漫
  • `` ``
`` ```` ```` ```` ``
`` ``)``}

2.3、JS实现路由跳转

引入BrowserRouter模块

import {BrowserRouter,HashRouter,Route,Link} ``from` `'react-router-dom'

使用BrowserRouter作为根容器

jump(){``  ``window.location.href = ``"/news"``}` `render(){``  ``return` `(``    ````      ``
`` ``

这是网站的根目录

`` ``
`` ```` ``
`` ```` ``
`` ``
`` ``);``}

在render方法中,写一个按钮,按钮名称为js跳转路由,定义一个onClick方法,箭头函数解决this指向问题,与render同级,定义一个jump方法,在jump方法中执行一句代码进行路由跳转,使用window.location.href = “路由的地址”实现路由跳转。

3、react-router-dom内置组件

首先按需引入,使用什么内置组件,就需要引入

import { BrowserRouter, Link, Route,Redirect,NavLink,Switch } ``from` `'react-router-dom'

3.1、在组件中使用NavLink

NavLink 带有选中activeClassName ,如果路由处于激活状态,显示激活class样式。

在我们之前案例的基础上,找到Link组件,我们已经学到Link组件的作用,可以进行路由的跳转,通过to属性,跳转相应的path地址。

​```html``//``
    `` ``
  • `` ``首页`` ``
  • `` ``
  • `` ``好看视频`` ``
  • ``

将组件中的Link全部换成NavLink组件

```html//

  • "red"` `to=“/home”>首页
  • “red”` `to= "/video">好看视频````````

    我们会发现,之前可以正常进行路由跳转,换成NavLink,还依然可以正常跳转,证明组件得跳转使用NavLink也可以实现,那么问题来了,NavLink有什么用,为什么封装了NavLink,将每一个NavLink加入一个activeClassName属性绑定一个class类样式,这时在触发NavLink时,会触发相应得样式,这样有一个切换效果。

    3.2、在组件中使用Redirect内置组件

    Redirect 重定向 具备to属性,可以直接跳转到指定路由。

    在render方法中,使用内置组件,Redirect内置组件使用to属性,当执行到内置标签是,会进行to跳转路由,to后面接的地址是什么,就可以匹配到相应得路由组件。

    ​```html``//``
    
    

    6、列出React的一些主要优点。

    React的一些主要优点是:

    1. 它提高了应用的性能
    2. 可以方便地在客户端和服务器端使用
    3. 由于 JSX,代码的可读性很好
    4. React 很容易与 Meteor,Angular 等其他框架集成
    5. 使用React,编写UI测试用例变得非常容易

    7、React hooks用过吗,为什么要用

    函数组件比起类组件“少”了很多东西,比如生命周期、对 state 的管理等。这就给函数组件的使用带来了非常多的局限性。

    React-Hooks 的出现,就是为了帮助函数组件补齐这些(相对于类组件来说)缺失的能力

    8虚拟DOM的优劣如何

    • 保证性能下限: 框架的虚拟 DOM 需要适配任何上层 API 可能产生的操作,它的一些 DOM 操作的实现必须是普适的,所以它的性能并不是最优的;但是比起粗暴的 DOM 操作性能要好很多,因此框架的虚拟 DOM 至少可以保证在你不需要手动优化的情况下,依然可以提供还不错的性能,即保证性能的下限;
    • 无需手动操作 DOM: 我们不再需要手动去操作 DOM,只需要写好 View-Model 的代码逻辑,框架会根据虚拟 DOM 和 数据双向绑定,帮我们以可预期的方式更新视图,极大提高我们的开发效率;
    • 跨平台: 虚拟 DOM 本质上是 JavaScript 对象,而 DOM 与平台强相关,相比之下虚拟 DOM 可以进行更方便地跨平台操作,例如服务器渲染、weex 开发等等。

    缺点:

    • 无法进行极致优化: 虽然虚拟 DOM + 合理的优化,足以应对绝大部分应用的性能需求,但在一些性能要求极高的应用中虚拟 DOM 无法进行针对性的极致优化。
      首次渲染大量DOM时,由于多了一层虚拟DOM的计算,会比innerHTML插入慢。

    9、React有哪些限制?

    React的限制如下:

    1. React 只是一个库,而不是一个完整的框架
    2. 它的库非常庞大,需要时间来理解
    3. 新手程序员可能很难理解
    4. 编码变得复杂,因为它使用内联模板和 JSX

    10、什么是JSX?

    JSX 是J avaScript XML 的简写。是 React 使用的一种文件,它利用 JavaScript 的表现力和类似 HTML 的模板语法。这使得 HTML 文件非常容易理解。此文件能使应用非常可靠,并能够提高其性能。下面是JSX的一个例子:

    render(){
        return(        
            <div>
                <h1> Hello World from Edureka!!</h1>
            </div>
        );
    }
    

    11、react中不同组件之间如何做到数据交互?

    • 父组件向子组件通信:使用 props
    • 子组件向父组件通信:使用 props 回调
    • 跨级组件间通信:使用 context 对象
    • 非嵌套组件间通信:使用事件订阅

    事实上,在组件间进行通信时,这些通信方式都可以使用,区别只在于使用相应的通信方式的复杂程度和个人喜好,选择最合适的那一个。比如,通过事件订阅模式通信不止可以应用在非嵌套组件间,还可以用于跨级组件间,非嵌套组件间通信也可以使用 context 等。关键是选择最合适的方式。
    当然,自己实现组件间的通信还是太难以管理了,因此出现了很多状态管理工具,如 flux、redux 等,使用这些工具使得组件间的通信更容易追踪和管理。

    12、react中refs的作用是什么?

    • RefsReact 提供给我们的安全访问 DOM元素或者某个组件实例的句柄
    • 可以为元素添加ref属性然后在回调函数中接受该元素在 DOM 树中的句柄,该值会作为回调函数的第一个参数返回

    13、请列举react生命周期函数。

    React 生命周期分为三种状态 1. 初始化 2.更新 3.销毁

    react面试题(六到七部分)_第1张图片

    • 初始化

    1、getDefaultProps()

    设置默认的props,也可以用dufaultProps设置组件的默认属性.

    2、getInitialState()

    在使用es6的class语法时是没有这个钩子函数的,可以直接在constructor中定义this.state。此时可以访问this.props

    3、componentWillMount()

    组件初始化时只调用,以后组件更新不调用,整个生命周期只调用一次,此时可以修改state

    在渲染前调用,在客户端也在服务端。

    4、 render()

    react最重要的步骤,创建虚拟dom,进行diff算法,更新dom树都在此进行。此时就不能更改state了。

    5、componentDidMount()

    组件渲染之后调用,只调用一次。

    在第一次渲染后调用,只在客户端。之后组件已经生成了对应的DOM结构,可以通过**this****.getDOMNode()**来进行访问。

    如果你想和其他JavaScript框架一起使用,可以在这个方法中调用****setTimeout, setInterval或者发送****AJAX请求等操作(防止异步操作阻塞UI)

    • 更新

    6、componentWillReceiveProps(nextProps)

    组件初始化时不调用,组件接受新的props时调用。

    *使用componentWillReceiveProps的时候,不要去向上分发,调用父组件的相关setState方法,否则会成为死循环*

    *在组件接收到一个新的 prop (更新后)时被调用。这个方法在初始化render时不会被调用。*

    7、shouldComponentUpdate(nextProps, nextState)

    react性能优化非常重要的一环。组件接受新的state或者props时调用,我们可以设置在此对比前后两个props和state是否相同,

    如果相同则返回false阻止更新,因为相同的属性状态一定会生成相同的dom树,这样就不需要创造新的dom树和旧的dom树进行diff算法对比,

    节省大量性能,尤其是在dom结构复杂的时候

    返回一个布尔值。在组件接收到新的props或者state时被调用。

    在初始化时或者使用forceUpdate时不被调用。

    可以在你确认不需要更新组件时使用。

    8、componentWillUpdata(nextProps, nextState)

    组件初始化时不调用,只有在组件将要更新时才调用,此时可以修改state

    9、render()

    组件渲染

    10、componentDidUpdate()

    组件初始化时不调用,组件更新完成后调用,此时可以获取dom节点。

    • 卸载

    11、componentWillUnmount()

    组件将要卸载时调用,一些事件监听和定时器需要在此时清除。

    二、组件生命周期的执行次数是什么样子的

    [复制代码](javascript:void(0)

    只执行一次: constructor、componentWillMount、componentDidMount
    
    执行多次:render 、子组件的componentWillReceiveProps、componentWillUpdate、componentDidUpdate
    
    有条件的执行:componentWillUnmount(页面离开,组件销毁时)
    
    不执行的:根组件(ReactDOM.render在DOM上的组件)的componentWillReceiveProps(因为压根没有父组件给传递props)
    
    

    [复制代码](javascript:void(0)

    三、React生命周期执行顺序

    react面试题(六到七部分)_第2张图片

    Mounting中为组件的挂载过程
    componentWillMount组件挂载之前
    render组件的渲染方法
    componentDidMount组件挂载完成执行
    Updation中为组件数据发生变化的过程
    props独有
    componentWillReceiveProps
    触发条件 1. 当一个组件从父组件接收了参数。
    2.如果这个组件第一次被父组件加载的时候不会被执行。
    3.这个组件之前已经存在于父组件中,并且接收的数据发生变动这时此方法才会被触发。
    props和states共有
    shouldComponentUpdata 是否要更新数据?需要一个返回值true继续执行下面的生命周期,false就会终止当前组件数
    componentWillUpdate 组件将要更新
    render组件的重新渲染
    componentDidUpdata 组件完成更新
    Unmounting组件卸载
    componentWillUnmount 组件销毁的时候触发

    14、你了解 Virtual DOM 吗?解释一下它的工作原理。

    Virtual DOM 是一个轻量级的 JavaScript 对象,它最初只是 real DOM 的副本。它是一个节点树,它将元素、它们的属性和内容作为对象及其属性。 React 的渲染函数从 React 组件中创建一个节点树。然后它响应数据模型中的变化来更新该树,该变化是由用户或系统完成的各种动作引起的。

    Virtual DOM 工作过程有三个简单的步骤。

    1. 每当底层数据发生改变时,整个 UI 都将在 Virtual DOM 描述中重新渲染。
      Virtual DOM 1
    2. 然后计算之前 DOM 表示与新表示的之间的差异。
      Virtual DOM 2
    3. 完成计算后,将只用实际更改的内容更新 real DOM。
      Virtual DOM 3

    15、为什么浏览器无法读取JSX?

    浏览器只能处理 JavaScript 对象,而不能读取常规 JavaScript 对象中的 JSX。所以为了使浏览器能够读取 JSX,首先,需要用像 Babel 这样的 JSX 转换器将 JSX 文件转换为 JavaScript 对象,然后再将其传给浏览器。

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

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

    1. require 与 import
    // ES5
    var React = require('react');
     
    // ES6
    import React from 'react';
    12345
    
    1. export 与 exports
    // ES5
    module.exports = Component;
     
    // ES6
    export default Component;
    12345
    
    1. component 和 function
    // ES5
    var MyComponent = React.createClass({
        render: function() {
            return
    			

    Hello Edureka!

    ; } }); // ES6 class MyComponent extends React.Component { render() { return

    Hello Edureka!

    ; } } 123456789101112131415
    1. props
    // ES5
    var App = React.createClass({
        propTypes: { name: React.PropTypes.string },
        render: function() {
            return
    			

    Hello, {this.props.name}!

    ; } }); // ES6 class App extends React.Component { render() { return

    Hello, {this.props.name}!

    ; } } 12345678910111213141516
    1. state
    // ES5
    var App = React.createClass({
        getInitialState: function() {
            return { name: 'world' };
        },
        render: function() {
            return
    	        

    Hello, {this.state.name}!

    ; } }); // ES6 class App extends React.Component { constructor() { super(); this.state = { name: 'world' }; } render() { return

    Hello, {this.state.name}!

    ; } } 12345678910111213141516171819202122

    10. React与Angular有何不同?

    主题 React Angular
    1. 体系结构 只有 MVC 中的 View 完整的 MVC
    2. 渲染 可以在服务器端渲染 客户端渲染
    3. DOM 使用 virtual DOM 使用 real DOM
    4. 数据绑定 单向数据绑定 双向数据绑定
    5. 调试 编译时调试 运行时调试
    6. 作者 Facebook Google

    17、React与Angular有何不同?

    主题 React Angular
    1. 体系结构 只有 MVC 中的 View 完整的 MVC
    2. 渲染 可以在服务器端渲染 客户端渲染
    3. DOM 使用 virtual DOM 使用 real DOM
    4. 数据绑定 单向数据绑定 双向数据绑定
    5. 调试 编译时调试 运行时调试
    6. 作者 Facebook Google

    18、你理解“在React中,一切都是组件”这句话。

    组件是 React 应用 UI 的构建块。这些组件将整个 UI 分成小的独立并可重用的部分。每个组件彼此独立,而不会影响 UI 的其余部分。

    19、解释 React 中 render() 的目的

    每个React组件强制要求必须有一个 render()。它返回一个 React 元素,是原生 DOM 组件的表示。如果需要渲染多个 HTML 元素,则必须将它们组合在一个封闭标记内,例如

    等。此函数必须保持纯净,即必须每次调用时都返回相同的结果。

    20、如何将两个或多个组件嵌入到一个组件中?

    可以通过以下方式将组件嵌入到一个组件中:

    class MyComponent extends React.Component{
        render(){
            return(          
    			

    Hello

    ); } } class Header extends React.Component{ render(){ return

    Header Component

    }; } ReactDOM.render( , document.getElementById('content') );

    21、 React中的状态是什么?它是如何使用的?

    状态是 React 组件的核心,是数据的来源,必须尽可能简单。基本上状态是确定组件呈现和行为的对象。与props 不同,它们是可变的,并创建动态和交互式组件。可以通过 this.state() 访问它们。

    22、React组件中props是什么?

    Props 是 React 中属性的简写。它们是只读组件,必须保持纯,即不可变。它们总是在整个应用中从父组件传递到子组件。子组件永远不能将 prop 送回父组件。这有助于维护单向数据流,通常用于呈现动态生成的数据。

    23、react中组件分为那俩种

    函数式 和类组件

    24、react中区分状态和 props

    条件 State Props
    1. 从父组件中接收初始值 Yes Yes
    2. 父组件可以改变值 No Yes
    3. 在组件中设置默认值 Yes Yes
    4. 在组件的内部变化 Yes No
    5. 设置子组件的初始值 Yes Yes
    6. 在子组件的内部更改 No Yes

    25、如何更新组件的状态?

    可以用 this.setState()更新组件的状态。

    class MyComponent extends React.Component {
        constructor() {
            super();
            this.state = {
                name: 'Maxx',
                id: '101'
            }
        }
        render()
            {
                setTimeout(()=>{this.setState({name:'Jaeha', id:'222'})},2000)
                return (              
    				

    Hello {this.state.name}

    Your Id is {this.state.id}

    ); } } ReactDOM.render( , document.getElementById('content') );

    26、React 中的箭头函数是什么?怎么用?

    箭头函数(=>)是用于编写函数表达式的简短语法。这些函数允许正确绑定组件的上下文,因为在 ES6 中默认下不能使用自动绑定。使用高阶函数时,箭头函数非常有用。

    //General way
    render() {    
        return(
            
        );
    }
    //With Arrow Function
    render() {  
        return(
            this.handleOnChange(e) } />
        );
    }
    

    27、区分有状态和无状态组件。

    有状态组件 无状态组件
    1. 在内存中存储有关组件状态变化的信息 1. 计算组件的内部的状态
    2. 有权改变状态 2. 无权改变状态
    3. 包含过去、现在和未来可能的状态变化情况 3. 不包含过去,现在和未来可能发生的状态变化情况
    4. 接受无状态组件状态变化要求的通知,然后将 props 发送给他们。 4.从有状态组件接收 props 并将其视为回调函数。

    28、React组件生命周期的阶段是什么?

    React 组件的生命周期有三个不同的阶段:

    1. *初始渲染阶段:*这是组件即将开始其生命之旅并进入 DOM 的阶段。
    2. *更新阶段:*一旦组件被添加到 DOM,它只有在 prop 或状态发生变化时才可能更新和重新渲染。这些只发生在这个阶段。
    3. *卸载阶段:*这是组件生命周期的最后阶段,组件被销毁并从 DOM 中删除。

    29、 React中的事件是什么?

    React 中,事件是对鼠标悬停、鼠标单击、按键等特定操作的触发反应。处理这些事件类似于处理 DOM 元素中的事件。但是有一些语法差异,如:

    1. 用驼峰命名法对事件命名而不是仅使用小写字母。
    2. 事件作为函数而不是字符串传递。

    事件参数重包含一组特定于事件的属性。每个事件类型都包含自己的属性和行为,只能通过其事件处理程序访问。

    30 React中的合成事件是什么?

    合成事件是围绕浏览器原生事件充当跨浏览器包装器的对象。它们将不同浏览器的行为合并为一个 API。这样做是为了确保事件在不同浏览器中显示一致的属性。

    31、你对 React 的 refs 有什么了解?

    Refs 是 React 中引用的简写。它是一个有助于存储对特定的 React 元素或组件的引用的属性,它将由组件渲染配置函数返回。用于对 render() 返回的特定元素或组件的引用。当需要进行 DOM 测量或向组件添加方法时,它们会派上用场。

    class ReferenceDemo extends React.Component{
         display() {
             const name = this.inputDemo.value;
             document.getElementById('disp').innerHTML = name;
         }
    render() {
        return(        
              
    Name: this.inputDemo = input} />

    Hello !!!

    ); } }

    32、 列出一些应该使用 Refs 的情况。

    以下是应该使用 refs 的情况:

    • 需要管理焦点、选择文本或媒体播放时
    • 触发式动画
    • 与第三方 DOM 库集成

    33、如何模块化 React 中的代码?

    可以使用 export 和 import 属性来模块化代码。它们有助于在不同的文件中单独编写组件。

    //ChildComponent.jsx
    export default class ChildComponent extends React.Component {
        render() {
            return(           
                  

    This is a child component

    ); } } //ParentComponent.jsx import ChildComponent from './childcomponent.js'; class ParentComponent extends React.Component { render() { return(
    ); } }

    34、如何在 React 中创建表单

    React 表单类似于 HTML 表单。但是在 React 中,状态包含在组件的 state 属性中,并且只能通过 setState() 更新。因此元素不能直接更新它们的状态,它们的提交是由 JavaScript 函数处理的。此函数可以完全访问用户输入到表单的数据。

    handleSubmit(event) {
        alert('A name was submitted: ' + this.state.value);
        event.preventDefault();
    }
     
    render() {
        return (        
            
                
                
            
        );
    }
    

    35、你对受控组件和非受控组件了解多少?

    受控组件 非受控组件
    1. 没有维持自己的状态 1. 保持着自己的状态
    2.数据由父组件控制 2.数据由 DOM 控制
    3. 通过 props 获取当前值,然后通过回调通知更改 3. Refs 用于获取其当前值

    36、什么是高阶组件(HOC)?

    高阶组件是重用组件逻辑的高级方法,是一种源于 React 的组件模式。 HOC 是自定义组件,在它之内包含另一个组件。它们可以接受子组件提供的任何动态,但不会修改或复制其输入组件中的任何行为。你可以认为 HOC 是“纯(Pure)”组件。

    37、你能用HOC做什么?

    HOC可用于许多任务,例如:

    • 代码重用,逻辑和引导抽象
    • 渲染劫持
    • 状态抽象和控制
    • Props 控制

    38、 什么是纯组件?

    纯(Pure) 组件是可以编写的最简单、最快的组件。它们可以替换任何只有 render() 的组件。这些组件增强了代码的简单性和应用的性能。

    39、 React 中 key 的重要性是什么?

    key 用于识别唯一的 Virtual DOM 元素及其驱动 UI 的相应数据。它们通过回收 DOM 中当前所有的元素来帮助 React 优化渲染。这些 key 必须是唯一的数字或字符串,React 只是重新排序元素而不是重新渲染它们。这可以提高应用程序的性能。

    40、MVC框架的主要问题是什么?

    以下是MVC框架的一些主要问题:

    • 对 DOM 操作的代价非常高
    • 程序运行缓慢且效率低下
    • 内存浪费严重
    • 由于循环依赖性,组件模型需要围绕 models 和 views 进行创建

    41、hooks的使用有什么注意事项

    在使用Hooks的过程中,需要注意的两点是:

    • 不要在循环,条件或嵌套函数中调用Hook,必须始终在React函数的顶层使用Hook。这是因为React需要利用调用顺序来正确更新相应的状态,以及调用相应的钩子函数。一旦在循环或条件分支语句中调用Hook,就容易导致调用顺序的不一致性,从而产生难以预料到的后果。
    • 只能在React函数式组件或自定义Hook中使用Hook。

    42、纯函数有什么特点

    • 无状态。线程安全。不需要线程同步。
    • 纯函数相互调用组装起来的函数,还是纯函数。
    • 应用程序或者运行环境(Runtime)可以对纯函数的运算结果进行缓存,运算加快速度。

    43、解释一下 Flux

    flux
    Flux 是一种强制单向数据流的架构模式。它控制派生数据,并使用具有所有数据权限的中心 store 实现多个组件之间的通信。整个应用中的数据更新必须只能在此处进行。 Flux 为应用提供稳定性并减少运行时的错误。

    44、什么是Redux?

    Redux 是当今最热门的前端开发库之一。它是 JavaScript 程序的可预测状态容器,用于整个应用的状态管理。使用 Redux 开发的应用易于测试,可以在不同环境中运行,并显示一致的行为。

    45、Redux遵循的三个原则是什么?

    1. ***单一事实来源:***整个应用的状态存储在单个 store 中的对象/状态树里。单一状态树可以更容易地跟踪随时间的变化,并调试或检查应用程序。
    2. ***状态是只读的:***改变状态的唯一方法是去触发一个动作。动作是描述变化的普通 JS 对象。就像 state 是数据的最小表示一样,该操作是对数据更改的最小表示。
    3. ***使用纯函数进行更改:***为了指定状态树如何通过操作进行转换,你需要纯函数。纯函数是那些返回值仅取决于其参数值的函数。

    Store

    46、你对“单一事实来源”有什么理解?

    Redux 使用 “Store” 将程序的整个状态存储在同一个地方。因此所有组件的状态都存储在 Store 中,并且它们从 Store 本身接收更新。单一状态树可以更容易地跟踪随时间的变化,并调试或检查程序。

    47、列出 Redux 的组件。

    Redux 由以下组件组成:

    1. Action – 这是一个用来描述发生了什么事情的对象。
    2. Reducer – 这是一个确定状态将如何变化的地方。
    3. Store – 整个程序的状态/对象树保存在Store中。
    4. View – 只显示 Store 提供的数据。

    48、数据如何通过 Redux 流动?

    Data Flow in Redux

    49、如何在 Redux 中定义 Action?

    React 中的 Action 必须具有 type 属性,该属性指示正在执行的 ACTION 的类型。必须将它们定义为字符串常量,并且还可以向其添加更多的属性。在 Redux 中,action 被名为 Action Creators 的函数所创建。以下是 Action 和Action Creator 的示例:

    function addTodo(text) {
           return {
                    type: ADD_TODO,    
                     text
        }
    }
    

    50、 解释 Reducer 的作用。

    Reducers 是纯函数,它规定应用程序的状态怎样因响应 ACTION 而改变。Reducers 通过接受先前的状态和 action 来工作,然后它返回一个新的状态。它根据操作的类型确定需要执行哪种更新,然后返回新的值。如果不需要完成任务,它会返回原来的状态。

    51、Store 在 Redux 中的意义是什么?

    Store 是一个 JavaScript 对象,它可以保存程序的状态,并提供一些方法来访问状态、调度操作和注册侦听器。应用程序的整个状态/对象树保存在单一存储中。因此,Redux 非常简单且是可预测的。我们可以将中间件传递到 store 来处理数据,并记录改变存储状态的各种操作。所有操作都通过 reducer 返回一个新状态。

    52、 Redux与Flux有何不同?

    Flux Redux
    1. Store 包含状态和更改逻辑 1. Store 和更改逻辑是分开的
    2. 有多个 Store 2. 只有一个 Store
    3. 所有 Store 都互不影响且是平级的 3. 带有分层 reducer 的单一 Store
    4. 有单一调度器 4. 没有调度器的概念
    5. React 组件订阅 store 5. 容器组件是有联系的
    6. 状态是可变的 6. 状态是不可改变的

    53、Redux 有哪些优点?

    Redux 的优点如下:

    • 结果的可预测性 - 由于总是存在一个真实来源,即 store ,因此不存在如何将当前状态与动作和应用的其他部分同步的问题。
    • 可维护性 - 代码变得更容易维护,具有可预测的结果和严格的结构。
    • 服务器端渲染 - 你只需将服务器上创建的 store 传到客户端即可。这对初始渲染非常有用,并且可以优化应用性能,从而提供更好的用户体验。
    • 开发人员工具 - 从操作到状态更改,开发人员可以实时跟踪应用中发生的所有事情。
    • 社区和生态系统 - Redux 背后有一个巨大的社区,这使得它更加迷人。一个由才华横溢的人组成的大型社区为库的改进做出了贡献,并开发了各种应用。
    • 易于测试 - Redux 的代码主要是小巧、纯粹和独立的功能。这使代码可测试且独立。
    • 组织 - Redux 准确地说明了代码的组织方式,这使得代码在团队使用时更加一致和简单。

    54、什么是React 路由?

    React 路由是一个构建在 React 之上的强大的路由库,它有助于向应用程序添加新的屏幕和流。这使 URL 与网页上显示的数据保持同步。它负责维护标准化的结构和行为,并用于开发单页 Web 应用。 React 路由有一个简单的API。

    55、为什么React Router v4中使用 switch 关键字 ?

    虽然

    * 用于封装 Router 中的多个路由,当你想要仅显示要在多个定义的路线中呈现的单个路线时,可以使用 “switch” 关键字。使用时,* 标记会按顺序将已定义的 URL 与已定义的路由进行匹配。找到第一个匹配项后,它将渲染指定的路径。从而绕过其它路线。

    56、为什么需要 React 中的路由?

    Router 用于定义多个路由,当用户定义特定的 URL 时,如果此 URL 与 Router 内定义的任何 “路由” 的路径匹配,则用户将重定向到该特定路由。所以基本上我们需要在自己的应用中添加一个 Router 库,允许创建多个路由,每个路由都会向我们提供一个独特的视图

    
        
        
        
    
    

    57、列出 React Router 的优点。

    几个优点是:

    1. 就像 React 基于组件一样,在 React Router v4 中,API 是 ‘All About Components’。可以将 Router 可视化为单个根组件(),其中我们将特定的子路由()包起来。
    2. 无需手动设置历史值:在 React Router v4 中,我们要做的就是将路由包装在 组件中。
    3. 包是分开的:共有三个包,分别用于 Web、Native 和 Core。这使我们应用更加紧凑。基于类似的编码风格很容易进行切换。

    58、React Router与常规路由有何不同?

    主题 常规路由 React 路由
    参与的页面 每个视图对应一个新文件 只涉及单个HTML页面
    URL 更改 HTTP 请求被发送到服务器并且接收相应的 HTML 页面 仅更改历史记录属性
    体验 用户实际在每个视图的不同页面切换 用户认为自己正在不同的页面间切换

    59、类组件和函数组件之间有什么区别?

    • 类组件( Class components

      • 无论是使用函数或是类来声明一个组件,它决不能修改它自己的 props
        • 所有 React 组件都必须是纯函数,并禁止修改其自身 props
      • React是单项数据流,父组件改变了属性,那么子组件视图会更新。
        • 属性 props 是外界传递过来的,状态 state 是组件本身的,状态可以在组件中任意修改
        • 组件的属性和状态改变都会更新视图。
    class Welcome extends React.Component {
      render() {
        return (
          

    Welcome { this.props.name }

    ); } } ReactDOM.render(, document.getElementById('root'));
    • 函数组件(functional component)
      • 函数组件接收一个单一的 props 对象并返回了一个React元素

    function Welcome (props) { return

    Welcome {props.name}

    } ReactDOM.render(, document.getElementById(‘root’));

    区别

    函数组件和类组件当然是有区别的,而且函数组件的性能比类组件的性能要高,因为类组件使用的时候要实例化,而函数组件直接执行函数取返回结果即可。为了提高性能,尽量使用函数组件。

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

    60、React中的refs作用是什么?

    Refs 是 React 提供给我们的安全访问 DOM 元素或者某个组件实例的句柄。

    我们可以为元素添加 ref 属性然后在回调函数中接受该元素在 DOM 树中的句柄,该值会作为回调函数的第一个参数返回:

    class UnControlledForm extends Component {
      handleSubmit = () => {
        console.log("Input Value: ", this.input.value)
      }
      render () {
        return (
          
    this.input = input} />
    ) } }

    上述代码中的 input 域包含了一个 ref 属性,该属性声明的回调函数会接收 input 对应的 DOM 元素,我们将其绑定到 this 指针以便在其他的类函数中使用。

    另外值得一提的是,refs 并不是类组件的专属,函数式组件同样能够利用闭包暂存其值:

    function CustomForm ({handleSubmit}) {
      let inputElement
      return (
        
    handleSubmit(inputElement.value)}> inputElement = input} />
    ) }

    61、描述React事件处理。

    为了解决跨浏览器兼容性问题,React中的事件处理程序将传递SyntheticEvent实例,该实例是React跨浏览器本机事件的跨浏览器包装器。这些综合事件具有与您惯用的本机事件相同的界面,除了它们在所有浏览器中的工作方式相同。

    有点有趣的是,React实际上并未将事件附加到子节点本身。React将使用单个事件侦听器在顶层侦听所有事件。这对性能有好处,也意味着React在更新DOM时无需担心跟踪事件监听器。

    63、React 中的 useState() 是什么?

    react hooks的状态钩子

    64、state 和 props有什么区别?

    state 和 props都是普通的JavaScript对象。尽管它们两者都具有影响渲染输出的信息,但它们在组件方面的功能不同。即

    • props 是一个从外部传进组件的参数,主要作为就是从父组件向子组件传递数据,它具有可读性和不变性,只能通过外部组件主动传入新的 props 来重新渲染子组件,否则子组件的 props 以及展现形式不会改变。
    • state 的主要作用是用于组件保存、控制以及修改自己的状态,它只能在 constructor 中初始化,它算是组件的私有属性,不可通过外部访问和修改,只能通过组件内部的 this.setState 来修改,修改 state 属性会导致组件的重新渲染。

    65、如何创建refs?

    Refs 是使用 React.createRef() 方法创建的,并通过 ref 属性添加到 React 元素上。为了在整个组件中使用 refs ,只需将 ref 分配给构造函数中的实例属性

    class MyComponent extends React.Component {
      constructor(props) {
        super(props);
        this.myRef = React.createRef();
      }
      render() {
        return 
    ; } }

    和:

    class UserForm extends Component {
      handleSubmit = () => {
        console.log("Input Value is: ", this.input.value)
      }
      render () {
        return (
          
    this.input = input} /> // Access DOM input in handle submit
    ) } }

    我们还可以借助闭包在功能组件中使用它。

    66、什么是高阶组件?

    67、描述 Flux 与 MVC?

    68、受控组件和非受控组件区别是啥?

    69、这段代码有什么问题吗?

    this.setState((prevState, props) => {
      return {
        streak: prevState.streak + props.count
      }
    })
    

    70、什么是受控组件?

    在HTML当中,像 ,