学习React阶段性总结
自己学习React也有一段时间了,应该做一个阶段性总结了,看了一下慕课网上的一些课程的介绍(自己舍不得花钱学-。-),然后自己截取了里面知识点介绍,对比一下自己的学习内容,试着去解释一下下面的知识点。 ---------------------------------------------------------------------------------------------------------------------------------------------- React.js组件基础
React.js属性与事件
React.js样式 内联样式及其表达式
React.js Router (下面就按照我的一个思路和目前学习的进度进行总结) ---------------------------------------------------------------------------------------------------------------------------------------------- 一.虚拟DOM的概念: 首先我用几个问题来引出这个话题 如果我们想创建一个DOM节点我们有哪些办法?
我们可以利用面向对象的思想去解决,而且我们js中就有构造器函数,利用它我们可以创建我们利用”工厂模式“批量建造~
<ul class="list"> <li class="item">1</li> <li class="item">2</li> </ul> 我们可以把它想象成一个对象 var ul={ tagName:"ul",props:{ class:"list" },childern:[ { tagName:"li",props:{ class="item" },children:["1"] },{ tagName:"li",children:["2"] },] } 创建我们的构造器函数进行批量处理: function Element(tagName,props,children){ this.tagName=tagName; this.props=props; this.children=children; } var ul=new Element("ul",{class:"list"},[ new Element("li",{ class: " item" },[ 1 ] ),new Element("li",[ 2 ] ),] )
Element.prototype.render = function () { var el = document.createElement(this.tagName) // 根据tagName构建 var props = this.props for (var propName in props) { // 设置节点的DOM属性 var propValue = props[propName] el.setAttribute(propName,propValue) } var children = this.children || [] children.forEach(function (child) { var childEl = (child instanceof Element) ? child.render() // 如果子节点也是虚拟DOM,递归构建DOM节点 : document.createTextNode(child) // 如果字符串,只构建文本节点 el.appendChild(childEl) }) return el }
---------------------------------------------------------------------------------------------------------------------------------------------- 二.React 组件,多组件嵌套,jsx内置表达式 对于这些概念我就不再详细说了,就直接看实例应该就能明白这些概念了。 (只给出关键性代码) class HelloMessage extends React.Component { constructor(props) { super(props); this.msg="Hello World" } render() { return ( <div> <h1>{this.msg}</h1> </div> ); } }; ReactDOM.render( <HelloMessage/>,document.getElementById('app') ); 我这边就把这个程序梳理一下: 1.创建一个HelloMessage类(首字母需要大写),继承React.Component(这个是React封装好的一个组件类,我们只需要继承它就可以用它提供的方法了,而且ES6提供了class和extends,这样我们创建类和继承就特别方便)。
2.在es6里面我们创建类后里面的方法就不用再用fn:function 这种形式,直接fn( )即可,我们创建的属性都放在constructor( )这个方法(构造函数)里面。
3.在constructor中我们需要在最开头使用super( ),super其实就是父类的构造函数,这个可以理解,因为我们使用了继承,所以当我们使用构造函数的时候,要先调用一下父类的构造函数,而且要把自己的参数全传给父类,这个props参数其实就是包含了组件上传进来的属性。
4.rener方法中return出来的对象就是我们产生的真实DOM;这里面也用到了jsx语法,html标签可以嵌入到我们的js语言中,只不过在html标签中写js的时候需要用{ } 括起来,在写样式的时候需要两个{ } 例如<div style={ { "color":"red"} }>,还有就是里面的写法需要用驼峰式,例如onClick ,marginLeft等,还有就是有些和ES6冲突的写法需要换一种方式,比如calss属性要写成calssName,for需要写成htmlFor。
5.render中return中只能有一个父级元素,不能有并列的。最后靠ReactDOM.render将我们生成的DOM节点真正挂载到我们的页面的DOM结构中去。
6.render中renturn中返回的元素不完全是我们的html标签元素,还可以是我们自己定义例如,组件之间各级嵌套,就如我们的html元素一样。 return ( <div> <h1>{this.msg}</h1> <Component2> <Component3/> </Component2> </div> );
7.我们可以把页面细分成多个组件,例如我们<h1>,<p>都可以看成一个组件,也可以进行嵌套形成一个复杂的组件;其实我们可以看见React组件之间嵌套一层又一层,形如一个金字塔形的结构。每个组件分工不一样,有的只是做展示,有的则是有具体的功能和交互,组件之间互相配合,重复使用。
---------------------------------------------------------------------------------------------------------------------------------------------- 三.State 属性、Props 属性、组件通信
React中最重要的两个概念,一个是组件,一个就是状态。我们是通过控制组件的状态从而控制程序的view层(都说React框架其实只是view层的表现,侧重点在于DOM节点的渲染).说到状态就不得不提state和props这2个属性。 这两个属性的最大不同点在于,props是只读的属性,state不是。由于这个特性我们大概就能猜出来这两个属性的作用来了:props是用来定义组件一些不变的属性,用来进行组件初始化的参数传递来达到渲染组件的目的,而state是定义一些可变属性,用来修改组件属性,从而达到再次渲染组件的目的。 这里既然说到了修改组件属性,那么我们就不得不提一下组件之间的通信: 可以参考我这篇博客的例子:http://www.52php.cn/article/p-mpwboybm-bch.html 这里还需要注意的是对于state属性的修改我们不能想当然的this.state.xxx=abc这样进行修改,react给了我们专门的方法this.setState( )这个方法供我们使用。
---------------------------------------------------------------------------------------------------------------------------------------------- 四.生命周期
个人认为组件的生命周期同样是个很重要的概念。 首先说一下生命周期分为以下几个:(这些函数都是以回调函数的形式给我们,这样我们就只需要在这里面写我们的逻辑即可,不用去调用,去担心什么时候该调用这些函数)
此外,React 还提供两种特殊状态的处理函数。 当我们有这些生命周期函数后,首先在书写代码的逻辑上给了我们很大的一个帮助,好比告诉我们一个人每个阶段该做什么事情,这样就不至于出现"谁的青春不迷茫"这样的感慨了,对于我们代码的结构上有很大的帮助,方便我们以后去维护,查看问题。而且前面也说了它是以一个回调函数的形式给我们,我们只需要把逻辑往里面“丢”就行~
下面是一个组件的生命周期调用顺序: 当一个组件被调用的时候先执行constructor这个函数,然后执行componentWillMount(即将渲染),接下来渲染到dom树上(触发render函数),渲染完成触发componentDidMount函数; 这时候,该组件就进入了一个running状态,并监视他的props和state以及被移除事件: 当props发生变化时执行componentWillReceiveProps然后去判断是否需要重新渲染(shouldComponentUpdate),如果不需要则继续保持running状态;如果需要则如初始时一样,执行componentWillMount(即将渲染),接下来渲染到dom树上,渲染完成触发componentDidMount函数,保持running状态继续监视; 当state发生变化时,则直接判断是否需要重新渲染(shouldComponentUpdate),然后根据是否需要决定执行渲染过程还是继续保持running状态; 当该组件被移除(unmount)时,将直接执行componentWillUnmount,该组件从dom树上消失; 上面都是一些理论知识,然后我们看一下具体一个例子:
class Clock extends React.Component { constructor(props) { super(props); this.state = { date: new Date()}; } componentDidMount() { this.timerID = setInterval( () => this.tick(),1000); } componentWillUnmount() { clearInterval(this.timerID); } tick() { this.setState({ date: new Date() }); } render() { return ( <div> <h2>It's {this.state.date.toLocaleTimeString()}</h2> </div> ); } }; ReactDOM.render( <Clock />,document.getElementById('app') );
----------------------------------------------------------------------------------------------------------------------------------------------
五.组件的Refs
jq之所以好用,很大一部分在于它强大的选择器,让我们更加轻松地直接操作我们想要的DOM节点;同样React也提供了一种让我们直接操作DOM节点的方法,其提供了一个refs属性,我们可以给组件定义一个ref=xxx 类似于我们ID,然后通过this.refs.xxx来直接操作我们的DOM节点,因为它返回的就是我们的真实DOM节点,这样我们就可以用原生的各种方法去操作它。
这里需要注意的两点就是:
1.这个属性是添加在我们组件中的html标签中的,例如<p>,<div>等,并不是我们自己定义的标签
2.需要等到组件componentDidMount之后我们才能访问到我们的DOM节点
既然这里说到了jq,那我就顺便提一下,React的开放性特别好,在它里面可以用jq,而且还兼容其他的前端框架,angular,vue等等。因为React提供给我们的就两个东西,一个是组件,一个就是状态,其他的一些功能需要我们自己去组合开发,自己写业务逻辑。但是angular是不能兼容其他框架的,它本身也封装好了很多方法给我们使用,比如表单验证,angular就提供给了我们接口,而React需要我们自己想办法。
class RefsC extends React.Component { constructor(props) { super(props); this.state = { date: new Date()}; } componentDidMount() { var _this=this; $(_this.refs.lzj).click(function(){ _this.setState((prevState,props) => ({ num:prevState.num+1 })); /*_this.setState(function(prevState){ return { num:prevState.num+1 } });*/ }) } render() { return ( <div> <h1 ref="lzj">{this.state.num}</h1> </div> ); } }; ReactDOM.render( <RefsC />,document.getElementById('app'));
/*目前就只先谈到这里,路由的话前面写过一次http://www.52php.cn/article/p-pzoidhmi-bch.html*/
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |