您的位置:首页 > Web前端 > React

React学习笔记——如何创建React组件

2017-06-11 12:24 633 查看
       最近在空闲之余学习了一下React,发现React入门比angular2较为容易很多(个人观点,不喜勿喷),代码逻辑非常简单,只要是有JavaScript基础的童鞋,都能看明白,想要入门的童鞋们,如果英文阅读能力还不错的,或者想要提高自己英文阅读水平的,可以看下React官网的的Tutorial,不喜欢英文教程的童鞋推荐去看一下阮一峰前辈的React入门实例教程 。

          React的核心是组件,其设计目的是提高代码复用率、降低测试难度和代码复杂度

      React主要的语法是JSX语法,JSX 是JavaScript Xml的缩写,但其本质上不是XML,它是基于ECMASAcript标准的一种新特性,JSX可以理解为能直接写HTML的JS,和一般的HTML嵌套又有一定的区别,主要区别在于JSX能够使用求值表达式作为被嵌套的子节点,而一般的HTML嵌套只能使用语句作为嵌套的子节点,区别求值表达式和语句,主要看是否能够能否参与运算。

      JSX中的css样式是通过对象的形式传给style

<div style={key:value}></div>


      调用方法的方式也是如此

<div onClick={this.clickFn}></div>

      说这些也没啥用,我们先来看下如何创建一个组件,我这里写了一个轮播图的组件,用这个组件来说明一下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
*{margin: 0;padding: 0; list-style: none;}
.wrap{height: 340px;width: 790px;margin: 100px auto; position: relative;overflow: hidden;}
.wrap ul{position: absolute;width: 3950px;}
.wrap ul li{height: 340px;float:left;}
.wrap ol{position: absolute;bottom: 10px; margin-left: 35%;}

.wrap ol li{
float:left;
height: 8px;
width: 10px;
margin-left: 30px;
4000

line-height: 20px;
text-align: center;
border-radius: 50%;
cursor: pointer;
background-color:rgba(255,255,255,.5);
transition: all .25s;
}
.wrap ol li.active{
border-radius: 50%;
color: #fff;
background-color:rgba(0,0,0,.2);
}
.wrap ol li:hover{
border-radius: 50%;
color: #fff;
background-color:rgba(0,0,0,.2);
transform: scale(1.3);
}
</style>
<script src="../build/react.js"></script>
<script src="../build/react-dom.js"></script>
<script src="../build/browser.min.js"></script>
<script src="../build/jquery.min.js"></script>
</head>
<body>
<div class="wrap" id="wrap"></div>
<script type="text/babel">
var imgs = ['img/1.jpg','img/2.jpg','img/3.jpg','img/4.jpg','img/5.jpg']
var Carusel = React.createClass({
getInitialState:function () {
return {
index : 0,
timer : null,
wrap  : {},
pic   : {},
list  : [],
}
},
autoPlay:function() {
this.state.index++;
if (this.state.index >= this.state.list.length) {
this.state.index = 0;
}
this.handle(this.state.index);
},
change:function (index) {
this.state.index = index
clearInterval(this.timer);
this.handle(index)
},
handle:function (index) {
for(var j=0;j<this.state.list.length;j++){
if(j != index){
this.state.list[j].className='';
}else{
this.state.list[j].className='active';
}
}
$("#pic").stop(true, false).animate({left: -index * 790 + 'px'}, 500, function () {

})

},
componentDidMount:function () {
this.state.wrap = document.getElementById('wrap');
this.state.pic = document.getElementById('pic');
this.state.list = document.getElementById('list').getElementsByTagName('li');
this.state.list[0].className='active';
this.timer = setInterval(this.autoPlay, 3000);
var obj = this;
for(var i=0;i<this.state.list.length;i++){
this.state.list[i].id=i;
this.state.list[i].onmouseover=function(){
clearInterval(this.timer);
obj.change(this.id);
}
}
},
render:function () {
return (
<div>
<ul id="pic" onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave}>
{
imgs.map(function (img,index) {
return <li key={index}><img src={img}></img></li>
})
}
</ul>
<ol id="list">
{
imgs.map(function (img,index) {
return <li key={index}></li>
})
}
</ol>
</div>

)
},
onMouseEnter:function () {
clearInterval(this.timer);
},
onMouseLeave:function () {
this.timer=setInterval(this.autoPlay,3000);
}
});
ReactDOM.render(
<Carusel/>,
document.getElementById('wrap')
)
</script>
</body>
</html>


          首先我们需要引入三个类库:(PS:这三个库必须首先加载)

              react.min.js - React 的核心库

              react-dom.min.js - 提供与 DOM 相关的功能

              Browser.js 的作用是将 JSX 语法转为 JavaScript 语法,这一步很消耗时间,实际上线的时候,应该将它放到服务器完成。

      在不支持ES6的浏览器我们还需要再引入一个类库:

              babel.min.js - Babel 可以将 ES6 代码转为 ES5 代码,这样我们就能在目前不支持 ES6 浏览器上执行 React 代码。Babel 内嵌了对 JSX 的支持。通过将 Babel 和 babel-sublime 包(package)一同使用可以让源码的语法渲染上升到一个全新的水平。

      在使用JSX的地方需要注意,type都必须为 type="text/babel",这是React独有的写法,跟JavaScript不兼容,所以只要用到JSX的地方,都必须是用type="text/babel"进行声明,

      现在我们开始创建一个组件,创建组件的写法 为var Carusel = React.creatClass({}), 名字首字母必须大写,其中最主要的两个属性是render和componentDidMoun属性,render属性是必须的,这是用于输出组件,componentDidMoun是在组件输出完成后要执行的方法,说到这里。不得不提一下React组件的生命周期,React的生命周期中提供了10个不同的API,一一说解释之后应该就能明白生命周期了

     React 生命周期Api:

         1:getInitialState :作用于组件的实例,在实例创建时调用一次,用于初始化每个实例的state,此时可以访问this.props,但是两者有不同的地方,this.state访问的属性值时可以更改的,this.props访问的属性值是不可更改的。

         2:getDefaultProps:用于设置实例的默认值,作用于组件类,只调用一次,返回对象用于设置默认的props,对于引用值,会在实例中共享。

         3:componentWillMount:在Dom完成首次渲染之前调用,此时仍可以修改组件的state。

         4:render:在上面我们也说到了这个是必须要有的属性方法,它的作用就是创建虚拟的Dom,在这个方法的内部只能通过this.stated或者this.props的方式访问数据,它可以返回null ,false,或者任何React的组件,但是只能返回一个顶级组件,这里需要注意,而且还不能改变组件的状态,不能修改Dom的输出。

         5:componentDidMount:在上面也说了真实的Dom被渲染出来后调用,在该方法中可通过this.getDOMNode()访问到真实的DOM元素。此时已可以使用其他类库来操作这个DOM。不过得注意一点,该属性在服务端中,该方法不会被调用。

         6:componentWillReceiveProps:组件接收到新的props时调用,并将其作为参数nextProps使用,此时可以更改组件props及state。

componentWillReceiveProps: function(nextProps) {
if (nextProps.bool) {
this.setState({
bool: true
});
}
}

        7:shouldComponentUpdate:组件是否应当渲染新的props或state,返回false表示跳过后续的生命周期方法,通常不需要使用以避免出现bug。在出现应用的瓶颈时,可通过该方法进行适当的优化。需要注意的是,在首次渲染期间或者调用了forceUpdate方法后,该方法不会被调用。

       8:componentWillUpdate:接收到新的props或者state后,进行渲染之前调用,此时不允许更新props或state。

       9:componentDidUpdate:完成渲染新的props或者state后调用,此时可以访问到新的DOM元素。

     10:componentWillUnmount:组件被移除之前被调用,可以用于做一些清理工作,在componentDidMount方法中添加的所有任务都需要在该方法中撤销,比如创建的定时器或添加的事件监听器。

     看完API的描述后,上述的代码应该就能明白了。我还得说一点,就是render在返回组件的时候,只能是返回一个标签对,不能返回两个兄弟元素标签,

render:function () {//render 用于输出组件,这是必须的一个属性
return (
<div>
<ul id="pic" onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave}>
{
imgs.map(function (img,index) {
return <li key={index}><img src={img}></img></li>
})
}
</ul>
<ol id="list">
{
imgs.map(function (img,index) {
return <li key={index}></li>
})
}
</ol>
</div>
)
}


比如这里,如果返回的这个dom,ul跟ol外层没有div包裹的话,程序执行后将会报错,必须使用一个div进行包裹,对于ReactDom.render方法也是同样。除此之外在练习的过程中就没遇到其它的什么问题了。至于轮播图代码是很简单的纯JavaScript的代码,很容易看懂的,如果对上面我的描述还有什么疑问的童鞋们,欢迎留言,我将会一一作答。

     
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  javascript React