React入门
React入门这里介绍一篇react网站上的教程,介绍如何使用react组件。这个组件包含以下一些内容 开始源码里面引用的一些资源均是在facebook的CDN上面,可以直接访问,也可以自己去下载这些引用的资源。现在打开编辑器,创建一个html文档。 <!-- index.html -->
<html>
<head>
<title>Hello React</title>
<script src="http://fb.me/react-0.12.2.js"></script>
<script src="http://fb.me/JSXTransformer-0.12.2.js"></script>
<script src="http://code.jquery.com/jquery-1.10.0.min.js"></script>
</head>
<body>
<div id="content"></div>
<script type="text/jsx"> // Your code here </script>
</body>
</html>
我们这里将javascript代码写在script标签里面(注意看上面script标签的type属性)
第一个组件React创建出来的组件,是模块化的、易于组合的组件。比如我们接下来要介绍的评论组件,它的结构如下 - CommentBox - CommentList - Comment - CommentForm
首先,我们创建一个CommentBox组件,这个组件就是一个简单的div // tutorial1.js
var CommentBox = React.createClass({
render: function() {
return (
<div className="commentBox">
Hello,world! I am a CommentBox.
</div>
);
}
});
React.render(
<CommentBox />,document.getElementById('content')
);
JSX语法可以看到上面的代码中使用了奇怪的语法(类似xml的语法),facebook提供一个简单的预编译方式,可以将这种语法的代码转化成普通的javascript代码 在代码中使用jsx语法是可选的,使用这种语法是会让你更轻松的编写出来更直观的react风格的代码。但是说实话,这种写法上手有的复杂,用过几次就会觉得不错了。jsx具体内容参考这里 分析如上代码会发现,这里我们传入一些方法给React.createClass(),然后创建出来了React组件,这里面最重要的方法就是render方法了,render方法返回一个树状的React组件集合,最终这些组件被渲染到html文档上。 组合组件接下来创建其他组件,CommentList和CommentForm,它们同样只是简单的div。 // tutorial2.js
var CommentList = React.createClass({
render: function() {
return (
<div className="commentList">
Hello,world! I am a CommentList.
</div>
);
}
});
var CommentForm = React.createClass({
render: function() {
return (
<div className="commentForm">
Hello,world! I am a CommentForm.
</div>
);
}
});
接下来,更新CommentBox组件,把上面写的两个组件组合进去。 // tutorial3.js
var CommentBox = React.createClass({
render: function() {
return (
<div className="commentBox">
<h1>Comments</h1>
<CommentList />
<CommentForm />
</div>
);
}
});
从上面代码不难看出,里面不仅有像h1、div一样的基础组件,也有我们自己定义的CommentList组件,在这里,它们都是React自己的组件。JSX语法会识别它们的,将它们都转化成React.createElement(tagname)形式。这样是为了防止全局命名空间的污染。 组件属性接下来我们创建第三个组件,Comment。我们希望将作者名字和发表的内容传入这个组件,以便我们可以重用代码。首先,我们添加一些内容到CommentList里面去。 // tutorial4.js
var CommentList = React.createClass({
render: function() {
return (
<div className="commentList">
<Comment author="Pete Hunt">This is one comment</Comment>
<Comment author="Jordan Walke">This is *another* comment</Comment>
</div>
);
}
});
注意,这里我们传入了一些数据给Comment组件。从父组件传给子组件的数据被称为props,是属性的英文单词的简写。 使用props开始创建Comment组件。使用props我们可以读取来自父组件CommentList的组件。 // tutorial5.js
var Comment = React.createClass({
render: function() {
return (
<div className="comment">
<h2 className="commentAuthor">
{this.props.author}
</h2>
{this.props.children}
</div>
);
}
});
在jsx中,使用大括号包含javascript表达式,就可以将组件或文本直接放到React的组件树中。我们通过this.props表达式可以访问传给这个组件的数据,也可以通过this.props.children来访问传递给这个组件的嵌套元素。 添加markdown语法Markdown提供一种简单的方式来格式化我们的文本,使其看起来更漂亮。比如在文本前后加星号,可以使文本突出显示。 <!-- index.html -->
<head>
<title>Hello React</title>
<script src="http://fb.me/react-0.12.2.js"></script>
<script src="http://fb.me/JSXTransformer-0.12.2.js"></script>
<script src="http://code.jquery.com/jquery-1.10.0.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/showdown/0.3.1/showdown.min.js"></script>
</head>
// tutorial6.js
var converter = new Showdown.converter();
var Comment = React.createClass({
render: function() {
return (
<div className="comment">
<h2 className="commentAuthor">
{this.props.author}
</h2>
{converter.makeHtml(this.props.children.toString())}
</div>
);
}
});
上面代码中调用了Showdown三方库做转化。但其实这里还是会有问题的。直接打开页面你会发现,三方库并没有转化html代码。我们看到的仍然是“ // tutorial7.js
var converter = new Showdown.converter();
var Comment = React.createClass({
render: function() {
var rawMarkup = converter.makeHtml(this.props.children.toString());
return (
<div className="comment">
<h2 className="commentAuthor">
{this.props.author}
</h2>
<span dangerouslySetInnerHTML={{__html: rawMarkup}} />
</div>
);
}
});
这个特殊的api是故意使插入原始html片段变得复杂的(安全考虑嘛),但对于Showdown,我们需要利用这个后门。
数据模型到目前为止,上面的数据都是直接插入的,实际项目中肯定不是这么玩的。下面,我们把一个JSON对象插入到CommentList中去。当然,这个JSON对象实际应该是从服务器读取的,这里,我们先将它写到源码中。 // tutorial8.js
var data = [
{author: "Pete Hunt",text: "This is one comment"},{author: "Jordan Walke",text: "This is *another* comment"}
];
我们需要使用一个模块化的方式将数据传入到CommentList里面去。这里,我们修改CommentBox组件和React.render方法,通过props的方式将数据传入到CommentList中去。 // tutorial9.js
var CommentBox = React.createClass({
render: function() {
return (
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={this.props.data} />
<CommentForm />
</div>
);
}
});
React.render(
<CommentBox data={data} />,document.getElementById('content')
);
现在,在CommentList中,这个数据是可用的了。我们可以动态的渲染评论了。 // tutorial10.js
var CommentList = React.createClass({
render: function() {
var commentNodes = this.props.data.map(function (comment) {
return (
<Comment author={comment.author}>
{comment.text}
</Comment>
);
});
return (
<div className="commentList">
{commentNodes}
</div>
);
}
});
从服务器获取数据在这里,我们将不再使用硬编码的方式将数据写在代码中,而是从服务器去取数据。我们需要去掉data属性,然后配置一个url属性,数据将从这个url里面去获取。 // tutorial11.js
React.render(
<CommentBox url="comments.json" />,document.getElementById('content')
);
这个组件和开始的组件已经不一样,它可以自己渲染。如果这个组件需要获取一些新的评论,那它可能没有可用的数据,除非服务器返回数据。 交互状态到目前为止,每一个组件都能够使用自己的属性来渲染了。props是不变的,数据来源于它们的父组件。为了实现交互,我们需要使用到可变的state。this.state是组件私有的,可以通过this.setState来改变它的值。当状态更新的时候,这个组件会重新渲染。 // tutorial12.js
var CommentBox = React.createClass({
getInitialState: function() {
return {data: []};
},render: function() {
return (
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={this.state.data} />
<CommentForm />
</div>
);
}
});
getInitialState()在组件的生命周期里面只会执行一次,在执行的时候,它负责设置组件的初始状态。 更新状态当一个组件第一次被创建,我们希望通过GET的方式从服务器拿到一些JSON数据并且更新状态,以展示最新数据。在一个真实的应用中,这是一次获取数据的完整的过程。但是在这个例子中,我们使用静态的JSON文件来做。 // tutorial13.json
[
{"author": "Pete Hunt","text": "This is one comment"},{"author": "Jordan Walke","text": "This is *another* comment"}
]
我们使用JQuery来帮助我们向服务器发起一个异步的请求
// tutorial13.js
var CommentBox = React.createClass({
getInitialState: function() {
return {data: []};
},componentDidMount: function() {
$.ajax({
url: this.props.url,dataType: 'json',success: function(data) {
this.setState({data: data});
}.bind(this),error: function(xhr,status,err) {
console.error(this.props.url,err.toString());
}.bind(this)
});
},render: function() {
return (
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={this.state.data} />
<CommentForm />
</div>
);
}
});
上面,当组件被渲染的时候,一个叫做commentDidMount的组件被调用,更新数据的关键是调用了this.setstate,我们使用从服务器获取来的数据更新了状态,这时,UI组件自己就会更新。由于有这样的能力,我们只做了一些小小的改动就实现了实时更新。在这里只是展示了简单的拉取数据的方法,你也可以很简单的使用websockets或其他技术实现。 var CommentBox = React.createClass({
loadCommentsFromServer: function() {
$.ajax({
url: this.props.url,getInitialState: function() {
return {data: []};
},componentDidMount: function() {
this.loadCommentsFromServer();
setInterval(this.loadCommentsFromServer,this.props.pollInterval);
},render: function() {
return (
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={this.state.data} />
<CommentForm />
</div>
);
}
});
React.render(
<CommentBox url="comments.json" pollInterval={2000} />,document.getElementById('content')
);
这里我们仅把AJAX调用分离了开,然后在组件初始化的时候和每隔2s去调用它。你可以在你的浏览器中运行代码,并修改comment.json文件;2s内,评论就会更新。 增加新的评论现在开始创建表单。我们的CommentForm组件应该获取到用户的名称和评论的内容,然后发送请求到服务器上面,最后保存评论。 // tutorial15.js
var CommentForm = React.createClass({
render: function() {
return (
<form className="commentForm">
<input type="text" placeholder="Your name" />
<input type="text" placeholder="Say something..." />
<input type="submit" value="Post" />
</form>
);
}
});
接下来我们可以让表单能够交互。当用户提交表单,我们清空它,然后提交一个请求到服务器,然后刷新评论列表。首先,我们需要监听表单的提交并清空它。 // tutorial16.js
var CommentForm = React.createClass({
handleSubmit: function(e) {
e.preventDefault();
var author = this.refs.author.getDOMNode().value.trim();
var text = this.refs.text.getDOMNode().value.trim();
if (!text || !author) {
return;
}
// TODO: send request to the server
this.refs.author.getDOMNode().value = '';
this.refs.text.getDOMNode().value = '';
},render: function() {
return (
<form className="commentForm" onSubmit={this.handleSubmit}>
<input type="text" placeholder="Your name" ref="author" />
<input type="text" placeholder="Say something..." ref="text" />
<input type="submit" value="Post" />
</form>
);
}
});
Events(事件)React通过使用驼峰命名的方式给组件添加事件处理函数。我们给表单添加onSubmit函数,当表单提交了有效的数据后,就清空表单中的数据。 Refs(引用)这里我们使用ref属性,来给孩子组件分配一个名字,然后通过this.refs可以拿到这个组件的引用。可以在组件里使用getDomNode方法来获取到本地浏览器上的DOM元素。 Callbacks as props(属性的回调)当一个用户提交了评论后,我们需要刷新评论列表。而当CommentBox拿到了最新状态的数据后,这个组件会帮你把剩下的事情都搞定的。so easy。 // tutorial17.js
var CommentBox = React.createClass({
loadCommentsFromServer: function() {
$.ajax({
url: this.props.url,handleCommentSubmit: function(comment) {
// TODO: submit to the server and refresh the list
},render: function() {
return (
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={this.state.data} />
<CommentForm onCommentSubmit={this.handleCommentSubmit} />
</div>
);
}
});
当用户提交了表单时,我们就调用这个回调 // tutorial18.js
var CommentForm = React.createClass({
handleSubmit: function(e) {
e.preventDefault();
var author = this.refs.author.getDOMNode().value.trim();
var text = this.refs.text.getDOMNode().value.trim();
if (!text || !author) {
return;
}
this.props.onCommentSubmit({author: author,text: text});
this.refs.author.getDOMNode().value = '';
this.refs.text.getDOMNode().value = '';
},render: function() {
return (
<form className="commentForm" onSubmit={this.handleSubmit}>
<input type="text" placeholder="Your name" ref="author" />
<input type="text" placeholder="Say something..." ref="text" />
<input type="submit" value="Post" />
</form>
);
}
});
现在,回调也已经有了,剩下的就是提交到服务器然后再刷新列表了。 // tutorial19.js
var CommentBox = React.createClass({
loadCommentsFromServer: function() {
$.ajax({
url: this.props.url,handleCommentSubmit: function(comment) {
$.ajax({
url: this.props.url,type: 'POST',data: comment,render: function() {
return (
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={this.state.data} />
<CommentForm onCommentSubmit={this.handleCommentSubmit} />
</div>
);
}
});
优化更新现在我们的应用该有的都已经有了,但是要服务器返回请求后,评论才会出现在列表中,这个过程感觉有些慢。我们可以直接将评论添加到列表中,这样就跑的更快了。 / tutorial20.js
var CommentBox = React.createClass({
loadCommentsFromServer: function() {
$.ajax({
url: this.props.url,handleCommentSubmit: function(comment) {
var comments = this.state.data;
var newComments = comments.concat([comment]);
this.setState({data: newComments});
$.ajax({
url: this.props.url,render: function() {
return (
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={this.state.data} />
<CommentForm onCommentSubmit={this.handleCommentSubmit} />
</div>
);
}
});
恭喜你已经可以创建一个评论的组建了。你也可以了解更多React或直接看API。祝君好运。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |