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

發佈了47 篇原創文章 · 獲贊 31 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章