React with TypeScript 系列(四) --数据篇

编者语:前三篇的文章把React的基础和TypeScript对ReactJS的一些整合方式都介绍给大家了,接下来几篇会聊到如何和数据业务进行整合。今天先说说简单的数据整合,而之后会说flux。

       数据加载现在在JS 上都会使用Promise的模式(http://www.infoq.com/cn/news/2011/09/js-promise) , 而React 对于数据的载入重点不是你用什么方法去利用Promise模式去加载数据。更多是关心你的数据是怎么触发数据页面的DOM元素的变化。在该系列文章的第二篇也有提及几个名JSX, State,Props都是React中数据加载后影响的几个元素。

       我们来看看State变化时的一些细节,触发DOM元素的变化是在ComponnetDidUpdate()方法内,这里通过SetState去触发重新的render()
       

       而Props 的变化也大致和State一样
       
       好我们先来看看代码(话说代码大家都是比较关注的),继续我们之前的例子,需要加载数据的是CatalogList这个组件,所以我们把焦点放在这里。
       1. 先做好一个DataService.ts , 这里我用到了jquery 和 bluebird
///<reference path="../typings/jquery/jquery.d.ts" />
///<reference path="../typings/bluebird/bluebird.d.ts" />


module ReactDemo.Utils
{
    export class DataService{
        
        getCatalogList() : Promise<string>{
           var url = '/api/values';
           return this.getPromise(url); 
        }
        
        private getPromise(api: string): Promise<string> {
            return new Promise((resolve: (result: string) => void, reject: (error: string) => void): void => {
                    $.ajax(<JQueryAjaxSettings>{
                        url: api,
                        cache: false,
                        dataType: "json",
                        type: "GET",
                        success: resolve.bind(this),
                        error: (jqXHR: JQueryXHR, status: string, message: string) => {
                                                    reject(`status[${status}] message[${message}]`);
                                }
                        });
            });
        }
        
    }
}

       2. 我们需要对之前的CatalogList 和 CatalogItem 做对应调整,由于我们需要在CatalogList上加载数据,所以我们需要定义它的State值,而在CatalogItem中我们只需要把CatalogList中加载数据后的每一项数据传递给CatalogItem的Props即可。
       先看我们定义的CatalogItem , 这里我们定义了一个接收数据的Props , 注意一点在ReactJS中初始化getInistailState在TypeScript中的呈现方式是用构造函数所取代的,而参数值传递是以{}作为标签,根据接口的数据,就有了我们下列的呈现方式
interface CatalogItemProps {
    data : any;
}

class CatalogItem extends React.Component<CatalogItemProps,any>{
    
    constructor(props : CatalogItemProps){
       super(props);
    }
    
    
    public render()
    {
        return (<div>
                    <div className="goods">
                        <a href="#">
                            <div className="goods-img">
                                <img src="images/goods/good.jpg" alt="" />
                                <span className="goods-mark">
                                    <span className="goods-discount">{this.props.data.catalogGroupPrice}折</span>
                                    <span className="customers-num">{this.props.data.catalogGroup}人团</span>
                                </span>
                            </div>
                            <h2>{this.props.data.catalogName}</h2>
                            <p className="outline">{this.props.data.catalogIntro}</p>
                            <div className="goods-go">
                                <div className="goods-go-icon"></div>
                                <div className="goods-go-price">
                                    <span>{this.props.data.catalogGroup}人团</span>
                                    <b>¥{this.props.data.catalogGroupPrice}</b>
                                </div>
                                <div className="goods-go-btn">去开团</div>
                            </div>
                        </a>
                    </div>
              </div>);
    }
}
           而CatalogList 如下:
interface CatalogListState {
   list : any ;  
}

interface CatalogListProps {
    
}



class CatalogList extends React.Component<CatalogListProps,CatalogListState>{
    
    
    public state : CatalogListState ;
    
    constructor(props : CatalogListProps){
       super(props);
       this.state = {list : []};
    }
    
    public componentDidMount: () => void =
    (): void => {
       
        var dataService = new ReactDemo.Utils.DataService(); 
        var dataList; 
        dataService.getCatalogList().then((result:string)=>{
              this.setState({list:result});
        
        });
    
    }
    
    public render()
    {
       
      var catalogs;
      
      if(this.state.list){
        catalogs = this.state.list.map(function(catalog){
           return (<div>
                     <CatalogItem data={catalog}/>
                   </div>);
        });
      } 
        
        return (<div>
                     <div id="goods-list">
                        {catalogs}
                     </div>
                </div>);
    }
}
       关于CatalogList需要注意的地方是你必须判断state中list是否有效否则会出错,所以if(this.state)是不能缺少的,否则出错,其次不要忘记componentDidMount才能触发this.setState(....)
       3. 运行后你就可以看结果了(图片就不在这里加载了)

       

      好就说到这里,明天我们谈flux

React-barrage是一个React组件库,提供了在页面上展示弹幕的功能。在使用react-barrage之前,你需要先在项目中安装它: ``` npm install react-barrage --save ``` 然后在你的组件中使用它: ```tsx import React, { useCallback, useEffect, useState } from 'react'; import { Barrage, BarrageItem } from 'react-barrage'; interface Message { text: string; time: number; } const BarrageComponent: React.FC = () => { const [messages, setMessages] = useState<Message[]>([]); useEffect(() => { // 模拟异步获取弹幕数据 const timer = setInterval(() => { const now = Date.now(); setMessages(prevMessages => [ ...prevMessages, { text: `弹幕${now}`, time: now } ]); }, 1000); return () => clearInterval(timer); }, []); const renderItem = useCallback(({ text }) => { return <div>{text}</div>; }, []); return ( <Barrage> {messages.map(message => ( <BarrageItem key={message.time} text={message.text} render={renderItem} /> ))} </Barrage> ); }; export default BarrageComponent; ``` 这里的Barrage组件是弹幕的容器,而BarrageItem则是每一条弹幕。你需要将需要展示的弹幕数据传递给BarrageItem,并通过render函数来渲染每一条弹幕的内容。在上面的例子中,我们使用了useState来存储弹幕数据,并使用useEffect模拟异步获取数据的过程。当组件挂载后,我们每隔一秒钟就会向弹幕数据中添加一条新的弹幕数据,并将其展示在页面上。 需要注意的是,由于react-barrage是基于canvas实现的,因此在使用时需要注意一些性能问题。如果弹幕太多或太长,可能会导致页面卡顿或者崩溃。因此,在使用时需要根据实际情况来控制弹幕的数量和长度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值