react是什么?为什么要使用它?
React 是一个用于构建用户界面的 JavaScript 库
优点: 传统的js需要去手动的更新DOM,每次状态改变时,使用js重新渲染整个页面会非常慢,这归咎于读取和更新DOM的性能问题
而react运用一个虚拟的DOM实现了非常强大的渲染系统,在react中对DOM只更新不读取。react以渲染函数为基础,这些函数读入当前状态,将其转换为页面上的一个虚拟表现,只要react被告知状态有变化,它就会重新运行这个函数,将计算结果更新DOM。
react是通过计算虚拟页面当前版本和最新版本的差异,基于这些差异对DOM进行必要的最少更新
react和jquery: 两者不是一个层面的东西,jq只是一个工具库,只是我们用来完成一些基本操作的工具库,用起来笨重,代码臃肿且难以维护和扩展。
react把ui组件独立出来,可以提高代码可读性和页面性能,适用于DOM操作复杂的单页面应用。
关于diff算法: react就是使用diff算法,来比对原始虚拟DOM和新的虚拟DOM之间的差异(同层虚拟DOM比对)---------循环dom节点时,加key值,可以很快地一对一比对,所以加上key值,也是提高性能的一种方法。
react和vue的对比
- react灵活性更大一些,处理非常复杂的业务时,技术方案会有更多一点的选择
- vue提供了更丰富的api,实现功能会更简单,而正因为api多,所以灵活性就有一定的限制
- react是mvc模式,而vue是mvvm模式(vue数据双向绑定)
- react主要使用jsx语法,而vue主要使用模板语法
其实vue也可以做复杂度高的,看自己的驾驭程度
如何使用react
1.react之jsx语法
react发明了jsx,利用html语法来创建虚拟dom
react的核心机制之一就是可以在内存中创建虚拟的dom元素,以此来减少对实际dom的操作,从而提升性能
jsx,即javascriptXML,它是对js语法的扩展,遇到< ,jsx就当html解析,遇到 { ,就当javascrpt解析
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
new Vue({
el: "#app",
render: h => h(App),
router,
store
});
vue也可以使用jsx,比如我们常写的 render:function(){ return *****},用来展示dom的,就是jsx语法,不过vue用的最多的还是模板语法;
jsx的优点:
- 快,执行速度很快,因为它在编译为javascript代码后进行了优化
- 可以使用熟悉的语法仿照HTML来定义虚拟DOM,从而编写模板更简单快速
- 防止注入攻击,React DOM 在渲染所有输入内容之前,默认会进行转义。它可以确保在你的应用中,永远不会注入那些并非自己明确编写的内容。所有的内容在渲染之前都被转换成了字符串。这样可以有效地防止 XSS(cross-site-scripting, 跨站脚本)攻击。
2.开发环境创建
使用官方脚手架:create react app
- 安装 node
- npx create-react-app my-app
- cd my-app
- npm start
3.react组件:函数组件和class组件
函数组件:
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
class组件
class Name extends React.Component {
//通过此方式将props传递到父类的构造函数中,super()初始化数据
constructor(props) {
super(props);
this.state = {name: 'lisa'};
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.name}.</h2>
</div>
);
}
}
两者组件的区别:
函数式组件:
- 函数组件看似只是一个返回值是DOM结构的函数,其实它的背后是无状态组件的思想。函数组件中,无法使用state,也无法使用组建的生命周期方法,它只是展示型组件,接收props,渲染DOM
- 函数组件中没有this
总结:操作简单,能实现的功能非常简单,只有简单的调取和返jsx而已
类组件:
- 操作相对复杂,可以实现一些更复杂的业务场景
- 能够使用生命周期函数操作业务
- 函数组件可以理解为静态组件(组件中内容调取时已经固定了,很难再修改),而类组件可以根据组件内部的状态来动态的更新和渲染内容。
总结:如果操作简单,只是展示性的业务场景,尽量使用函数式组件,节省性能。
关于生命周期
这里着重提一下shouldComponentUpdate,在react开发中,经常会遇到组件重复渲染的问题,父组件一个state的变化,就会导致该组件的所有子组件都重写render,
尽管大多数子组件的props没有变化,所以为了避免这些不必要的render,我们就可以使用shouldComponentUpdate(),
如果return true,就会继续往后执行,如果return false,就不往后执行,不更新dom了,所以我们可以用这个方法节省性能。
当然,现在还有一个方法可以代替shouldComponentUpdate,那就是React.PureComponent()关于redux
react是视图层框架,和vue一样,需要结合逻辑层框架,如redux;
如果有异步请求,可以使用redux-thunk中间件来实现
路由
react的路由使用 react-router-dom
yarn add react-router-dom
import {BrowserRouter ,Route} from 'react-router-dom'
<div>
<Header />
<BrowserRouter>
<div>
<Route path='/' exat render={()=><div>home</div>} />
<Route path='/detail' exat render={()=><div>detail</div>} />
</div>
</BrowserRouter>
</div>
BrowserRouter里面只能由一个打标签,多以用一个div包裹
标签里面的内容要使用路由,防止访问‘/detail’时,‘/’也被访问显示
页面点击跳转以及路由传参
import {Link} from 'react-router-dom'
<Link to={'/detail/'+item.id}></Link>
//然后在详情页里调用id:this.props.match.params.id
//注:路由配置里需要这样写 <Route path='/detail/:id' exat render={()=><div>detail</div>} />
//2.用?连接
<Link to={'/detail?id='+item.id}></Link>
//然后在详情页里调用id:this.props.location.search ,获取到的是 ?id=1,需要自己处理
//注:路由配置里需要这样写 <Route path='/detail' exat render={()=><div>detail</div>} />