简介:
当2014年Facebook推出React时,给整个业界带来全新的看待网页应用开发的方式,和React一同问世的Flux,也克服传统MVC框架的很多弊病。技术在不断发展,在2015年,Flux的一个变体Redux出现,进一步优化了Flux的功能。
优秀之处:
专注视图层:(处理路由,数据,以及逻辑的处理)
VirtualDom:只对虚拟dom更新,不对真实dom更新;只对dom进行必要的更新,实现的重绘的最小化;
Vue与React的异同点
React和Vue都是很优秀的框架,它们之间的相似之处多过不同之处,并且大部分的优秀功能是相通的,核心在于封装dom操作,专注视图层的轻量级框架
相同点:
用虚拟DOM实现快速渲染,提升性能(虚拟dom就是一个js对象,用它来描述真实dom,之所以可以提高性能js里面去比较js对象不怎么耗性能,但是比较真实的dom会很耗性能)
语法简单的轻量级MVVM框架()
同时支持服务端客户端渲染
生态优良,各种打包工具,路由,代码分割,数据管理,swiper,echart全家桶
异同点:
react适配多端(web页面,客户端页面)
react虚拟dom操作diff算法算出最小修改的需求的地方,dom操作合并
vue生态圈越来越强大,构建强大的应用也不是问题
公司选啥你选啥,哪个用的爽选哪个
jsx语法:
1) 高内聚,低耦合 (组件的设计要素)
高内聚:把逻辑紧密相关的内容放在一个组件中;
低耦合:不同组件之间的依赖关系要尽量弱化;尽量保持每个组件的独立性;
2) onClick 不是原生dom中的onclick事件,这里是onClict是通过react的事件委托方式,触发挂在顶层dom节点上的一个事件处理函数(提高了性能);
3) 可以将样式一起写入组件文件中;
4) 关于jsx语法的说法:
在jsx语法中可以直接写入组件,注意组件为了和普通标签区别,必须第一个字母大写;
jsx语法是历史的进步还是倒退;(样式,结构,逻辑于一体)
4、 活跃的生态圈:(开源项目)
5、 组件式开发
react的工作方式:
(1)从繁琐的dom处理中解脱出来,响应式,函数式编程思维;输入相同的数据,将产出相同的效果;数据更新,dom同时做出更新;
(2)Virtual Dom
Dom:结构化文本的抽象表达式;
虚拟dom:对dom树的抽象,不会触及浏览器,只存在于js内存的空间树形结构,每次的数据刷新,render函数的执行都会触发一个新旧虚拟dom 的对比,如果无改变,则不更新,有改变,只更新相应dom结构;
自动化构建项目:
1、 初始化:
全局安装:
npm install –-global create- react- app
初始化项目:
create- react- app myReactApp ( React脚手架工具: create-react-app)
启动服务:
cd myReactApp
npm start
2、引用index.js
3.组件的写法
在React中创建组件有三种方式:
ES5写法:React.createClass
ES6写法:React.Component
无状态的函数写法,又称为纯组件SFC
原文: https://www.w3cplus.com/react/stateful-vs-stateless-components.html © w3cplus.com
React.Component写法
import React from 'react';
import List from './list.jsx'; //子组件
export default class Chart extends React.Component{
constructor(){
super();
this.state={
list:[{
name:'琪芭比'
}]
}
}
render(){
return <div>{
//注释方法 {/** 对比vue的v-for,react用map方法遍历数组,map有返回 forEach没有返回*/}
this.state.list.map((item,index)=>{
return <div key={index}>
<div>
<p>{item.name}</p>
<p>{item.price}</p>
<p>{item.num}</p>
</div>
</div>
})
}</div>
}
}
无状态的函数写法
无状态的函数创建的组件是无状态组件,它是一种只负责展示的纯组件:
function HelloComponent(props) {
return <div>Hello {props.name}</div>
}
ReactDOM.render(<HelloComponent name="marlon" />, mountNode)
最后ps:总的来说:无状态函数式写法 优于
React.createClass
,而React.Component
优于React.createClass
。能用React.Component
创建的组件的就尽量不用React.createClass
形式创建组件。
React组件的数据
组件内部数据类型:
两种数据结构,prop和state,这两种数据的改变都会引起组件的重新渲染;
1、 Prop:组件的外部接口,接受外部数据;跟html的属性的书写类似,但是除了接受字符串之外,还可以接受js对象,数字等的;如果组件进行数据反馈给外界,可以通过prop传入组件一个函数;
Prop的读取:
由class类的constructor函数接受,以及super()方法调用时的传入;
最后的props为一个对象,键值分别为传入时的属性名;这里比较方便的是使用es6的解构赋值;
PropTypes的检查:
可以通过增加类的propTypes属性来定义prop规格,在constructor函数中进行如下定义:
Index.propTypes={ //组件全局进行配置
caption:PropTypes.string.isRequired,
initValue:PropTypes.number
}
注意:此属性不会影响组件的渲染,只是做到在开发过程中辅助开发;
2、 State:由于组件不能改变出入的prop,所以当组件要进行自己的状态纪录时就需要用到state;
初始化:state的初始化可以在constructor中,通过this.state进行设置,值必须为一个js对象的格式,通常将prop传入的外部值赋给state,以便后续操作;设置默认值时,可以用 | | 操作符进行;
读取和更新state
更新使用this.setState({count:this.state.count++})方法;
读取为:this.state.count这种方式
3、 Prop和state的对比:
Prop:定义外部接口;赋值在外部环境使用组件时;组件内部不能更改
State:纪录内部状态;赋值在组件内部;在组件内部可以进行更改;
PropTypes类型检查
在react的15.5版本后,React.PropTypes已经废弃了,需要单独引入prop-types库进行验证
importPropTypes from 'prop-types'
class Children extends Component {
constructor(props) {
super(props)
}
render() {
return (
<div>
<p>这里是子组件</p>
{this.props.name}
</div>
)
}
}
Children.propTypes={
name:PropTypes.string
}
prop-types库可以校验的类型如下:
importPropTypes from 'prop-types';
MyComponent.propTypes = {
// 你可以将属性声明为以下 JS 原生类型
optionalArray:PropTypes.array,
optionalBool:PropTypes.bool,
optionalFunc:PropTypes.func,
optionalNumber:PropTypes.number,
optionalObject:PropTypes.object,
optionalString:PropTypes.string,
optionalSymbol:PropTypes.symbol,
// 任何可被渲染的元素(包括数字、字符串、子元素或数组)。
optionalNode:PropTypes.node,
// 一个 React 元素
optionalElement:PropTypes.element,
// 你也可以声明属性为某个类的实例,这里使用 JS 的
// instanceof 操作符实现。
optionalMessage:PropTypes.instanceOf(Message),
// 你也可以限制你的属性值是某个特定值之一
optionalEnum:PropTypes.oneOf(['News', 'Photos']),
// 限制它为列举类型之一的对象
optionalUnion:PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
PropTypes.instanceOf(Message)
]),
// 一个指定元素类型的数组
optionalArrayOf:PropTypes.arrayOf(PropTypes.number),
// 一个指定类型的对象
optionalObjectOf:PropTypes.objectOf(PropTypes.number),
// 一个指定属性及其类型的对象
optionalObjectWithShape:PropTypes.shape({
color:PropTypes.string,
fontSize:PropTypes.number
}),
// 你也可以在任何 PropTypes 属性后面加上 `isRequired`
// 后缀,这样如果这个属性父组件没有提供时,会打印警告信息
requiredFunc:PropTypes.func.isRequired,
// 任意类型的数据
requiredAny:PropTypes.any.isRequired,
// 你也可以指定一个自定义验证器。它应该在验证失败时返回
// 一个 Error 对象而不是 `console.warn` 或抛出异常。
// 不过在 `oneOfType` 中它不起作用。
customProp:function(props, propName, componentName) {
if (!/matchme/.test(props[propName])) {
returnnewError('Invalid prop `' + propName + '` supplied to' +' `' + componentName + '`. Validation failed.');
}
},
// 不过你可以提供一个自定义的 `arrayOf` 或 `objectOf`
// 验证器,它应该在验证失败时返回一个 Error 对象。它被用
// 于验证数组或对象的每个值。验证器前两个参数的第一个是数组
// 或对象本身,第二个是它们对应的键。
customArrayProp:PropTypes.arrayOf(function(propValue, key, componentName, location, propFullName) {
if (!/matchme/.test(propValue[key])) {
returnnewError(
'Invalid prop `' + propFullName + '` supplied to' +
' `' + componentName + '`. Validation failed.'
);
}
})
};