-
MVC 框架的主要问题是什么?
-对 DOM 操作的代价非常高
- 程序运行缓慢且效率低下
- 内存浪费严重
- 由于循环依赖性,组件模型需要围绕 models 和 views 进行创建
-
React 有什么特点?
React 的主要功能有:使用虚拟 DOM 而不是真正的 DOM ; 可以进行服务端渲染; 遵循单向数据流或数据绑定。
-
React 的主要优点与不足?
优势:
React实现对虚拟DOM的操作,使得它速度快,提高了Web性能;
模块化,组件化开发,可维护性高;
单向数据流,比较有序便于管理;
跨浏览器兼容:虚拟DOM帮助我们解决了跨浏览器问题,它为我们提供了标准化的API,甚至在IE8中都是没问题的。
可以方便地在客户端和服务端使用;
由于 JSX ,代码具有很好的可读性;
灵活性好,React 很容易与已知的库或框架很好地配合,如 Meteor、Angular 等其他框架集成;
使用React,编写UI测试用例变得非常容易。
不足:
react中只是MVC模式的View部分,要依赖引入很多其他模块开发。
当父组件进行重新渲染操作时,即使子组件的props或state没有做出任何改变,也会同样进行重新渲染。
React 只是一个库,而不是一个完整的框架;它的库非常庞大,需要花费较多时间来理解;新手学习成本高,上手慢;它使用内联模块和JSX让编码变得复杂。 -
Virtual DOM理解
本质上Virtual Dom是一个JavaScript对象,通过对象的方式来表示DOM结构。包含 TagName、props 和 Children 这些属性.
VirtualDOM工作过程有三个简单的步骤。(1)每当底层数据发生改变时,整个UI都将在VirtualDOM描述中重新渲染。(2)然后计算原来的DOM表示和新表示之间的差异。(3)完成计算后,将只用实际更改的内容更新Real DOM。 -
React类式组件和函数式组件的区别
-
react组件通信
-
什么是props ?
Props 是React中属性的简写,它们是只读组建,必须保持纯,即不可变。他们总是在整个应用中从父组件传递到子组件。子组件永远不能将prop送回父组件。这有助于维护单向数据流,通常用于呈现动态生成的数据。
-
state
props
是组件对外的接口,一般情况下,props是不变的,props对使用它的组件来说是只读的,如果要修改props,只能通过组件的父类组件修改
state
是组件对内的接口,是组件的私有属性
,只能被本组件访问和修改
setState() 异步操作
更新的状态不会立马刷新,而是将修改的状态放入一个队列
中;
React 可能会对多次 setState 状态修改进行合并修正
;{this.state}
获取的状态可能会不准确;
也不能依赖props
来计算组件的下一个状态;
-
setState是异步还是同步函数
在react18版本,任何情况下setState都是异步
在react17版本,如果平常使用就是异步的,但是在定时器或者js原生事件中是同步的,利用setTimeout绕过react内部的合并逻辑
异步的情况: 由React控制的事件处理函数,以及生命周期函数调用setState时表现为异步。大部分开发中用到的都是React封装的事件,比如onChange、onClick、onTouchMove等(合成事件中),这些事件处理函数中的setState都是异步处理的。
同步的情况: React控制之外的事件中调用setState是同步更新的。比如原生js绑定的事件,setTimeout/setInterval,ajax,promise.then内等React无法掌控的APIs情况下,setState是同步更新state的
setState()函数本身是同步的,由 React 控制的事件处理过程 setState是异步的不会同步更新this.state。
React的setState()函数实现是根据一个变量isBatchingUpdates判断是直接更新 this.state还是放到一个updateQueue中延时更新,而 isBatchingUpdates默认是false,表示setState会同步更新this.state;但是,有一个函数batchedUpdates,该函数会把 isBatchingUpdates修改为true,而当React在调用事件处理函数之前就会先调用这个 batchedUpdates将isBatchingUpdates修改为true,这样由 React 控制的事件处理过程 setState不会同步更新this.state,而是异步的 -
React 组件生命周期的三个阶段
初始渲染阶段:constructor(){}
更新阶段:componentWillMount() – 在渲染之前执行,在客户端和服务器端都会执行。
render()-渲染。
componentDidMount() – 仅在第一次渲染后在客户端执行。
componentWillReceiveProps() – 当从父类接收到 props 并且在调用另一个渲染器之前调用。
shouldComponentUpdate() – 根据特定条件返回 true 或 false。如果你希望更新组件,请返回true 否则返回 false。默认情况下,它返回 false。
componentWillUpdate() – 在 DOM 中进行渲染之前调用。
render()componentDidUpdate() – 在渲染发生后立即调用。
卸载阶段:componentWillUnmount() – 从 DOM 卸载组件后调用。用于清理内存空间。
-
对refs的了解及哪些情况下应该使用 Refs?
Refs是React中引用的简写,它是一个有助于存储对特定的React元素或组件的引用的属性,它将由组件渲染配置函数返回。用于对render() 返回的特定元素或组件的引用。当需要进行DOM测量或向组件添加方法时,它们会派上用场。
class ReferenceDemo extends React.component{ display(){ const name = this.inputDemo.value; document.getElementById('disp').innerHtml = name; } render(){ return( <div> Name:<input type="text" ref={input =>this.inputDemo = input} /> <button name="click" onClick={this.display}>Click</button> <h2>Hello <span id="disp"></span>!!!</h2> </div> ) } }
以下是应该使用refs的情况:
- 获取真实dom节点,需要管理焦点、选择文本或媒体播放时
- 使用回调函数refs用回调函数绑定ref,在对应文本节点上写入 ref={(currentNode)=>{this._name=currentNode}}
对应参数currentNode其实就是该文本节点,将该文本节点取一个别名_name
挂在实例上,可以直接this. ,注意,这里的ref不存在于实例的refs属性中{/* ref的回调函数方法 */} <input ref={(currentNode)=>{this.inp1=currentNode}} placeholder="请输入内容"></input> <button onClick={()=>{alert(this.inp1.value)}}>点击弹出左侧内容</button>
- 使用React.createRef()
首先声明一个_name=React.createRef(),然后就可以直接使用
该ref挂在实例对象上,也是一个对象,获取时用this._name.current.xxx获取
注意:该_name 是每个文本节点独有的,也就是说要绑定多个ref时需要创建多个对象myRef = React.createRef() render() { return <div> {/* ref的回调函数方法 */} <input ref={this.myRef} placeholder="请输入内容"></input> <button onClick={()=>{console.log(this.myRef.current.value)}}>点击弹出左侧内容</button> </div> }
-触发式动画- 与第三方DOM库集成
-
React Hooks
不能在react 循环 条件或嵌套函数中使用hook
-
useRef()
useRef可以用来定义变量,这些变量更改之后不会引起页面重新渲染,比如分页获取数据时,存储页码。useRef也可以用来区分初始渲染还是更新(通过current有没值,具体见示例库里的didOrUpdate.tsx)在DOM节点上定义ref属性,通过.current就可以获取到该DOM元素通过forwardRef就可以给函数子组件传入ref属性。使用useImperativeHandle用于定义暴露给父组件的ref方法 -
usememo usecallback 区别
useMemo 用于缓存计算结果只有在依赖项发生变化时才会重新计算当依赖项发生变化时,它会重新计算函数的返回值,并返回缓存的值。这适用于处理大量计算或复杂的计算逻辑,以避免不必要的重渲染。
usecallback 用于缓存函数只有在依赖项发生变化时才会重新创建函数。它同样接收一个函数作为参数,并返回一个记忆化后的函数。当依赖项发生变化时,它会重新创建函数并返回;当依赖项没有变化时,它会复用上一次记忆化的函数。这适用于将函数作为 prop 传递给子组件或传递给 `useEffect` 等副作用函数,以避免不必要的子组件重渲染或副作用的重复执行 -
高阶组件(HOC)的理解
高阶组件的本质是函数,是重用组件逻辑的高级方法,是一种源于React的组件模式。HOC 是自定义组件,在它之内包含另一个组件。它们可以接受子组件提供的任何动态,但不会修改或复制其输入组件中的任何行为。可以认为HOC是“纯(Pure)”组件。
HOC可用于许多任务,如:
-代码重用,逻辑和引导抽象
-渲染劫持
-状态抽象和控制
-props控制
一个 React 高阶组件的例子:
import React, { component } from 'react' export default (WrappedComponent) => { class NewComponent extends Component { constructor() { super(); this.state = { username: '' } } componentWillMount() { let username = localStorage.getItem('username'); this.setState({ username: username }) } render() { return <WrappedComponent username={this.state.username} /> } } return NewComponent }
另一个例子:
import React, { Component } from 'react' import wrapWithUsername from 'wrapWithUsername' class Welcome extends Component { render() { return ( <div>welcome {this.props.username}</div> ) } } Welcome = wrapWithUsername(Welcome); export default Welcome;
-
什么是纯组件
纯(Pure)组件是可以编写的最简单、最快的组件,它们可以替换任何只有render() 的组件,这些组件增强了代码的简单性和应用的性能。
-
React 中 key 的重要性
key 用于识别唯一的 Virtual DOM 元素及其驱动 UI 的相应数据。它们通过回收 DOM 中当前所有元素来帮助 React 优化渲染。这些 key 必须是唯一的数字或字符串,React 只是重新排序元素而不是重新渲染它们。这可以提高应用程序的性能。
-
对比真实DOM和虚拟DOM
Real DOM: 更新缓慢;可以直接更新HTML;如果元素更新,则创建新DOM;DOM 操作代价很高;消耗内存较多。
VirtualDOM :更新更快;无法直接更新 HTML;如果元素更新,则更新 JSX;DOM操作非常简单;很少的内存消耗。
-
Flux 的理解
Flux 是一种强制单向数据流的架构模式。它控制派生数据,并使用具有所有数据权限的中心 store 实现多个组件之间的通信。整个应用中的数据更新必须只能在此处进行。Flux 为应用提供稳定性并减少运行时的错误。
-
Redux 的理解
Redux 是当今最热门的前端开发库之一,它是Javascript 程序的可预测状态容器,用于整个应用的状态管理。
使用Redux开发的应用程序易于测试,可以在不同的环境中运行,表现出一致的行为。Redux 遵循三个基本原则:
(1)单一事实来源:整个应用的状态存储在单个 store 中的对象/状态树里。单一状态树可以更容易地跟踪随时间的变化,并调试或检查应用程序。
(2)状态是只读的: 改变状态的唯一途径是触发一个动作(action)。动作是描述变化的普通 JS 对象。该操作是对数据更改的最小表示。
(3)使用纯函数进行更改:为了指定状态树如何通过操作进行转换,我们需要用纯函数。纯函数是返回值仅取决于其参数值的函数。
Redux 由以下组件组成:
- Action
- Reducer
- Store
- View
-
Redux有什么缺点?
一个组件所需要的数据,必须由父组件传过来,而不能像flux中直接从store取。
当一个组件相关数据更新时,即使父组件不需要用到这个组件,父组件还是会重新render,可能会有效率影响,或者需要写复杂的shouldComponentUpdate进行判断。
-
router配置有三种
- (1)手工写代码(2)约定式路由 umi (3)配置式路由 routes.js antdesignpro
-
import { HashRouter as Router,Route } from 'react-router-dom'
- Router 是路由容器,放在最外层。
- Route代表路由配置,根据path匹配地址栏路径,渲染对应的 component。exact 参数是精确匹配
-
react的diff算法是怎么完成的
1.把树形结构按照层级分解,只比较同级元素。 2.通过给列表结构的每个单元添加的唯一 key值进行区分同层次的子节点的比较。 3.React 只会匹配相同 class 的 component(这里面的 class 指的是组件的名字) 4.合并操作,调用 component 的 setState 方法的时候, React 将其标记为 dirty. 到每一个事件循环结束, React 检查所有标记 dirty 的 component 重新绘制。 5.选择性渲染。开发人员可以重写 shouldComponentUpdate 提高 diff 的性能。
-
react 的重复渲染问题
-
React 18
已经放弃了对ie11
的支持,将于2022年6月15日
停止支持ie
,如需兼容,需要回退到React 17
版本。
React 18 中引入的新特性是使用现代浏览器的特性构建的,在IE中无法充分polyfill,比如micro-tasks -
react工具库
React 一些重要知识总结
于 2020-04-03 15:54:53 首次发布