目录
一.说说对 React 的理解?有哪些特性?
前端
1. 什么是React
2. 说说 Real DOM 和 Virtual DOM 的区别?优缺点?
3. 什么是JSX
4. React创建元素的方法?
5. class组件和函数组件区别
6. React 事件绑定的方式
7. 事件处理方法this指向改变
8. React事件处理方法传值
9 React如何获取表单数据
10. React条件渲染方法有哪些
11. React怎么实现列表渲染
12. React中key的作用是什么?
13. React组件样式的定义方式
14. Props校验数据类型
15.受控组件和非受控组件
16. props和state的区别
17.react-roter-dom中V5和V6区别?
18.父传子通信流程
19. 子传父通信的流程
20.非父子组件通信
21.context状态树是怎么运行的?
22.React生命周期分为几个阶段?
23. 简述React的生命周期函数?
24. React旧生命周期有哪些问题?
25. React新生命周期有哪些改变?
26. react的路由几种模式,是什么?
27. react路由常用的组件有哪些?
28. react路由传参的方式有哪些?
29. react路由跳转的方式有哪些?
30. react路由嵌套如何配置?
1.React是用于构建用户界面的javascript库,只提供了ui层面的解决方案
遵循组件设计模式,声明式编程和函数式变成的概念,使得前端应用程序
更加的高效
2.使用虚拟DOM来有效得操作DOM,遵循从高阶组件到低阶组件的
单向数据流,帮助我们将界面分成了各个独立的小块,每一小块
就是一个组件这些组件之间可以组合嵌套,构成整体页面
3.特性:JSX语法,单项数据绑定,虚拟DOM,声明式编程,component
二.说说 Real DOM 和 Virtual DOM 的区别?优缺点?
Real DOM 真实DOM 意思是文档对象模型,,是一个一个结构化文本的抽象;
在页面渲染出来的每一个节点都是一个真实的DOM
虚拟DOM不会进行排版与重绘操作,而真实DOM会频繁的重排和重绘
虚拟DOM的总损耗是"虚拟DOM增删改+真实DOM差异增删改+排版与重绘"真实DOM的
总消耗的是"真实DOM完全增删改+排版与重绘"
真实Dom的优势:易用
缺点:1.效率低,解析速度慢 内存占用量过高
2.性能差,频繁操作真实DOM,易于导致重绘和回流
3.简单方便 如果使用手动操作真实DOM来完成页面,繁琐又容易出错,在大规模应用
下维护起来很困难
4.性能方面,使用Virtual DOM 能够有效避免真实DOM数据频繁更新,减少多次
三.说说React Jsx转换成真实DOM过程?
使用React.createElement或JSX编写React组件,实际上所有的JSX代码最后都会转换成React.reateElement(),
Babel帮助我们完成了这个转换过程
createElement函数对key和ref等特殊的props进行处理,并获取defaultProps对默认props进行赋值,并且对传入的子节点进行处理,最终构建成一个虚拟DOM 对象
ReactDOM.render将生成好的虚拟Dom渲染到指定容器上,才用到了批量处理、事务等机制并且对特定浏览器进行了,性能优化,最终转成真实DOM
四.说说你第mvc和mvvm的理解
MVC:用户对视图层得操作会交给controller,controller完成相对得业务逻辑之后会要求数层去改变数据,
model中数据得改变会会触发view视图层得更新,事单向数据绑定
MVVM:
view视图层和model之间不会建立任何联系,viewModel是建立两者之间得桥梁
view与viewModel之间通过双向数据绑定建立联系 这样当view变化时 会自动更细到viewModel中
vm的理解:视图模型层,model层中的数据往往不能直接跟view中得控制一一对应,所以需要再定义一个数据
对虚拟DOM进行专门对应真实DOM上得控件,而viewMOdel得职责就是把model对象封装成可以显示和接收得页面数据对象
五.说说react中引入css的方式有哪几种?区别?
四种1.组件内部标签使用style编写样式 2.外部引入.css文件 3.引入modeule.css 4.通过css in js
第一种:组件内部直接使用css style编写,能够根据状态修改样式属性,代码多了容易混乱
第二种:组件中引入module.css符合日常编写习惯,但是作用是全局得,样式之间会层叠
第三种:引入module.css文件解决作用于的问题,可以类似于预处理器嵌套、定义、修改、状态
第四种:通过css in js 可以满足大部分场景应用,可以根据各自情况选择合适的方案
六.call、apply、bind的区别?如何实现一个bind
三者都可以改变函数的this 对象指向
三者第一个参数都是this 要指向的对象,如果没有这个参数或参数为undefined或null,则默认指向全局对象window
三者都可以传参,但是apply是数组,而call是参数列表,且apply和ca11是一次性传入参数而bind 可以分为多次传入
bind是返回绑定this之后的函数,apply、call则是立即执行
七.对react中合成事件的理解
React合成事件是React模拟原生DOM事件所有能力的一个事件对象,即浏览器原生事件的跨浏览器包装器
:它根据W3C规范来定义合成事件,兼容所有浏览器,拥有与浏览器原生事件相同的接口。在React中,
所有事件都是合成的,不是原生DOM事件,但可以通过 enativeEvent”属性获取DOM事件。
八.对react中setState的理解
一个组件的显示形态可以由数据状态和外部参数所决定,而数据状态就是state,当需要修改里面的值的状态需要通过调用setState来改变从而达到更新组件内部数据的作用
setState第一个参数可以是一个对象,或者是一个函数,而第二个参数是一个回调函数,用于可以实时的获取到更新之后的数据
在使用setState更新数据的时候,setState的更新类型分成:同步更新,异步更新在组件生命周期或React合成事件中,setState是异步在setTimeout或者原生dom事件中,setState是同步对同一个值进行多次setState,setState的批量更新策略会对其进行覆盖,取最后一次的执行结果
React,用于构建用户界面的 JavaScript 库,只提供了 UI 层面的解决方案
遵循组件设计模式、声明式编程范式和函数式编程概念,以使前端应用程序更高效
使用虚拟 DOM 来有效地操作 DOM,遵循从高阶组件到低阶组件的单向数据流
帮助我们将界面成了各个独立的小块,每一个块就是组件,这些组件之间可以组合、嵌套,构成整体页面
react 类组件使用一个名为 render() 的方法或者函数组件return,接收输入的数据并返回需要展示的内容
React 特性有很多,如:
JSX 语法
单向数据绑定
虚拟 DOM
声明式编程
Component
React 存在的优势:
高效灵活
声明式的设计,简单使用
组件式开发,提高代码复用率
单向响应的数据流会比双向绑定的更安全,速度更快
两者的区别如下:
虚拟 DOM 不会进行排版与重绘操作,而真实 DOM 会频繁重排与重绘
虚拟 DOM 的总损耗是“虚拟 DOM 增删改+真实 DOM 差异增删改+排版与重绘”,真实 DOM 的总损耗是“真实 DOM 完全增删改+排版与重绘”
真实 DOM 的优势:
易用
缺点:
效率低,解析速度慢,内存占用量过高
性能差:频繁操作真实 DOM,易于导致重绘与回流
使用虚拟 DOM 的优势如下:
简单方便:如果使用手动操作真实 DOM 来完成页面,繁琐又容易出错,在大规模应用下维护起来也很困难
性能方面:使用 Virtual DOM,能够有效避免真实 DOM 数频繁更新,减少多次引起重绘与回流,提高性能
跨平台:React 借助虚拟 DOM,带来了跨平台的能力,一套代码多端运行
缺点:
在一些性能要求极高的应用中虚拟 DOM 无法进行针对性的极致优化
首次渲染大量 DOM 时,由于多了一层虚拟 DOM 的计算,速度比正常稍慢
jsx是JavaScript的一种语法扩展,它跟模板语言很接近,但是它充分具备JavaScript的能力
JSX就是用来声明React当中的元素,React使用JSX来描述用户界面
JSX语法糖允许前端开发者使用我们最熟悉的类HTML标签语法来创建虚拟DOM在降低学习成本
React.createElement()
参考答案:
面试官:React构建组件的方式有哪些?区别? | web前端面试 - 面试官系列
React 事件绑定属性的命名采用驼峰式写法, 采用 JSX 的语法传入一个函数作为事件处理函数
事件绑定函数的方式
1. 直接写函数名字{callback},
2. 可以使用bind方法绑定调用 {callback.bind(this)}
当我们把事件函数写成普通函数的形式时 , 调用函数使用state变量会报错,提示state变量不存在,
是因为
事件处理程序的函数式函数调用模式,在严格模式下,this指向undefined
render函数是被组件实例调用的,因此render函数中的this指向当前组件
解决方法: 1. 把普通函数改成箭头函数 2. 调用函数的时候使用bind方法改变this指向
调用的时候定义一个箭头函数 函数中调用方法传递参数据
点击
第二种方法 bind方法传递参数
点击
react中可以使用map方法渲染列表,return对应的页面结构即可, React 在渲染列表时,会要求开发者为每一个列表元素指定唯一的 key
,我们尽量不要使用index索引值作为key,如果对数据进行:逆序添加、逆序删除等破坏顺序操作:可能会引起页面更新错误问题。
key是虚拟DOM对象的唯一标识,在更新显示时key起到极其重要的作用 ,简单的来说就是为了提高diff的同级比较的效率,避免原地复用带来的副作用
react采用的是自顶而下的更新策略,每次小的改动都会生成一个全新的的vdom,从而进行diff,如果不写key,就会发生本来应该更新却没有更新
参考答案: 面试官:React中的key有什么作用? | web前端面试 - 面试官系列
外联样式
定义css文件,在组件中通过import导入css样式,
import "App.css"
内联样式
React推崇的是内联的方式定义样式。这样做的目的就在于让你的组件更加的容易复用
定义一个style属性,属性中定义对应的css样式即可,比如style={{fontSize:'15px'}}
外层花括号是语法,内层花括号是对象边界符
array(数组)、bool(布尔值)、func(函数number(数字)、object(对象)、string(字符串)
受控组件
由React控制的输入表单元素而改变其值的方式,称为受控组件。
比如,给表单元素input绑定一个onChange事件,当input状态发生变化时就会触发onChange事件,从而更新组件的state。
非受控组件
非受控组件指的是,表单数据由DOM本身处理。即不受setState()的控制,与传统的HTML表单输入相似,input输入值即显示最新值。
在非受控组件中,可以使用一个ref来从DOM获得表单值。
props是指组件间传递的一种方式,props自然也可以传递state。由于React的数据流是自上而下的,所以是从父组件向子组件进行传递;另外组件内部的this.props属性是只读的不可修改!
state是组件内部的状态(数据),不能够直接修改,必须要通过setState来改变值的状态,从而达到更新组件内部数据的作用。
参考链接: react 中router v6 与 v5 区别 - 哔哩哔哩
- 在父组件中我们通过createContext() 创建一个空对象,在父组件的最外层我们使用Provider包裹数据,通过value绑定要传递的对象数据。
- 在嵌套的子组件中,我们有两种方式获取数据:
(1) 我们可以使用Customer标签,在标签中绑定一个箭头函数,函数的形参context就是value传递的数据
(2). class组件中我们可以定义static contextType=context对象,组件中直接使用this.context获取数据。
Mounting(挂载阶段):已插入真实 DOM
Updating(更新阶段):正在被重新渲染
Unmounting(卸载阶段):已移出真实 DOM
挂载阶段:
- constructor() 在 React 组件挂载之前,会调用它的构造函数。
- componentWillMount: 在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。
- componentDidMount(): 在组件挂载后(插入 DOM 树中)立即调用
更新运行阶段:
* componentWillReceiveProps: 在接受父组件改变后的props需要重新渲染组件时用到的比较多,外部组件传递频繁的时候会导致效率比较低
* shouldComponentUpdate():用于控制组件重新渲染的生命周期,state发生变化,组件会进入重新渲染的流程,在这里return false可以阻止组件的更新
* render(): render() 方法是 class 组件中唯一必须实现的方法。
* *componentWillUpdate(): shouldComponentUpdate返回true以后,组件进入重新渲染完成之前进入这个函数。
* **componentDidUpdate(): 每次state改变并重新渲染页面后都会进入这个生命周期
卸载或销毁阶段
componentWillUnmount (): 在此处完成组件的卸载和数据的销毁。
(1) componentWillMount ,在ssr中 这个方法将会被多次调用, 所以会重复触发多遍,同时在这里如果绑定事件,
将无法解绑,导致内存泄漏 , 变得不够安全高效逐步废弃。
(2) componentWillReceiveProps 外部组件多次频繁更新传入多次不同的 props,会导致不必要的异步请求
(3) componetWillupdate, 更新前记录 DOM 状态, 可能会做一些处理,与componentDidUpdate相隔时间如果过长, 会导致 状态不太信
两种路由模式:
一种是Hash路由模式,用的是HashRouter组件
一种是历史路由模式,用的是BrowserRouter组件绑定
HashRouter或BrowserRouter配置路由模式
Route 定义路由组件映射关系
Redirect 设置路由重定向
NavLink 或者Link 页面路由跳转
Switch 路由匹配,当path匹配到一个component之后,将不会再想下继续匹配,提高了程序效率
//隐士参数传递
(1) this.props.history.push({ pathname : '/user' ,query : {id:100}})
this.props.location.query.id 获取query传递的参数据,刷新数据不在
(2) this.props.history.push({ pathname:'/user',state:{id: 1000 } }) this.props.location.state.id 获取state的数据,刷新数据还在
3. url传参方式 () history.location.search获取数据比较麻烦,得自己解析
4. 动态路由定义 /detail/:id
=> /detail/100
=> location.match.params中接受的参数是 {id:100}
声明式导航:
使用NavLink或者Link跳转, to属性后面跟字符串或者跟对象
编程式导航跳转:
props.history.push(url) 跳转页面可以返回上一页,保留历史记录
props.history.replace(url) 跳转页面,清空历史记录
props.history.go(num) 返回第几个页面
不是所有组件都直接与路由相连(比如拆分的子组件)的,当这些组件需要路由参数时,使用withRouter就可以给此组件传入路由参数,将react-router的history、location、match三个对象传入props对象上,此时就可以使用this.props.history跳转页面了或者接受参数了
+