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

用TypeScipt和AMD模块化理念实现React官方教程(四)获取数据

发布时间:2020-12-15 04:39:52 所属栏目:百科 来源:网络整理
导读:从服务器获取数据 现在我们将硬编码进去的数据改成从服务器获得动态数据。我们将删去data prop并用URL的方式获取数据。 修改 main.tsx 如下: /// reference path="../typings/react/react-global.d.ts"/ import CommentBox = require( "./CommentBox" );Rea

从服务器获取数据

现在我们将硬编码进去的数据改成从服务器获得动态数据。我们将删去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.propsthis.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,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,err) {
                console.error(this.props.url,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秒内,页面将得到更新。

(编辑:李大同)

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

    推荐文章
      热点阅读