用TypeScipt和AMD模块化理念实现React官方教程(四)获取数据
2016-02-20 21:52
681 查看
从服务器获取数据
现在我们将硬编码进去的数据改成从服务器获得动态数据。我们将删去data prop并用URL的方式获取数据。修改main.tsx如下:
/// <reference path="../typings/react/react-global.d.ts"/> import CommentBox = require("./CommentBox"); ReactDOM.render(<CommentBox url="/api/comments" />, document.getElementById('content'));
这个组件同之前组件不同之处是它能够重新渲染它自己。组件在从服务器获得数据之前是没有数据的。注:这一步代码还不能工作。
重激活状态
到现在为止,基于组件的props,每个组件能渲染自己一次。props是不可变的:它由父组件传入并且由父组件“拥有”。为了实现交互,我们引入了可变的state到组件中。
this.state对组件来说是私有的,并且可以通过调用
this.setState()进行改变。当状态更新时,组件能自行重新渲染。
render() 方法作为
this.props和
this.state函数的声明式方法。框架保证UI总是跟输入保持一致。修改 CommentBox.tsx 如下
/// <reference path="../typings/react/react-global.d.ts"/> import CommentList = require("./CommentList"); import CommentForm = require("./CommentForm"); export =CommentBox; class CommentBox extends React.Component<any, any> { getInitialState() { return { data: [] } } render() { return ( <div className="commentBox"> <h1>评论</h1> <CommentList data={this.state.data} /> <CommentForm /> </div> ); } }
getInitialState()在组件的生命周期开始时执行一次并设置好组件的初始状态。
更新状态
当组件一开始创建的时想,我们想从服务器GET一些JSON并更新状态反映新新的数据。我们现在使用jQuery来异步获取从服务器提供的数据。数据在你启动服务器的时候已经包含 了(基于comments.json文件),所以当获取数据后,this.state.data会象这样:
[ {"author": "Pete Hunt", "text": "This is one comment"}, {"author": "Jordan Walke", "text": "This is *another* comment"} ]
现在CommentBox.tsx如下添加componetDidMount:
/// <reference path="../typings/react/react-global.d.ts"/> /// <reference path="../typings/jquery/jquery.d.ts"/> import CommentList = require("./CommentList"); import CommentForm = require("./CommentForm"); export =CommentBox; interface CommentBoxProps { } interface CommentBoxState { data: any; } class CommentBox extends React.Component<CommentBoxProps, CommentBoxState> { public state: CommentBoxState; constructor(props: CommentBoxProps) { super(props); this.state = { data: [] }; } componentDidMount() { $.ajax({ url: this.props.url, dataType: 'json', cache: false, success: function (data) { this.setState({ data: data }); }.bind(this), error: function (xhr, status, err) { console.error(this.props.url, status, err.toString()); }.bind(this) }); } render() { return ( <div className="commentBox"> <h1>评论</h1> <CommentList data={this.state.data} /> <CommentForm /> </div> ); } }
在这里,componentDidMount 是由React在一个组件第一次渲染之后自动调用的一个方法。动态更新的的关键是调用
this.setState()。我们将老的评论数组换成了从来自服务器的新数据,并自动的更新。因为这样的反应,我们只要一个小的改更就能添加活动更新。你还可以通过WebSockets或其它技术轻松使用它们。下面我们对这个进行更改:
/// <reference path="../typings/react/react-global.d.ts"/> /// <reference path="../typings/jquery/jquery.d.ts"/> import CommentList = require("./CommentList"); import CommentForm = require("./CommentForm"); export =CommentBox; interface CommentBoxProps { url: string; pollInterval: number; } interface CommentBoxState { data: any; } class CommentBox extends React.Component<CommentBoxProps, CommentBoxState> { public state: CommentBoxState; constructor(props: CommentBoxProps) { super(props); this.state = { data: [] }; } loadCommentsFromServer() { $.ajax({ url: this.props.url, dataType: 'json', cache: false, success: function (data) { this.setState({ data: data }); }.bind(this), error: function (xhr, status, err) { console.error(this.props.url, status, err.toString()); }.bind(this) }); } componentDidMount() { this.loadCommentsFromServer(); //setInterval(this.loadCommentsFromServer, this.props.pollInterval); //setInterval(() => this.loadCommentsFromServer, this.props.pollInterval); setInterval(() => this.loadCommentsFromServer(), this.props.pollInterval); } render() { return ( <div className="commentBox"> <h1>评论</h1> <CommentList data={this.state.data} /> <CommentForm /> </div> ); } }
CommentBox.tsx 中的修改是将AJAX的调用放到了一个单独的方法中。当组件第一次加载后每隔2秒钟更新数据。在这段修改的代码里我特别标注了两种错误的写法。注释掉的写法会导至不能按2秒更新数据。详细的解释可以参考:
参考stackoverflow中的一个问答
我们对main.tsx也进行修改:
/// <reference path="../typings/react/react-global.d.ts"/> import CommentBox = require("./CommentBox"); ReactDOM.render(<CommentBox url="/api/comments" pollInterval={2000} />, document.getElementById('content'));
在浏览器中运行后,打开comments.json进行修改,2秒内,页面将得到更新。
相关文章推荐
- react-native启动异常,react-deep-force-update/.babelrc
- react-native启动异常,react-deep-force-update/.babelrc
- react-active init XXX 没反应
- 用TypeScipt和AMD模块化理念实现React官方教程(三)静态页面
- ReactiveCocoa简介6,添加附加操作(Adding side-effects)
- ReactiveCocoa简介五:用信号封装异步API
- ReactiveCocoa简介四,Button的点击事件的实现
- ReactiveCocoa简介四,聚合信号
- ReactiveCocoa简介三,根据输入框的条件,改变输入框背景颜色
- ReactiveCocoa简介二,值的传递
- ReactiveCocoa简介一,什么是信号量和基本操作
- react native 安装指南
- React-Native OpenGL体验二
- React Native For Android On Windows
- ReactJS初步学习
- React Native-11.React Native TabBarIOS TabBarIOS.Item组件详解
- React.js组件的生命周期
- React 特别需要注意的地方
- react-native组件封装与传值
- React Native-10.React Native Image组件详解