-
什么是React?
是一个构建用户界面的渐进式JavaScript库。
①:本身只负责处理ui
②:不关心路由
③:不处理ajax
④:数据驱动视图
React主要用于构建ui,mvc模式中的v,是真正意义上的第一个前端组件化开发框架,vue借鉴了React,angular也借鉴了。
-
什么时候用React?
开发原生app,vue用的是weex,react用的是native。
-
特点?
①:组件化、高效率,react首创虚拟DOM,vue2.0借鉴了虚拟DOM。
②:灵活。渐进式本身只处理ui,配合其他技术实现全家桶也可以。
③:声明式设计(函数式编程)。使用data响应数据,使用methods处理函数。
④:JSX(只能开发使用)。一种编译JavaScript语言,可将js和html混写。采用js逻辑。 -
vue和react对比?
①:两者都采用虚拟DOM,性能都差不多,都支持组件化。
②:vue支持表单控件双向数据绑定。
③:react不支持双向数据绑定。
④:核心都很小,采用渐进式。
⑤:react采用JSX语法编写组件。
⑥:vue采用文件组件。(xxx.vue)
开发高性能app,主流采用react。react用的最多的是全家桶。类似vue-cli一样,react也有脚手架工具,叫做:create-react-app,也继承了webpack工具。
一、体验react
引入两个核心库。(BootCDN中复制连接或者下载)
1.react.js 实现核心的react逻辑。
2.react-dom.js 实现具体的dom渲染。
认识原始渲染:
通过React.createClass注册组件,该组件只包含render函数。通过调用React.createElement方法实现创建DOM节点。
<body>
<!-- 节点目标 -->
<div id="app"></div>
</body>
<script src="./react.js"></script>
<script src="./react-dom.js"></script>
<script>
/* 检查是否引入成功 */
console.log(React);
let hello = React.createClass({
render:function(){
/* 创建节点 */
return React.createElement("h1",null,"hello React");
}
})
/* 渲染方法
两个参数: 想要渲染的节点,节点目标。
*/
ReactDOM.render(
/* 参数创建节点 */
React.createElement(hello,null),
/* 节点目标 */
document.getElementById("app")
)
</script>
上述方法已经被官方舍弃,真正使用react需要正确使用JSX。JSX不被任何平台识别,必须用bable编译。所以要在项目中引入babel文件(BootCDN中复制连接或者下载)。注意在script标签中注意type = "text/babel"。
正确使用JSX和bebal简单使用react如下:
<body>
<!-- 渲染元素 -->
<div id="root"></div>
</body>
<script src="./js/react.js"></script>
<script src="./js/react-dom.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
<script type="text/babel">
ReactDOM.render(
/* 混写h1为渲染内容 权重渲染元素 */
<h1>Hello wold react</h1>,
document.querySelector('#root')
)
</script>
JSX语法:
①:只有一个根节点,即所有内容包含在div中。可嵌套。
②:遇到以 < 开头的代码,用html规则解析
③:遇到以 { 开头的代码,用js规则解析
二、react组件化开发
-
什么是组件?
对功能进行分类。带有复用功能,由数据驱动。在react中,能实现上述功能则为一个组件。
组件命名:避免h5所有标签,首字母大写。
-
三种创建组件的方法。
①:函数式组件。(最简单,最常用,也称无状态组件)
这种组件只负责根据你传入的数据,进行展示,不会涉及到数据状态的操作,在大部分react代码中,很多组件都是无状态组件,因为无状态组件兼容性极好。可以通过简单的组合,构建成其他的组件。是很被倡导的。
优点:
1.组件不会被实例化,整体性能较高。
2.组件不能访问this对象。
3.组件只能传入一个数据,不会有其他副作用。
缺点:
1.无法根据数据进行动态渲染。
2.组件没有生命周期。
创建代码如下:
/* 创建组件 */
function AppText(){
/* 组件内容全部return */
return (
<div>
<input type="text"/>
<button>我si一个组件</button>
</div>
)
}
/* 渲染元素 在内部调用组件直接用*/
const ele = (
<div>
<p>我是头</p>
<AppText/>
</div>
)
/* 加载页面并渲染 */
ReactDOM.render(ele,document.getElementById('app'))
②:React.createClass(有状态,不被倡导,被React.Component替代)
/* 创建组件 */
let Hello = React.createClass({
render:function() {
return React.createElement('h1',{className:'active'},'hello Wold')
}
})
/* 界面渲染 */
ReactDOM.render(
React.createElement(Hello,null),
document.getElementById('app')
)
③:class
很多时候,我们需要根据数据状态去动态修改渲染,需要一种有属性,有状态,有方法,类似VUE的component的组件,语法就是ES6的class。React.Component类似VUE中的Vue.component,属性也是data,方法也是methods。
class AppText extends React.Component{
render(){
return(
<div>
<input type="text" />
<button>确认</button>
</div>
)
}
}
/* 在渲染元素中调用 */
const ele = (
<div>
<p>我是头</p>
<AppText/>
</div>
)
/* 获取渲染元素并渲染 */
ReactDOM.render(ele,document.getElementById('app'))
三、组件对象的三大属性
①:props属性
每个组件都有一个props属性。即组件标签 <AppText /> 的所有属性全都会保存在props中。内部想要获取某个属性值:this.props.propertyName。
<body>
<div id="app"></div>
<div id="box"></div>
</body>
<script src="./react.js"></script>
<script src="./react-dom.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
<script type='text/babel'>
/* 定义两条数据(对象) */
let obj1 = {
name:'lly',
sex: '1',
age:22
}
let obj2 = {
name:'zjh',
age:28
}
/* 定义组件 */
class AppText extends React.Component {
constructor(props){//获取props属性
super(props)
console.log(props)
}
render(){
return(
<ul>
<li>你好,我叫:{this.props.name}</li>
<li>我今年:{this.props.age}岁</li>
<li>我是:{this.props.sex}</li>
</ul>
)
}
}
/* 可给构造组件设置默认值 */
AppText.defaultProps = {
sex:'男孩'
}
/* 限制props的类型,不满足限制时发出警告 */
AppText.propTypes = {
age:React.PropTypes.number.isRequired
}
/* 渲染时讲两条数据传入 */
ReactDOM.render(<AppText {...obj1} /> , document.getElementById('app'))
ReactDOM.render(<AppText {...obj2} /> , document.getElementById('box'))
</script>
②:refs属性
1.组件内的所有标签都可以通过ref属性来标识自己。
2.在组件中,我们可以通过this.refs.refName来得到对应的真实DOM对象。
3.表单中用的多。
时间的处理:
1.通过 onXxx (onClick)属性指定组件处理函数。(注意大写)
2.通过event.target可以得到发生时间的DOM对象。
通过第三方途径,操作DOM元素,就必须使用ref属性,如果只是对DOM自身,添加操作,则可以直接使用event,不需要绑定ref属性了。
举例:input操纵自己的数据,即使用event.target.value即获取input值。input通过button操纵数据,则给input加上ref标识符并命名。在button的事件中使用this.refs.refName.value获取。
class Refs extends React.Component{
constructor(props){
super(props);
/* 构造函数绑定this指向 */
this.showMsg = this.showMsg.bind(this);
this.hand = this.hand.bind(this);
}
/* 点击显示数据 通过第三方button 则给inoput加上标识符*/
showMsg(){
console.log(this.refs.msg.value)
}
/* 鼠标离开显示数据 */
hand(event){
console.log(event.target.value)
}
render(){
return(
<div>
<input onBlur={this.hand} type='text' ref='msg' />
<button onClick={this.showMsg}>提示输入的数据</button>
</div>
)
}
}
ReactDOM.render(<Refs/> , document.getElementById('app'))
③:state属性
用来更新组件的状态值。让页面重新渲染。
1.初始化状态:
constructor (props){
super(props)
this.state = {
xxx1 = value1,
xxx2 = value2
}
}
2.读取状态的值
this.state.xxx;
3.更新状态
当state属性,发生了更新才会渲染。当state发生更新的时
候,对应的组件界面也会发生更新。
this.setState({
xxx1:value1,
xxx2:value2,
...
})
class App extends React.Component {
constructor (props){
super(props);
/* 定义状态 */
this.state = {
flag: false
}
this.oop = this.oop.bind(this)
}
oop(){
console.log(this.state.flag)
let flag = !this.state.flag;
/* 重置状态 */
this.setState({flag})
}
/* 在渲染中判断状态 */
render(){
let txt = this.state.flag ? 'mmp' : '变变变'
return <h1 onClick={this.oop}>{txt}</h1>
}
}
ReactDOM.render(<App/>,document.getElementById('app'))
四、react生命周期。
1.组件有三个生命周期状态
-Mount 插入真实的DOM
-Update 被重新渲染
-Unmount 被除以真实的DOM
2.React为每一个状态都提供了两个钩子函数,will进入前状态,did执行完状态
componentWillMount()
componentDidMount() 执行完render之后,才会执行
componentWillUpdate()
componentDidUpdate()
componentWillUnmount()
3.大致生命周期流程
①:第一次初始化渲染显示,render()
construtor()创建了初始化对象state
componentWillMount()
render()
componentDidMount()
②:每次跟新state
componentWillUpdate()
render
componentDidUpdate()
③:组件删除
ReactDOM.unmountComponentAtNode(document.getElementById('app'))
删除之前,会执行componentWillUnmount()
一般通常我们会在componentDidMount()开启监听,发送ajax请求,在componentWillUnmount()里面停止监听,处理请求返回的数据
class Life extends React.Component {
constructor(props){
super(props)
console.log('constructor() 创建组件对象')
this.state = {
date:new Date().toLocaleString()
}
}
componentWillMount(){
console.log('componentWillMount() 将要初始化挂载')
}
componentDidMount(){
console.log('componentDidMount() 已经初始化挂载')
}
render(){
console.log('render 渲染内部虚拟DOM')
return (
<div>
<h1>{this.state.date}</h1>
</div>
)
}
}
ReactDOM.render(<Life/>,document.getElementById('app'))
五、axios
服务器端打开
class App extends React.Component{
constructor (props){
super(props)
this.state = {
data:null
}
}
componentDidMount(){
axios.get("./msg.tex")
.then((response)=>{
this.setState({
data:response.data
})
})
.catch((error)=>{
console.log(error)
})
}
render(){
return <p>{this.state.data}</p>
}
}
ReactDOM.render(<App />,document.getElementById('app'))