我的React之路--入门
React的学习之路还要继续走下去,最近一边在做未完成的项目一边学习React,项目是vue写的,后面还需要有一个后台管理系统计划使用react完成,寒假说长也不长,要抓紧时间了。 有人爱有人恨的语法糖--jsxjsx简介很多人不喜欢React,很大程度上是因为不喜欢jsx,那么jsx到底是什么呢?首先还是不要忘了React的基本哲学--一切都是js,包括文档结构。所以曾经每天都会见到的html在react的世界里全都不存在,react通过一系列叫做react元素的对象来构建虚拟DOM结构,最原始的创建react元素的方式是这样的: const root = React.createElement('div',{ className: 'main' },'我是一个div'); 最终它将返回一个大概这样子的对象(有所简化过,不代表在 React 源码中是这样): const root = { type: 'div',props: { className: 'main',children: '我是一个div' } }; 这样一个个创建节点其实是很麻烦的,想想看,如果每个整个虚拟DOM的内容都要通过React.createElement来创建,代码量会很多,而且我们根本无法直观地看出树形结构,无论开发还是维护性都及其不友好。为了解决这一问题,一种新型的,类似xml结构的语法扩展就诞生了,就是jsx。 上面的代码结构改成jsx的书写方式就是这样的: const root =( <div className="main"> 我是一个div </div> ); 这个结构就很熟悉了,不过要记住,他不是html模板,它就是js,最终在执行之前会被完全转义成为纯js代码,所以使用jsx是不存在任何性能问题的。 jsx语法jsx的标准语法结构和xml完全类似,特别的,jsx中的html属性要写成小驼峰命名的形式,比如onclick就要写成onClick。另一点需要注意的问题就是,由于class是js中的保留字,所以要用className来代替。 jsx使用jsx时候要时刻记住它是js表达式,所以它可以像普通的js表达式一样,赋值传参返回都可以。而在jsx内部如果想使用表达式,就需要放在 const item = this.newsList.map((news,index) => ( <li key={index}> <span>{news.title}</span> <span>{news.desc}</span> {news.image ? <img src="{news.image}"/> : null} </li> ) ); const list = ( <ul> {item} </ul> ); 这是一个在react开发中特别常见的使用场景,我们得到了一个数组的数据,需要以列表的形式渲染出来。在react中不需要使用任何迭代判断的相关指令语法,只要会写js的都能看懂上面的逻辑:通过数组的map方法迭代数组的内容,在回调函数中处理数据,渲染成想要的样式,就得到了一条一条列表项,插到列表里面就完成数据渲染了。我们可以发现在不论是迭代方法还是三元表达式等等,只要是js语法就可以随意地写到里面,自由度非常高。 可复用的基本单位--组件为什么要使用组件了解了jsx,下一个重要概念就是组件了。组件不是react特有的,组件化开发有很多好处,组件符合高内聚低耦合的要求,每一个组件是封装了视图和逻辑的一个相对独立的个体,而整个页面是由多个组件构成的,每个组件可以多次复用。 组件可以理解为类似于函数调用一样,定义好的组件是一个抽象的视图,而我们通过传入相关的“参数”来使它展示出我们想要的样子,组件就是我们复用各种独立部件的基本单位。 React中的组件定义一个组件最简单的方式是使用JavaScript函数: function Welcome(props) { return <h1>Hello,{props.name}</h1>; } 这是一个最简单的函数定义组件,整个函数调用结果实际上就是返回一个 class Welcome extends React.Component { render() { return <h1>Hello,{this.props.name}</h1>; } } 此处使用了ES6的类和继承,创建了一个继承自Component的类。这个组件和上一个组件效果是完全相同的,下面来重点分析React组件中几个重要的概念。 核心数据状态--state什么是state?状态,在react组件中,state是指一个组件UI呈现的最小状态集。在react中,视图层的更新是通过处理状态的变化来实现的,而state就是对这一系列状态的定义。react的数据是单向流动的,数据只能从模型层流向视图层,对应到具体的实现,我们对state所做的一系列处理会自动的反映到视图上,我们想要更新视图,只更新状态即可。说的可能比较抽象,看一个具体例子: class ClickMe extends React.Component { constructor(props) { super(props); this.state = { count: 0 }; } clicked() { this.setState({ count: this.state.count + 1 }); } render() { return ( <div onClick={() => this.clicked()}> 点我{this.state.count}次 </div> ); } } 这个组件的效果就是点击文字,会显示你的点击次数,效果很简单就不截图了,关于组件生命周期和点击事件绑定后面再看,这里重点来看state的变化。在构造函数里面初始化state的数据,把state数据放在页面上,点击时候调用setState方法改变state中的数据。 关于state有几点需要注意:
外部传递属性--propsprops是组件的另一个非常重要的概念,props指的是从外部传入的属性。props是React中父组件向子组件通信的方式,下面是一个简单的例子: class Child extends React.Component { constructor(props) { super(props); } render() { return ( <div> {this.props.data} </div> ); } } 使用组件 <Child data="我是显示的数据"></Child> 我们定义组件时候在构造函数中可以接收到props参数,并且要使用super传到Component的构造方法中。在整个组件的类中就可以使用成员变量props了。而props的内容,是父元素在调用子元素时候以属性的形式传入的。整个props控制的就是从父元素到子元素的事件流,这样我们在使用组件的时候就可以像函数调用一样使用组件,像传入参数一样传入props。 使用props时候要注意一点,props传递数据是单向的,数据只能从父组件传递到子组件,需要其它方向的数据传递就需要使用其他方式了。 组件从创建到销毁--生命周期生命周期这个概念在很多开发中都会接触,react也是如此,一个react组件从创建运行到销毁需要经历很多阶段,系统也为我们提供了对应阶段的hook方法(hook方法翻译为钩子方法,指的是当组件运行到对应的阶段时候就会自动执行写在这些方法里面的逻辑),我从网上找到了一副描述比较清晰的图片(侵删):
下面来逐一介绍这些生命周期方法以及它们说发挥的作用
以上是react生命周期的相关内容,到此,react组件的基本概念就介绍的差不多了。 行为与交互--事件绑定在react中绑定事件需要注意一个问题,如果是使用ES6的class方式定义的组件中事件处理函数的this默认是不会绑定的,我们需要手动绑定this指向。来看下面一个错误的例子: class EventTest extends React.Component { clicked() { console.log('clicked'); } render() { return ( <div onClick={this.clicked}> 点我 </div> ); } } 点击点我,确实能够正常打印出clicked,看起来好像没有问题,但是,如果试着打印一下this,就会发现结果是undefined。 这样写this没办法绑定,自然也就没办法使用各种成员变量和方法,也不能调用内置方法了,显然不是我们预期的,所以我们需要手动来绑定this指向,方法也很简单: class EventTest extends React.Component { clicked() { console.log('clicked'); } render() { return ( <div onClick={this.clicked.bind(this)}> 点我 </div> ); } } 只要增加bind(this)就能实现预期效果了,这也是一种常用的绑定this方式。除此之外还可以采用箭头函数来自动绑定this,下面的做法也是完全可以的: class EventTest extends React.Component { clicked() { console.log('clicked'); } render() { return ( <div onClick={()=>this.clicked()}> 点我 </div> ); } } 把clicked作为箭头函数返回的函数来使用,利用箭头函数内部自动绑定this的特性也可以实现this绑定。另外,还有一种写法: class EventTest extends React.Component { clicked = () => { console.log('clicked'); } render() { return ( <div onClick={this.clicked}> 点我 </div> ); } } 这种方法是新的ES标准中的实验性语法,由于有babel转译也是可以使用的,官网上面也提到了这种写法,不过由于新的标准还未成熟,所以用的人也不多。 了解了这些,react算是入了门了,接下来深入学习的路还长,虚拟DOM的原理,diff算法,css-in-js,工程化下的react项目结构,react-router,redux,还有以后要学习的react native,后面随着学习慢慢总结。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |