react学习笔记
react学习随记
新年初始,公司的项目还没开始,趁着休闲的时间学习一下react.
· React起源于Facebook的内部项目,是一个用于构建用户界面的JavaScript库,主要适用于构建UI,可以认为react是MVC中的视图V
· react的特点如下:
声明式设计 + 代码高效灵活 + jsx语法 + 组件复用 + 单项响应的数据流
· react中重要的几点:
jsx + 组件 + react State状态 + react Props + ajax + 表单/事件 + Refs获得实际DOM
下面对这几点简单的介绍总结:
1、reactJSX
jsx就像是一个xml的JavaScript的语法扩展,它是将html和JavaScript混合编写,虽然我们使用react并不一定要用jsx,但是还是推荐使用,
jsx使用起来执行更快,而且是类型安全的,在编译的过程中就可以发现错误;
使用jsx:
!<p data-myattribute = "somevalue">这是一个很不错的 JavaScript 库!</p>
这个p元素中添加自定义属性date-myattribute,添加自定义属性需要使用data-为前缀
!项目中的reactJSX代码可以放在一个独立的文件中,也可以放在当前html文件中;不过要注意的是使用jsx的时候需要标注script标签的type为text/babel
例如:<script type="text/babel" src="demo.js"></script>
!在jsx中可以使用JavaScript表达式,需要用{}括起来:
ReactDOM.render(
<div>
<h1>{1+1}</h1>
</div> ,
document.getElementById('example')
);
而且在jsx中不能使用if else语句,但是可以使用三元运算表达式来替代<h1>{i == 1 ? 'True!' : 'False'}</h1>
!react中推荐使用内联样式,我们可以使用camelCase语法来设置内联样式,react会在指定元素数字后自动添加px,
var myStyle = { fontSize: 100, color: '#FF0000' }; ReactDOM.render( <h1 style = {myStyle}>菜鸟教程</h1>, document.getElementById('example') );
!在jsx中注释需要用{}进行包括:
ReactDOM.render( <div> <h1>菜鸟教程</h1> {/*注释...*/} </div>, document.getElementById('example') );
!jsx允许在模板中插入数组,数组会自动展开所有的成员(这个是比较方便的一种形式)
var arr = [ <h1>菜鸟教程</h1>, <h2>学的不仅是技术,更是梦想!</h2>, ]; ReactDOM.render( <div>{arr}</div>, document.getElementById('example') );
!jsx中的html标签 VS react组件
react可以渲染html标签(strings)或者react组件(classes)
要是渲染html标签,只需要在jsx中使用小写字母的标签名,但是渲染react组件则需要创建一个大写字母开头的本地变量,jsx中使用大小的约定来区分本地组件和html标签,但需要注意一些标识符class和for不建议最为xml属性名,最为替代ReactDOM使用className和HTMLFor来做对应的属性
html标签渲染:
var myDivElement = <div className="foo" />; ReactDOM.render(myDivElement, document.getElementById('example'));
react组件渲染:
var MyComponent = React.createClass({/*...*/}); var myElement = <MyComponent someProperty={true} />; ReactDOM.render(myElement, document.getElementById('example'));
2、react组件
!react中React.createClass()方法用于生成一个组件类HelloMessage ,<HelloMessage/>实例组件类并输出信息,需要注意的是原生html元素名以小写字母开头,而自定义的react类名以大写字母开头,比如HelloMessage,除此之外还要注意组件类只能包含一个顶层标签,不然也会报错,如果我们需要向组件传递参数,可以使用this.props对象
var HelloMessage = React.createClass({
render: function() {
return <h1>Hello {this.props.name}</h1>;
}
});
ReactDOM.render(
<HelloMessage name="Runoob" />,
document.getElementById('example')
);
~~注意,在添加属性时, class 属性需要写成 className ,for 属性需要写成 htmlFor ,这是因为 class 和 for 是 JavaScript 的保留字。
!复合组件:我们可以通过创建多个组件来合成一个组件,即把组件的不同功能点进行分离。
//复合组件
var WebSite = React.createClass({
render:function () {
return(
<div>
<Name name={this.props.name}></Name>
<Link site={this.props.title}></Link>
</div>
);
}
});
var Name = React.createClass({
render:function () {
return(
<h1>{this.props.name}</h1>
)
}
});
var Link = React.createClass({
render:function(){
return(
<a href={this.props.site}>{this.props.site}</a>
)
}
});
ReactDOM.render(
<WebSite name="百度" title="http://www.baidu.com"/>,
document.getElementById("10")
)
3、ReactState状态
react是把组件看成一个状态机,通过与用户的交互,实现不同的状态,然后渲染UI,让用户界面和数据保持一致
在react中只需更新组件的state,然后根据新的state重新渲染用户界面,并不需要操作DOMvar LikeButton = React.createClass({
getInitialState: function() {//设置初始状态,这个对象可以通过this.state属性读取
return {liked: false};
},
handleClick: function(event) {
this.setState({liked: !this.state.liked});
},
render: function() {
var text = this.state.liked ? '喜欢' : '不喜欢';
return (
<p onClick={this.handleClick}>//用户点击组件,导致状态变化,this.setState方法就修改状态值,每次修改之后自动调用this.render方法,再次渲染组件
你<b>{text}</b>我。点我切换状态。
</p>
);
}
});
React.render(
<LikeButton />,
document.getElementById('example')
);
4、React Props
react中state和props主要的区别在于props是不可改变的,而state可以根据与用户的交互来进行改变,这也是为什么有些容器组件需要定义state来更新和修改数据,但是子组件只能通过props来传递数据
可以通过getDefaultProps()方法为props设置默认值
var HelloMessage = React.createClass({
getDefaultProps: function() {
return {
name: 'Runoob'
};
},
render: function() {
return <h1>Hello {this.props.name}</h1>;
}
});
ReactDOM.render(
<HelloMessage />,
document.getElementById('example')
);
!state和props:在父组件中设置state,并通过子组件使用props将其传递到子组件上,在render函数中,设置name和site来获取父组件传递过来的数据
var WebsiteCur = React.createClass({
getInitialState:function(){
return{
name:'baidu',
site:"http://www.baidu.com"
};
},
render:function () {
return (
<div>
<NameCur name={this.state.name}/>
<LinkCur site={this.state.site}/>
</div>
);
}
});
var NameCur = React.createClass({
render:function () {
return(
<h1>{this.props.name}</h1>
)
}
});
var LinkCur = React.createClass({
render:function(){
return (
<a href={this.props.site}>{this.props.site}</a>
)
}
});
ReactDOM.render(
<WebsiteCur />,
document.getElementById("01")
);
!props验证:使用propTypes, 可以保证应用组件被正确使用,当向props传入无效数据的时候,虽然页面上会正常显示,但是控制台会有报错
var title = "demo";
// var title = 123;
var MyTitle = React.createClass({
propTypes: {
title: React.PropTypes.string.isRequired,
},
render: function() {
return <h1> {this.props.title} </h1>;
}
});
ReactDOM.render(
<MyTitle title={title} />,
document.getElementById('example')
);
5、React组件API
设置状态:setState
替换状态:replaceState
设置属性:setProps -> setProps(object nextProps[, function callback]
替换属性:replaceProps -> replaceProps(object nextProps[, function callback]
强制更新:forceUpdate(一般来说要避免使用这个属性)
获取DOM节点:findDOMNode
判断组件挂载状态:isMOunted 返回true 或者false , 表示组件是否已经挂载到DOM中
关于setState
不能在组件内部通过this.state修改状态,因为该状态会在调用setState()后被替换。
setState()并不会立即改变this.state,而是创建一个即将处理的state。setState()并不一定是同步的,为了提升性能React会批量执行state和DOM渲染。
setState()总是会触发一次组件重绘,除非在shouldComponentUpdate()中实现了一些条件渲染逻辑。
var Counter = React.createClass({
getInitialState: function () {
return { clickCount: 0 };
},
handleClick: function () {
this.setState(function(state) {
return {clickCount: state.clickCount + 1};
});
},
render: function () {
return (<h2 onClick={this.handleClick}>点我!点击次数为: {this.state.clickCount}</h2>);
}
});
ReactDOM.render(
<Counter />,
document.getElementById('message')
);