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

用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秒内,页面将得到更新。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: