加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

React入门

发布时间:2020-12-15 05:24:42 所属栏目:百科 来源:网络整理
导读:React入门 这里介绍一篇react网站上的教程,介绍如何使用react组件。这个组件包含以下一些内容 1.评论里面所有的视图 2.一个用来提交评论的表单 3.一个自定义的后台的钩子 原地址点这里 开始 源码里面引用的一些资源均是在facebook的CDN上面,可以直接访问,

React入门

这里介绍一篇react网站上的教程,介绍如何使用react组件。这个组件包含以下一些内容
1.评论里面所有的视图
2.一个用来提交评论的表单
3.一个自定义的后台的钩子
原地址点这里

开始

源码里面引用的一些资源均是在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属性)

上面的html文档中有使用jquery,这里仅仅只是为了方便调用ajax而已,实际上react是可以脱离jquery正常运行的。

第一个组件

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代码
// tutorial1-raw.js
var CommentBox = React.createClass({displayName: ‘CommentBox’,
render: function() {
return (
React.createElement(‘div’,{className: “commentBox”},
“Hello,world! I am a CommentBox.”
)
);
}
});
React.render(
React.createElement(CommentBox,null),
document.getElementById(‘content’)
);

在代码中使用jsx语法是可选的,使用这种语法是会让你更轻松的编写出来更直观的react风格的代码。但是说实话,这种写法上手有的复杂,用过几次就会觉得不错了。jsx具体内容参考这里

分析如上代码会发现,这里我们传入一些方法给React.createClass(),然后创建出来了React组件,这里面最重要的方法就是render方法了,render方法返回一个树状的React组件集合,最终这些组件被渲染到html文档上。
div标签并不是DOM节点,它是React里面的组件。它只能被React识别的,你可以把它当做一个特殊的标记或者数据。在这里,React是很安全的,默认的React是不会生成html字符串的。
React.render实例化root组件,启动React框架。如果传入第二个参数(一个DOM节点),它会把生成的标记写入到这个DOM元素里面去。

组合组件

接下来创建其他组件,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提供一种简单的方式来格式化我们的文本,使其看起来更漂亮。比如在文本前后加星号,可以使文本突出显示。
首先,需要引入一个三方的Showdown库,这个库是可以将Markdown语法的文本转化成原始的html内容。

<!-- 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>

注意上面上面最后一个script标签中的内容
然后我们把普通的文件转化成Markdown,然后输出:

// 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代码。我们看到的仍然是“<p>This is <em>another</em> comment</p>”。
这里是因为有React的保护机制存在,为了预防xss攻击的。下面介绍一种方式能够显示markdown语法,不过还是建议不要这么做。

// 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,我们需要利用这个后门。

注意,如果要使用这个特性,你必须依赖三方库如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来改变它的值。当状态更新的时候,这个组件会重新渲染。
render()方法是写给this.props和this.state的方法,状态或者属性的变化总是会触发render被调用。通过这个方式,框架使得ui和输入总是保持一致。
当服务器返回数据,组件这边会根据返回的数据来更新展示。这里,我们添加一些评论的数据给CommentBox组件,这些数据就是组件的状态。

// 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来帮助我们向服务器发起一个异步的请求

现在,这已经演变成了一个ajax的应用,你需要使用一个web服务器来开发你的应用,而不是使用本地文件。你可以在这里找到基于服务器的例子

// 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函数,当表单提交了有效的数据后,就清空表单中的数据。
在事件中调用preventDefault方法来组件浏览器的默认行为。

Refs(引用)

这里我们使用ref属性,来给孩子组件分配一个名字,然后通过this.refs可以拿到这个组件的引用。可以在组件里使用getDomNode方法来获取到本地浏览器上的DOM元素。

Callbacks as props(属性的回调)

当一个用户提交了评论后,我们需要刷新评论列表。而当CommentBox拿到了最新状态的数据后,这个组件会帮你把剩下的事情都搞定的。so easy。
有时候,我们需要从子组件中传递数据到父组件。为了实现这个功能,我们可以再父组件的render函数中加一个回调(handleCommentSubmint),然后将这个回调传给孩子组件,孩子组件就将这个回调绑定在onCommentSubmint事件上,只要这个事件被触发,回调就会被执行。

// 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。祝君好运。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读