react:(一)
简介
react发展历史:
react是facebook开发的,(vue-尤雨溪。angular-谷歌-收购的)facebook在构建instagram网站的时候遇见两个问题:
- 数据绑定的时候,大量操作真实dom,性能成本太高,比较浪费
- 网站的数据流向太混乱,不好控制
于是facebook起初调研过市场上已存的mvc框架,比如angularjs,发现都不太满意,于是就推陈出新,开发了react框架,并在2013年五月份开源,国内2016年才开始首先在杭州使用。
react 特点:
- 声明式设计 −React采用声明范式,可以轻松描述应用(自动dom操作)
- 高效 −React通过对DOM的模拟(虚拟dom),最大限度地减少与DOM的交互
- 灵活 −React可以与已知的库或框架很好地配合,比如(jquery库)
- JSX − JSX 是 JavaScript 语法的扩展
- 组件 − 通过 React 构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中
- 单向响应的数据流 − React 实现了单向响应的数据流,从而减少了重复代码,这也是它为什么比传统数据绑定更简单
组件化设计目的和优点:
组件化开发:
React 把用户界面抽象成一个个组件,如按钮组件 Button、对话框组件 Dialog、日期组件 Calendar。开发者通过组合这些组件,最终得到功能丰富、可交互的页面。通过引入 JSX 语法,复用组件变得非常容易,同时也能保证组件结构清晰。有了组件这层抽象,React 把代码和真实渲染目标隔离开来,除了可以在浏览器端渲染到 DOM 来开发网页外,还能用于开发原生移动应用。react开发的组件在原生js中也可以使用。
组件的本质–对象/类
React的核心是组件,组件的设计目的是提高代码复用率、降低测试难度和代码复杂度
- 提高代码复用率:组件将数据和逻辑封装,类似面向对象中的类。
- 降低测试难度:组件高内聚低耦合,很容易对单个组件进行测试。
- 降低代码复杂度:直观的语法可以极大提高可读性。
高内聚:当前组件专注做某一件事情。
低耦合:组件之间关联地比较低。
react 专注于视图层:
<>现在的应用已经变得前所未有的复杂,因而开发工具也必须变得越来越强大。React 并不是完整的 MVC/MVVM 框架,它专注于提供清晰、简洁的 View(视图)层解决方案。而又与模板引擎不同,React 不仅专注于解决 View 层的问题,又是一个包括 View 和 Controller 的库。对于复杂的应用,可以根据应用场景自行选择业务层框架,并根据需要搭配 Flux、Redux、GraphQL/Relay 来使用。
React 不像其他框架那样提供了许多复杂的概念与烦琐的 API,它以 Minimal API Interface(极少的API) 为目标,只提供组件化相关的非常少量的 API。同时为了保持灵活性,它没有自创一套规则,而是尽可能地让用户使用原生 JavaScript 进行开发。只要熟悉原生 JavaScript 并了解重要概念后,就可以很容易上手 React 应用开发。
react 核心编程方式:函数式编程(Functional Programming):
它属于 “结构化编程” 的一种,主要思想是把运算过程尽量写成一系列嵌套的函数调用。
函数式编程好处:
- 代码简洁,开发快速
- 接近自然语言(原生js),易于理解
- 更方便的代码管理
- 易于"并发编程“(同时调用)
- 代码的热升级
在过去,工业界的编程方式一直以命令式编程为主。命令式编程解决的是做什么的问题。
比如说:你现在要往东走,命令式编程就是让你往东走;函数式编程就是把你往东走的过程封装成一个函数,怎么走,一步走多少,然后你再往东走(也就是调用)。
React 把过去不断重复构建 UI 的过程抽象成了组件,且在给定参数的情况下约定渲染对应的 UI 界面。React 能充分利用很多函数式方法去减少冗余代码。此外,由于它本身就是简单函数,所以易于测试。可以说,函数式编程才是 React 的精髓。
JSX的语法:
React 为方便 View 层组件化,承载了构建 HTML 结构化页面的职责。从这点上来看,React 与其他 JavaScript 模板语言有着许多异曲同工之处,但不同之处在于 React 是通过创建与更新虚拟元素(virtual element)来管理整个 Virtual DOM 的。
JSX 将 HTML 语法直接加入到 JavaScript 代码中,再通过翻译器转换到纯 JavaScript 后由浏览器执行。在实际开发中,JSX 在产品打包阶段都已经编译成纯 JavaScript,不会带来任何副作用,反而会让代码更加直观并易于维护。
由于jsx语法浏览器不认识:编译过程由Babel 的 JSX 编译器实现。
将 HTML 语法直接加入到 JavaScript 代码中,并且遵循xml的语法规范。就是jsx语法。
创建react的一个组件:
browser端开发:
低版本(15):
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.bootcss.com/react/15.3.1/react.min.js" charset="utf-8"></script>
<script src="https://cdn.bootcss.com/react/15.3.1/react-dom.min.js" type="text/javascript" charset="utf-8"></script>
<script src="https://cdn.bootcss.com/babel-core/5.8.35/browser.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="out"></div>
</body>
<script type="text/babel">
//react.min.js 提供了跟组件相关的api以及核心diff算法思想
//react-dom.min.js 提供将虚拟dom转换真实dom的api
//browser 翻译器
var App=React.createClass({
render(){
return(
<div>{/*注释标签,切记有且只有一个根节点*/}
<div>hello react</div>
</div>
)
}
})
ReactDOM.render(<App/>,document.getElementById('out'))
</script>
</html>
高版本(16):
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.bootcss.com/react/16.0.0/umd/react.production.min.js" type="text/javascript" charset="utf-8"></script>
<script src="https://cdn.bootcss.com/react-dom/16.0.0/umd/react-dom.production.min.js" charset="utf-8"></script>
<script src="https://cdn.bootcss.com/babel-core/5.8.35/browser.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="out"></div>
</body>
<script type="text/babel">
class App extends React.Component{
constructor(props){
super(props)
}
render(){
return(
<div>{/*注释标签,切记有且只有一个根节点*/}
<div>高版本</div>
<input type="text" />
</div>
)
}
}
ReactDOM.render(<App/>,document.getElementById('out'))
</script>
</html>
样式的添加:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.bootcss.com/react/15.3.1/react.min.js" charset="utf-8"></script>
<script src="https://cdn.bootcss.com/react/15.3.1/react-dom.min.js" type="text/javascript" charset="utf-8"></script>
<script src="https://cdn.bootcss.com/babel-core/5.8.35/browser.min.js" type="text/javascript" charset="utf-8"></script>
<style type="text/css">
#tit{
color: red;
}
.tit{
color: blue;
}
</style>
</head>
<body>
<div id="out"></div>
</body>
<script type="text/babel">
var str='info'
var col={color:'red'}
var App=React.createClass({
render(){
return(
<div>
<div id="tit">hello react</div>
<div className="tit">你好</div>
<div>{str}</div>
<div style={{color:'red'}}>行间样式</div>
<div style={col}>行间-全局</div>{/*定义在外部*/}
<div style={this.col}>原型链样式</div>{/*用this调用自身的方法*/}
</div>
)
}
})
App.prototype.col={
color:"pink"
}
ReactDOM.render(<App/>,document.getElementById('out'))
</script>
</html>
样式添加时:给虚拟Dom添加id的方法无异常,但是我们通常是通过添加类名加样式;这时注意这里和原生js一样,用className添加类名。(用的较多)
react主张的样式写法是行间样式,因为权重最高,封装的组件独立性很强。
事件:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.bootcss.com/react/15.3.1/react.min.js" charset="utf-8"></script>
<script src="https://cdn.bootcss.com/react/15.3.1/react-dom.min.js" type="text/javascript" charset="utf-8"></script>
<script src="https://cdn.bootcss.com/babel-core/5.8.35/browser.min.js" type="text/javascript" charset="utf-8"></script>
<style type="text/css">
#tit{
color: red;
}
.tit{
color: blue;
}
</style>
</head>
<body>
<div id="out"></div>
</body>
<script type="text/babel">
var tap=function(){
alert('ok')
}
var App=React.createClass({
tap2(i){
console.log(i)
},
render(){
return(
<div>
<button onClick={tap}>全局事件</button>
{/*<button onClick={tap.bind(this)}>全局事件</button> 如果加上小括号会直接调用,解决办法是直接绑定this指向,用bind*/}
<button onClick={this.tap1}>私有函数-原型链</button>
<button onClick={this.tap2.bind(this,1)}>私有函数</button>{/*this后正常传参*/}
{/*组件本身是个类对象,直接添加方法*/}
</div>
)
}
})
App.prototype.tap1=function(){
console.log('hello')
}
ReactDOM.render(<App/>,document.getElementById('out'))
</script>
</html>
给标签绑定事件时一旦加上小括号,事件就会自动执行,而且仅执行一次。react本身的特点,如果不需要参数可以不加括号,但是一旦需要传参就不可避免,就要修正当前函数的this指向,用bind修正,this后面正常传参。
高版本(16)中,事件:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.bootcss.com/react/16.0.0/umd/react.production.min.js" type="text/javascript" charset="utf-8"></script>
<script src="https://cdn.bootcss.com/react-dom/16.0.0/umd/react-dom.production.min.js" charset="utf-8"></script>
<script src="https://cdn.bootcss.com/babel-core/5.8.35/browser.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="out"></div>
</body>
<script type="text/babel">
class App extends React.Component{
constructor(props){
super(props)
this.tap1=this.tap1.bind(this)
}
tap(){
console.log('hello')
}
tap1(){
console.log(this)
}
//可以在构造器里修复this比如上面的函数中要用this。
render(){
return(
<div>
<div>高版本</div>
<button onClick={this.tap.bind(this)}>事件</button>
</div>
)
}
}
ReactDOM.render(<App/>,document.getElementById('out'))
</script>
</html>
HTML的转义:
React 会将所有要显示到 DOM 的字符串转义,防止 XSS。{}单花括号会把标签也原文输出
后台传过来的数据带页面标签的是不能直接转义的。具体转义的写法如下:
var content='<strong>content</strong>';
React.render(
<div dangerouslySetInnerHTML={{__html: content}}></div>,
);
组件嵌套:
组件嵌套 不能多个节点渲染,否则最后一个组件覆盖前面的
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.bootcss.com/react/15.3.1/react.min.js" charset="utf-8"></script>
<script src="https://cdn.bootcss.com/react/15.3.1/react-dom.min.js" type="text/javascript" charset="utf-8"></script>
<script src="https://cdn.bootcss.com/babel-core/5.8.35/browser.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="out"></div>
</body>
<script type="text/babel">
var str='<span>info</span>'
var App=React.createClass({
render(){
return(
<div>
<div>{str}</div>
<div dangerouslySetInnerHTML={{__html:str}}></div>
<hr/>
<Home/>
</div>
)
}
})
var Home=React.createClass({
render(){
return(
<div>另一个组件</div>
)
}
})
ReactDOM.render(<App/>,document.getElementById('out'))
</script>
</html>
全局只有一个实例化的dom节点,所有看到的视图都是放在这一个dom元素上的。访问这个页面时展示其他组件。把其他组件当做普通的标签放在其里面来做一个展示。
总结使用步骤:
- react.creatClass()创建组件
- 要去实现组件中render方法
- 在render方法中 通过return返回jsx生成页面中的html内容
注意:
- 组件命名,首字母大写
- render方法 ReactDOM.render(<组件/>,node节点)
react中写入css
- base class—需要将react写class–用className代替class
- 每个组件都具有自己的属性和功能 inner css reactjs 行内 样式均是以json形式存在{color:‘red’},react将变量嵌套jsx中,style={变量名称}
- 基于全局变量 也就是将css抽取变成全局变量 或者在组件原型链上面进行挂载
事件机制
(函数声明需要与render同级,因为在react.creatClass传入的是对象,声明的函数也是其中的一个对象,是react对象对外暴漏的原型链,render会计算return的方法,同样计算同级的方法)
- 直接写事件机制onClick={this.函数名}
- 将所有函数变量封装到全局变量中
- 原型链写法
在jsx中写逻辑 --要写在render和return之间
注释标签的方法{/标签/}
组件嵌套 不能多个节点渲染,否则最后一个组件覆盖前面的
以上是基本的完整的一个react组件的构建形式,包含html js style。
但是有问题的:
- 所有组件都写在一个js文件里面 不好维护 写多个js去引入也无法识别
- 通过browser.js令jsx转换成js 性能慢
如何解决:
借助前段构建工具webpack
后面的文章会相继推出 谢谢